1 //===------- Interp.cpp - Interpreter for the constexpr VM ------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "Interp.h" 10 #include "Function.h" 11 #include "InterpFrame.h" 12 #include "InterpShared.h" 13 #include "InterpStack.h" 14 #include "Opcode.h" 15 #include "PrimType.h" 16 #include "Program.h" 17 #include "State.h" 18 #include "clang/AST/ASTContext.h" 19 #include "clang/AST/ASTDiagnostic.h" 20 #include "clang/AST/CXXInheritance.h" 21 #include "clang/AST/DeclObjC.h" 22 #include "clang/AST/Expr.h" 23 #include "clang/AST/ExprCXX.h" 24 #include "llvm/ADT/APSInt.h" 25 #include "llvm/ADT/StringExtras.h" 26 #include <limits> 27 #include <vector> 28 29 using namespace clang; 30 using namespace clang::interp; 31 32 static bool RetValue(InterpState &S, CodePtr &Pt, APValue &Result) { 33 llvm::report_fatal_error("Interpreter cannot return values"); 34 } 35 36 //===----------------------------------------------------------------------===// 37 // Jmp, Jt, Jf 38 //===----------------------------------------------------------------------===// 39 40 static bool Jmp(InterpState &S, CodePtr &PC, int32_t Offset) { 41 PC += Offset; 42 return true; 43 } 44 45 static bool Jt(InterpState &S, CodePtr &PC, int32_t Offset) { 46 if (S.Stk.pop<bool>()) { 47 PC += Offset; 48 } 49 return true; 50 } 51 52 static bool Jf(InterpState &S, CodePtr &PC, int32_t Offset) { 53 if (!S.Stk.pop<bool>()) { 54 PC += Offset; 55 } 56 return true; 57 } 58 59 static void diagnoseMissingInitializer(InterpState &S, CodePtr OpPC, 60 const ValueDecl *VD) { 61 const SourceInfo &E = S.Current->getSource(OpPC); 62 S.FFDiag(E, diag::note_constexpr_var_init_unknown, 1) << VD; 63 S.Note(VD->getLocation(), diag::note_declared_at) << VD->getSourceRange(); 64 } 65 66 static void diagnoseNonConstVariable(InterpState &S, CodePtr OpPC, 67 const ValueDecl *VD); 68 static bool diagnoseUnknownDecl(InterpState &S, CodePtr OpPC, 69 const ValueDecl *D) { 70 const SourceInfo &E = S.Current->getSource(OpPC); 71 72 if (isa<ParmVarDecl>(D)) { 73 if (S.getLangOpts().CPlusPlus11) { 74 S.FFDiag(E, diag::note_constexpr_function_param_value_unknown) << D; 75 S.Note(D->getLocation(), diag::note_declared_at) << D->getSourceRange(); 76 } else { 77 S.FFDiag(E); 78 } 79 return false; 80 } 81 82 if (!D->getType().isConstQualified()) 83 diagnoseNonConstVariable(S, OpPC, D); 84 else if (const auto *VD = dyn_cast<VarDecl>(D); 85 VD && !VD->getAnyInitializer()) 86 diagnoseMissingInitializer(S, OpPC, VD); 87 88 return false; 89 } 90 91 static void diagnoseNonConstVariable(InterpState &S, CodePtr OpPC, 92 const ValueDecl *VD) { 93 if (!S.getLangOpts().CPlusPlus) 94 return; 95 96 const SourceInfo &Loc = S.Current->getSource(OpPC); 97 if (const auto *VarD = dyn_cast<VarDecl>(VD); 98 VarD && VarD->getType().isConstQualified() && 99 !VarD->getAnyInitializer()) { 100 diagnoseMissingInitializer(S, OpPC, VD); 101 return; 102 } 103 104 // Rather random, but this is to match the diagnostic output of the current 105 // interpreter. 106 if (isa<ObjCIvarDecl>(VD)) 107 return; 108 109 if (VD->getType()->isIntegralOrEnumerationType()) { 110 S.FFDiag(Loc, diag::note_constexpr_ltor_non_const_int, 1) << VD; 111 S.Note(VD->getLocation(), diag::note_declared_at); 112 return; 113 } 114 115 S.FFDiag(Loc, 116 S.getLangOpts().CPlusPlus11 ? diag::note_constexpr_ltor_non_constexpr 117 : diag::note_constexpr_ltor_non_integral, 118 1) 119 << VD << VD->getType(); 120 S.Note(VD->getLocation(), diag::note_declared_at); 121 } 122 123 static bool CheckActive(InterpState &S, CodePtr OpPC, const Pointer &Ptr, 124 AccessKinds AK) { 125 if (Ptr.isActive()) 126 return true; 127 128 assert(Ptr.inUnion()); 129 assert(Ptr.isField() && Ptr.getField()); 130 131 Pointer U = Ptr.getBase(); 132 Pointer C = Ptr; 133 while (!U.isRoot() && U.inUnion() && !U.isActive()) { 134 if (U.getField()) 135 C = U; 136 U = U.getBase(); 137 } 138 assert(C.isField()); 139 140 // Get the inactive field descriptor. 141 const FieldDecl *InactiveField = C.getField(); 142 assert(InactiveField); 143 144 // Consider: 145 // union U { 146 // struct { 147 // int x; 148 // int y; 149 // } a; 150 // } 151 // 152 // When activating x, we will also activate a. If we now try to read 153 // from y, we will get to CheckActive, because y is not active. In that 154 // case, our U will be a (not a union). We return here and let later code 155 // handle this. 156 if (!U.getFieldDesc()->isUnion()) 157 return true; 158 159 // Find the active field of the union. 160 const Record *R = U.getRecord(); 161 assert(R && R->isUnion() && "Not a union"); 162 163 const FieldDecl *ActiveField = nullptr; 164 for (const Record::Field &F : R->fields()) { 165 const Pointer &Field = U.atField(F.Offset); 166 if (Field.isActive()) { 167 ActiveField = Field.getField(); 168 break; 169 } 170 } 171 172 const SourceInfo &Loc = S.Current->getSource(OpPC); 173 S.FFDiag(Loc, diag::note_constexpr_access_inactive_union_member) 174 << AK << InactiveField << !ActiveField << ActiveField; 175 return false; 176 } 177 178 static bool CheckTemporary(InterpState &S, CodePtr OpPC, const Pointer &Ptr, 179 AccessKinds AK) { 180 if (auto ID = Ptr.getDeclID()) { 181 if (!Ptr.isStaticTemporary()) 182 return true; 183 184 if (Ptr.getDeclDesc()->getType().isConstQualified()) 185 return true; 186 187 if (S.P.getCurrentDecl() == ID) 188 return true; 189 190 const SourceInfo &E = S.Current->getSource(OpPC); 191 S.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK; 192 S.Note(Ptr.getDeclLoc(), diag::note_constexpr_temporary_here); 193 return false; 194 } 195 return true; 196 } 197 198 static bool CheckGlobal(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { 199 if (auto ID = Ptr.getDeclID()) { 200 if (!Ptr.isStatic()) 201 return true; 202 203 if (S.P.getCurrentDecl() == ID) 204 return true; 205 206 S.FFDiag(S.Current->getLocation(OpPC), diag::note_constexpr_modify_global); 207 return false; 208 } 209 return true; 210 } 211 212 namespace clang { 213 namespace interp { 214 static void popArg(InterpState &S, const Expr *Arg) { 215 PrimType Ty = S.getContext().classify(Arg).value_or(PT_Ptr); 216 TYPE_SWITCH(Ty, S.Stk.discard<T>()); 217 } 218 219 void cleanupAfterFunctionCall(InterpState &S, CodePtr OpPC) { 220 assert(S.Current); 221 const Function *CurFunc = S.Current->getFunction(); 222 assert(CurFunc); 223 224 if (CurFunc->isUnevaluatedBuiltin()) 225 return; 226 227 // Some builtin functions require us to only look at the call site, since 228 // the classified parameter types do not match. 229 if (CurFunc->isBuiltin()) { 230 const auto *CE = 231 cast<CallExpr>(S.Current->Caller->getExpr(S.Current->getRetPC())); 232 for (int32_t I = CE->getNumArgs() - 1; I >= 0; --I) { 233 const Expr *A = CE->getArg(I); 234 popArg(S, A); 235 } 236 return; 237 } 238 239 if (S.Current->Caller && CurFunc->isVariadic()) { 240 // CallExpr we're look for is at the return PC of the current function, i.e. 241 // in the caller. 242 // This code path should be executed very rarely. 243 unsigned NumVarArgs; 244 const Expr *const *Args = nullptr; 245 unsigned NumArgs = 0; 246 const Expr *CallSite = S.Current->Caller->getExpr(S.Current->getRetPC()); 247 if (const auto *CE = dyn_cast<CallExpr>(CallSite)) { 248 Args = CE->getArgs(); 249 NumArgs = CE->getNumArgs(); 250 } else if (const auto *CE = dyn_cast<CXXConstructExpr>(CallSite)) { 251 Args = CE->getArgs(); 252 NumArgs = CE->getNumArgs(); 253 } else 254 assert(false && "Can't get arguments from that expression type"); 255 256 assert(NumArgs >= CurFunc->getNumWrittenParams()); 257 NumVarArgs = NumArgs - (CurFunc->getNumWrittenParams() + 258 isa<CXXOperatorCallExpr>(CallSite)); 259 for (unsigned I = 0; I != NumVarArgs; ++I) { 260 const Expr *A = Args[NumArgs - 1 - I]; 261 popArg(S, A); 262 } 263 } 264 265 // And in any case, remove the fixed parameters (the non-variadic ones) 266 // at the end. 267 S.Current->popArgs(); 268 } 269 270 bool CheckExtern(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { 271 if (!Ptr.isExtern()) 272 return true; 273 274 if (Ptr.isInitialized() || 275 (Ptr.getDeclDesc()->asVarDecl() == S.EvaluatingDecl)) 276 return true; 277 278 if (!S.checkingPotentialConstantExpression() && S.getLangOpts().CPlusPlus) { 279 const auto *VD = Ptr.getDeclDesc()->asValueDecl(); 280 diagnoseNonConstVariable(S, OpPC, VD); 281 } 282 return false; 283 } 284 285 bool CheckArray(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { 286 if (!Ptr.isUnknownSizeArray()) 287 return true; 288 const SourceInfo &E = S.Current->getSource(OpPC); 289 S.FFDiag(E, diag::note_constexpr_unsized_array_indexed); 290 return false; 291 } 292 293 bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr, 294 AccessKinds AK) { 295 if (Ptr.isZero()) { 296 const auto &Src = S.Current->getSource(OpPC); 297 298 if (Ptr.isField()) 299 S.FFDiag(Src, diag::note_constexpr_null_subobject) << CSK_Field; 300 else 301 S.FFDiag(Src, diag::note_constexpr_access_null) << AK; 302 303 return false; 304 } 305 306 if (!Ptr.isLive()) { 307 const auto &Src = S.Current->getSource(OpPC); 308 309 if (Ptr.isDynamic()) { 310 S.FFDiag(Src, diag::note_constexpr_access_deleted_object) << AK; 311 } else { 312 bool IsTemp = Ptr.isTemporary(); 313 S.FFDiag(Src, diag::note_constexpr_lifetime_ended, 1) << AK << !IsTemp; 314 315 if (IsTemp) 316 S.Note(Ptr.getDeclLoc(), diag::note_constexpr_temporary_here); 317 else 318 S.Note(Ptr.getDeclLoc(), diag::note_declared_at); 319 } 320 321 return false; 322 } 323 324 return true; 325 } 326 327 bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc) { 328 assert(Desc); 329 330 const auto *D = Desc->asVarDecl(); 331 if (!D || !D->hasGlobalStorage()) 332 return true; 333 334 if (D == S.EvaluatingDecl) 335 return true; 336 337 if (D->isConstexpr()) 338 return true; 339 340 QualType T = D->getType(); 341 bool IsConstant = T.isConstant(S.getASTContext()); 342 if (T->isIntegralOrEnumerationType()) { 343 if (!IsConstant) { 344 diagnoseNonConstVariable(S, OpPC, D); 345 return false; 346 } 347 return true; 348 } 349 350 if (IsConstant) { 351 if (S.getLangOpts().CPlusPlus) { 352 S.CCEDiag(S.Current->getLocation(OpPC), 353 S.getLangOpts().CPlusPlus11 354 ? diag::note_constexpr_ltor_non_constexpr 355 : diag::note_constexpr_ltor_non_integral, 356 1) 357 << D << T; 358 S.Note(D->getLocation(), diag::note_declared_at); 359 } else { 360 S.CCEDiag(S.Current->getLocation(OpPC)); 361 } 362 return true; 363 } 364 365 if (T->isPointerOrReferenceType()) { 366 if (!T->getPointeeType().isConstant(S.getASTContext()) || 367 !S.getLangOpts().CPlusPlus11) { 368 diagnoseNonConstVariable(S, OpPC, D); 369 return false; 370 } 371 return true; 372 } 373 374 diagnoseNonConstVariable(S, OpPC, D); 375 return false; 376 } 377 378 static bool CheckConstant(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { 379 if (!Ptr.isBlockPointer()) 380 return true; 381 return CheckConstant(S, OpPC, Ptr.getDeclDesc()); 382 } 383 384 bool CheckNull(InterpState &S, CodePtr OpPC, const Pointer &Ptr, 385 CheckSubobjectKind CSK) { 386 if (!Ptr.isZero()) 387 return true; 388 const SourceInfo &Loc = S.Current->getSource(OpPC); 389 S.FFDiag(Loc, diag::note_constexpr_null_subobject) 390 << CSK << S.Current->getRange(OpPC); 391 392 return false; 393 } 394 395 bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr, 396 AccessKinds AK) { 397 if (!Ptr.isOnePastEnd()) 398 return true; 399 const SourceInfo &Loc = S.Current->getSource(OpPC); 400 S.FFDiag(Loc, diag::note_constexpr_access_past_end) 401 << AK << S.Current->getRange(OpPC); 402 return false; 403 } 404 405 bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr, 406 CheckSubobjectKind CSK) { 407 if (!Ptr.isElementPastEnd()) 408 return true; 409 const SourceInfo &Loc = S.Current->getSource(OpPC); 410 S.FFDiag(Loc, diag::note_constexpr_past_end_subobject) 411 << CSK << S.Current->getRange(OpPC); 412 return false; 413 } 414 415 bool CheckSubobject(InterpState &S, CodePtr OpPC, const Pointer &Ptr, 416 CheckSubobjectKind CSK) { 417 if (!Ptr.isOnePastEnd()) 418 return true; 419 420 const SourceInfo &Loc = S.Current->getSource(OpPC); 421 S.FFDiag(Loc, diag::note_constexpr_past_end_subobject) 422 << CSK << S.Current->getRange(OpPC); 423 return false; 424 } 425 426 bool CheckDowncast(InterpState &S, CodePtr OpPC, const Pointer &Ptr, 427 uint32_t Offset) { 428 uint32_t MinOffset = Ptr.getDeclDesc()->getMetadataSize(); 429 uint32_t PtrOffset = Ptr.getByteOffset(); 430 431 // We subtract Offset from PtrOffset. The result must be at least 432 // MinOffset. 433 if (Offset < PtrOffset && (PtrOffset - Offset) >= MinOffset) 434 return true; 435 436 const auto *E = cast<CastExpr>(S.Current->getExpr(OpPC)); 437 QualType TargetQT = E->getType()->getPointeeType(); 438 QualType MostDerivedQT = Ptr.getDeclPtr().getType(); 439 440 S.CCEDiag(E, diag::note_constexpr_invalid_downcast) 441 << MostDerivedQT << TargetQT; 442 443 return false; 444 } 445 446 bool CheckConst(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { 447 assert(Ptr.isLive() && "Pointer is not live"); 448 if (!Ptr.isConst() || Ptr.isMutable()) 449 return true; 450 451 // The This pointer is writable in constructors and destructors, 452 // even if isConst() returns true. 453 // TODO(perf): We could be hitting this code path quite a lot in complex 454 // constructors. Is there a better way to do this? 455 if (S.Current->getFunction()) { 456 for (const InterpFrame *Frame = S.Current; Frame; Frame = Frame->Caller) { 457 if (const Function *Func = Frame->getFunction(); 458 Func && (Func->isConstructor() || Func->isDestructor()) && 459 Ptr.block() == Frame->getThis().block()) { 460 return true; 461 } 462 } 463 } 464 465 if (!Ptr.isBlockPointer()) 466 return false; 467 468 const QualType Ty = Ptr.getType(); 469 const SourceInfo &Loc = S.Current->getSource(OpPC); 470 S.FFDiag(Loc, diag::note_constexpr_modify_const_type) << Ty; 471 return false; 472 } 473 474 bool CheckMutable(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { 475 assert(Ptr.isLive() && "Pointer is not live"); 476 if (!Ptr.isMutable()) 477 return true; 478 479 // In C++14 onwards, it is permitted to read a mutable member whose 480 // lifetime began within the evaluation. 481 if (S.getLangOpts().CPlusPlus14 && 482 Ptr.block()->getEvalID() == S.Ctx.getEvalID()) 483 return true; 484 485 const SourceInfo &Loc = S.Current->getSource(OpPC); 486 const FieldDecl *Field = Ptr.getField(); 487 S.FFDiag(Loc, diag::note_constexpr_access_mutable, 1) << AK_Read << Field; 488 S.Note(Field->getLocation(), diag::note_declared_at); 489 return false; 490 } 491 492 bool CheckVolatile(InterpState &S, CodePtr OpPC, const Pointer &Ptr, 493 AccessKinds AK) { 494 assert(Ptr.isLive()); 495 496 // FIXME: This check here might be kinda expensive. Maybe it would be better 497 // to have another field in InlineDescriptor for this? 498 if (!Ptr.isBlockPointer()) 499 return true; 500 501 QualType PtrType = Ptr.getType(); 502 if (!PtrType.isVolatileQualified()) 503 return true; 504 505 const SourceInfo &Loc = S.Current->getSource(OpPC); 506 if (S.getLangOpts().CPlusPlus) 507 S.FFDiag(Loc, diag::note_constexpr_access_volatile_type) << AK << PtrType; 508 else 509 S.FFDiag(Loc); 510 return false; 511 } 512 513 bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr, 514 AccessKinds AK) { 515 assert(Ptr.isLive()); 516 517 if (Ptr.isInitialized()) 518 return true; 519 520 if (const auto *VD = Ptr.getDeclDesc()->asVarDecl(); 521 VD && VD->hasGlobalStorage()) { 522 const SourceInfo &Loc = S.Current->getSource(OpPC); 523 if (VD->getAnyInitializer()) { 524 S.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << VD; 525 S.Note(VD->getLocation(), diag::note_declared_at); 526 } else { 527 diagnoseMissingInitializer(S, OpPC, VD); 528 } 529 return false; 530 } 531 532 if (!S.checkingPotentialConstantExpression()) { 533 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_uninit) 534 << AK << /*uninitialized=*/true << S.Current->getRange(OpPC); 535 } 536 return false; 537 } 538 539 bool CheckGlobalInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { 540 if (Ptr.isInitialized()) 541 return true; 542 543 assert(S.getLangOpts().CPlusPlus); 544 const auto *VD = cast<VarDecl>(Ptr.getDeclDesc()->asValueDecl()); 545 if ((!VD->hasConstantInitialization() && 546 VD->mightBeUsableInConstantExpressions(S.getASTContext())) || 547 (S.getLangOpts().OpenCL && !S.getLangOpts().CPlusPlus11 && 548 !VD->hasICEInitializer(S.getASTContext()))) { 549 const SourceInfo &Loc = S.Current->getSource(OpPC); 550 S.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << VD; 551 S.Note(VD->getLocation(), diag::note_declared_at); 552 } 553 return false; 554 } 555 556 bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr, 557 AccessKinds AK) { 558 if (!CheckLive(S, OpPC, Ptr, AK)) 559 return false; 560 if (!CheckConstant(S, OpPC, Ptr)) 561 return false; 562 563 if (!CheckDummy(S, OpPC, Ptr, AK)) 564 return false; 565 if (!CheckExtern(S, OpPC, Ptr)) 566 return false; 567 if (!CheckRange(S, OpPC, Ptr, AK)) 568 return false; 569 if (!CheckActive(S, OpPC, Ptr, AK)) 570 return false; 571 if (!CheckInitialized(S, OpPC, Ptr, AK)) 572 return false; 573 if (!CheckTemporary(S, OpPC, Ptr, AK)) 574 return false; 575 if (!CheckMutable(S, OpPC, Ptr)) 576 return false; 577 if (!CheckVolatile(S, OpPC, Ptr, AK)) 578 return false; 579 return true; 580 } 581 582 /// This is not used by any of the opcodes directly. It's used by 583 /// EvalEmitter to do the final lvalue-to-rvalue conversion. 584 bool CheckFinalLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { 585 if (!CheckLive(S, OpPC, Ptr, AK_Read)) 586 return false; 587 if (!CheckConstant(S, OpPC, Ptr)) 588 return false; 589 590 if (!CheckDummy(S, OpPC, Ptr, AK_Read)) 591 return false; 592 if (!CheckExtern(S, OpPC, Ptr)) 593 return false; 594 if (!CheckRange(S, OpPC, Ptr, AK_Read)) 595 return false; 596 if (!CheckActive(S, OpPC, Ptr, AK_Read)) 597 return false; 598 if (!CheckInitialized(S, OpPC, Ptr, AK_Read)) 599 return false; 600 if (!CheckTemporary(S, OpPC, Ptr, AK_Read)) 601 return false; 602 if (!CheckMutable(S, OpPC, Ptr)) 603 return false; 604 return true; 605 } 606 607 bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { 608 if (!CheckLive(S, OpPC, Ptr, AK_Assign)) 609 return false; 610 if (!CheckDummy(S, OpPC, Ptr, AK_Assign)) 611 return false; 612 if (!CheckExtern(S, OpPC, Ptr)) 613 return false; 614 if (!CheckRange(S, OpPC, Ptr, AK_Assign)) 615 return false; 616 if (!CheckGlobal(S, OpPC, Ptr)) 617 return false; 618 if (!CheckConst(S, OpPC, Ptr)) 619 return false; 620 return true; 621 } 622 623 bool CheckInvoke(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { 624 if (!CheckLive(S, OpPC, Ptr, AK_MemberCall)) 625 return false; 626 if (!Ptr.isDummy()) { 627 if (!CheckExtern(S, OpPC, Ptr)) 628 return false; 629 if (!CheckRange(S, OpPC, Ptr, AK_MemberCall)) 630 return false; 631 } 632 return true; 633 } 634 635 bool CheckInit(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { 636 if (!CheckLive(S, OpPC, Ptr, AK_Assign)) 637 return false; 638 if (!CheckRange(S, OpPC, Ptr, AK_Assign)) 639 return false; 640 return true; 641 } 642 643 bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) { 644 645 if (F->isVirtual() && !S.getLangOpts().CPlusPlus20) { 646 const SourceLocation &Loc = S.Current->getLocation(OpPC); 647 S.CCEDiag(Loc, diag::note_constexpr_virtual_call); 648 return false; 649 } 650 651 if (F->isConstexpr() && F->hasBody() && 652 (F->getDecl()->isConstexpr() || F->getDecl()->hasAttr<MSConstexprAttr>())) 653 return true; 654 655 // Implicitly constexpr. 656 if (F->isLambdaStaticInvoker()) 657 return true; 658 659 const SourceLocation &Loc = S.Current->getLocation(OpPC); 660 if (S.getLangOpts().CPlusPlus11) { 661 const FunctionDecl *DiagDecl = F->getDecl(); 662 663 // Invalid decls have been diagnosed before. 664 if (DiagDecl->isInvalidDecl()) 665 return false; 666 667 // If this function is not constexpr because it is an inherited 668 // non-constexpr constructor, diagnose that directly. 669 const auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl); 670 if (CD && CD->isInheritingConstructor()) { 671 const auto *Inherited = CD->getInheritedConstructor().getConstructor(); 672 if (!Inherited->isConstexpr()) 673 DiagDecl = CD = Inherited; 674 } 675 676 // FIXME: If DiagDecl is an implicitly-declared special member function 677 // or an inheriting constructor, we should be much more explicit about why 678 // it's not constexpr. 679 if (CD && CD->isInheritingConstructor()) { 680 S.FFDiag(Loc, diag::note_constexpr_invalid_inhctor, 1) 681 << CD->getInheritedConstructor().getConstructor()->getParent(); 682 S.Note(DiagDecl->getLocation(), diag::note_declared_at); 683 } else { 684 // Don't emit anything if the function isn't defined and we're checking 685 // for a constant expression. It might be defined at the point we're 686 // actually calling it. 687 bool IsExtern = DiagDecl->getStorageClass() == SC_Extern; 688 if (!DiagDecl->isDefined() && !IsExtern && DiagDecl->isConstexpr() && 689 S.checkingPotentialConstantExpression()) 690 return false; 691 692 // If the declaration is defined, declared 'constexpr' _and_ has a body, 693 // the below diagnostic doesn't add anything useful. 694 if (DiagDecl->isDefined() && DiagDecl->isConstexpr() && 695 DiagDecl->hasBody()) 696 return false; 697 698 S.FFDiag(Loc, diag::note_constexpr_invalid_function, 1) 699 << DiagDecl->isConstexpr() << (bool)CD << DiagDecl; 700 701 if (DiagDecl->getDefinition()) 702 S.Note(DiagDecl->getDefinition()->getLocation(), 703 diag::note_declared_at); 704 else 705 S.Note(DiagDecl->getLocation(), diag::note_declared_at); 706 } 707 } else { 708 S.FFDiag(Loc, diag::note_invalid_subexpr_in_const_expr); 709 } 710 711 return false; 712 } 713 714 bool CheckCallDepth(InterpState &S, CodePtr OpPC) { 715 if ((S.Current->getDepth() + 1) > S.getLangOpts().ConstexprCallDepth) { 716 S.FFDiag(S.Current->getSource(OpPC), 717 diag::note_constexpr_depth_limit_exceeded) 718 << S.getLangOpts().ConstexprCallDepth; 719 return false; 720 } 721 722 return true; 723 } 724 725 bool CheckThis(InterpState &S, CodePtr OpPC, const Pointer &This) { 726 if (!This.isZero()) 727 return true; 728 729 const SourceInfo &Loc = S.Current->getSource(OpPC); 730 731 bool IsImplicit = false; 732 if (const auto *E = dyn_cast_if_present<CXXThisExpr>(Loc.asExpr())) 733 IsImplicit = E->isImplicit(); 734 735 if (S.getLangOpts().CPlusPlus11) 736 S.FFDiag(Loc, diag::note_constexpr_this) << IsImplicit; 737 else 738 S.FFDiag(Loc); 739 740 return false; 741 } 742 743 bool CheckPure(InterpState &S, CodePtr OpPC, const CXXMethodDecl *MD) { 744 if (!MD->isPureVirtual()) 745 return true; 746 const SourceInfo &E = S.Current->getSource(OpPC); 747 S.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << MD; 748 S.Note(MD->getLocation(), diag::note_declared_at); 749 return false; 750 } 751 752 bool CheckFloatResult(InterpState &S, CodePtr OpPC, const Floating &Result, 753 APFloat::opStatus Status) { 754 const SourceInfo &E = S.Current->getSource(OpPC); 755 756 // [expr.pre]p4: 757 // If during the evaluation of an expression, the result is not 758 // mathematically defined [...], the behavior is undefined. 759 // FIXME: C++ rules require us to not conform to IEEE 754 here. 760 if (Result.isNan()) { 761 S.CCEDiag(E, diag::note_constexpr_float_arithmetic) 762 << /*NaN=*/true << S.Current->getRange(OpPC); 763 return S.noteUndefinedBehavior(); 764 } 765 766 // In a constant context, assume that any dynamic rounding mode or FP 767 // exception state matches the default floating-point environment. 768 if (S.inConstantContext()) 769 return true; 770 771 FPOptions FPO = E.asExpr()->getFPFeaturesInEffect(S.Ctx.getLangOpts()); 772 773 if ((Status & APFloat::opInexact) && 774 FPO.getRoundingMode() == llvm::RoundingMode::Dynamic) { 775 // Inexact result means that it depends on rounding mode. If the requested 776 // mode is dynamic, the evaluation cannot be made in compile time. 777 S.FFDiag(E, diag::note_constexpr_dynamic_rounding); 778 return false; 779 } 780 781 if ((Status != APFloat::opOK) && 782 (FPO.getRoundingMode() == llvm::RoundingMode::Dynamic || 783 FPO.getExceptionMode() != LangOptions::FPE_Ignore || 784 FPO.getAllowFEnvAccess())) { 785 S.FFDiag(E, diag::note_constexpr_float_arithmetic_strict); 786 return false; 787 } 788 789 if ((Status & APFloat::opStatus::opInvalidOp) && 790 FPO.getExceptionMode() != LangOptions::FPE_Ignore) { 791 // There is no usefully definable result. 792 S.FFDiag(E); 793 return false; 794 } 795 796 return true; 797 } 798 799 bool CheckDynamicMemoryAllocation(InterpState &S, CodePtr OpPC) { 800 if (S.getLangOpts().CPlusPlus20) 801 return true; 802 803 const SourceInfo &E = S.Current->getSource(OpPC); 804 S.CCEDiag(E, diag::note_constexpr_new); 805 return true; 806 } 807 808 bool CheckNewDeleteForms(InterpState &S, CodePtr OpPC, bool NewWasArray, 809 bool DeleteIsArray, const Descriptor *D, 810 const Expr *NewExpr) { 811 if (NewWasArray == DeleteIsArray) 812 return true; 813 814 QualType TypeToDiagnose; 815 // We need to shuffle things around a bit here to get a better diagnostic, 816 // because the expression we allocated the block for was of type int*, 817 // but we want to get the array size right. 818 if (D->isArray()) { 819 QualType ElemQT = D->getType()->getPointeeType(); 820 TypeToDiagnose = S.getASTContext().getConstantArrayType( 821 ElemQT, APInt(64, static_cast<uint64_t>(D->getNumElems()), false), 822 nullptr, ArraySizeModifier::Normal, 0); 823 } else 824 TypeToDiagnose = D->getType()->getPointeeType(); 825 826 const SourceInfo &E = S.Current->getSource(OpPC); 827 S.FFDiag(E, diag::note_constexpr_new_delete_mismatch) 828 << DeleteIsArray << 0 << TypeToDiagnose; 829 S.Note(NewExpr->getExprLoc(), diag::note_constexpr_dynamic_alloc_here) 830 << NewExpr->getSourceRange(); 831 return false; 832 } 833 834 bool CheckDeleteSource(InterpState &S, CodePtr OpPC, const Expr *Source, 835 const Pointer &Ptr) { 836 if (Source && isa<CXXNewExpr>(Source)) 837 return true; 838 839 // Whatever this is, we didn't heap allocate it. 840 const SourceInfo &Loc = S.Current->getSource(OpPC); 841 S.FFDiag(Loc, diag::note_constexpr_delete_not_heap_alloc) 842 << Ptr.toDiagnosticString(S.getASTContext()); 843 844 if (Ptr.isTemporary()) 845 S.Note(Ptr.getDeclLoc(), diag::note_constexpr_temporary_here); 846 else 847 S.Note(Ptr.getDeclLoc(), diag::note_declared_at); 848 return false; 849 } 850 851 /// We aleady know the given DeclRefExpr is invalid for some reason, 852 /// now figure out why and print appropriate diagnostics. 853 bool CheckDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR) { 854 const ValueDecl *D = DR->getDecl(); 855 return diagnoseUnknownDecl(S, OpPC, D); 856 } 857 858 bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr, 859 AccessKinds AK) { 860 if (!Ptr.isDummy()) 861 return true; 862 863 const Descriptor *Desc = Ptr.getDeclDesc(); 864 const ValueDecl *D = Desc->asValueDecl(); 865 if (!D) 866 return false; 867 868 if (AK == AK_Read || AK == AK_Increment || AK == AK_Decrement) 869 return diagnoseUnknownDecl(S, OpPC, D); 870 871 assert(AK == AK_Assign); 872 if (S.getLangOpts().CPlusPlus11) { 873 const SourceInfo &E = S.Current->getSource(OpPC); 874 S.FFDiag(E, diag::note_constexpr_modify_global); 875 } 876 return false; 877 } 878 879 bool CheckNonNullArgs(InterpState &S, CodePtr OpPC, const Function *F, 880 const CallExpr *CE, unsigned ArgSize) { 881 auto Args = llvm::ArrayRef(CE->getArgs(), CE->getNumArgs()); 882 auto NonNullArgs = collectNonNullArgs(F->getDecl(), Args); 883 unsigned Offset = 0; 884 unsigned Index = 0; 885 for (const Expr *Arg : Args) { 886 if (NonNullArgs[Index] && Arg->getType()->isPointerType()) { 887 const Pointer &ArgPtr = S.Stk.peek<Pointer>(ArgSize - Offset); 888 if (ArgPtr.isZero()) { 889 const SourceLocation &Loc = S.Current->getLocation(OpPC); 890 S.CCEDiag(Loc, diag::note_non_null_attribute_failed); 891 return false; 892 } 893 } 894 895 Offset += align(primSize(S.Ctx.classify(Arg).value_or(PT_Ptr))); 896 ++Index; 897 } 898 return true; 899 } 900 901 // FIXME: This is similar to code we already have in Compiler.cpp. 902 // I think it makes sense to instead add the field and base destruction stuff 903 // to the destructor Function itself. Then destroying a record would really 904 // _just_ be calling its destructor. That would also help with the diagnostic 905 // difference when the destructor or a field/base fails. 906 static bool runRecordDestructor(InterpState &S, CodePtr OpPC, 907 const Pointer &BasePtr, 908 const Descriptor *Desc) { 909 assert(Desc->isRecord()); 910 const Record *R = Desc->ElemRecord; 911 assert(R); 912 913 if (Pointer::pointToSameBlock(BasePtr, S.Current->getThis())) { 914 const SourceInfo &Loc = S.Current->getSource(OpPC); 915 S.FFDiag(Loc, diag::note_constexpr_double_destroy); 916 return false; 917 } 918 919 // Destructor of this record. 920 if (const CXXDestructorDecl *Dtor = R->getDestructor(); 921 Dtor && !Dtor->isTrivial()) { 922 const Function *DtorFunc = S.getContext().getOrCreateFunction(Dtor); 923 if (!DtorFunc) 924 return false; 925 926 S.Stk.push<Pointer>(BasePtr); 927 if (!Call(S, OpPC, DtorFunc, 0)) 928 return false; 929 } 930 return true; 931 } 932 933 bool RunDestructors(InterpState &S, CodePtr OpPC, const Block *B) { 934 assert(B); 935 const Descriptor *Desc = B->getDescriptor(); 936 937 if (Desc->isPrimitive() || Desc->isPrimitiveArray()) 938 return true; 939 940 assert(Desc->isRecord() || Desc->isCompositeArray()); 941 942 if (Desc->isCompositeArray()) { 943 const Descriptor *ElemDesc = Desc->ElemDesc; 944 assert(ElemDesc->isRecord()); 945 946 Pointer RP(const_cast<Block *>(B)); 947 for (unsigned I = 0; I != Desc->getNumElems(); ++I) { 948 if (!runRecordDestructor(S, OpPC, RP.atIndex(I).narrow(), ElemDesc)) 949 return false; 950 } 951 return true; 952 } 953 954 assert(Desc->isRecord()); 955 return runRecordDestructor(S, OpPC, Pointer(const_cast<Block *>(B)), Desc); 956 } 957 958 void diagnoseEnumValue(InterpState &S, CodePtr OpPC, const EnumDecl *ED, 959 const APSInt &Value) { 960 llvm::APInt Min; 961 llvm::APInt Max; 962 963 if (S.EvaluatingDecl && !S.EvaluatingDecl->isConstexpr()) 964 return; 965 966 ED->getValueRange(Max, Min); 967 --Max; 968 969 if (ED->getNumNegativeBits() && 970 (Max.slt(Value.getSExtValue()) || Min.sgt(Value.getSExtValue()))) { 971 const SourceLocation &Loc = S.Current->getLocation(OpPC); 972 S.CCEDiag(Loc, diag::note_constexpr_unscoped_enum_out_of_range) 973 << llvm::toString(Value, 10) << Min.getSExtValue() << Max.getSExtValue() 974 << ED; 975 } else if (!ED->getNumNegativeBits() && Max.ult(Value.getZExtValue())) { 976 const SourceLocation &Loc = S.Current->getLocation(OpPC); 977 S.CCEDiag(Loc, diag::note_constexpr_unscoped_enum_out_of_range) 978 << llvm::toString(Value, 10) << Min.getZExtValue() << Max.getZExtValue() 979 << ED; 980 } 981 } 982 983 bool Interpret(InterpState &S, APValue &Result) { 984 // The current stack frame when we started Interpret(). 985 // This is being used by the ops to determine wheter 986 // to return from this function and thus terminate 987 // interpretation. 988 const InterpFrame *StartFrame = S.Current; 989 assert(!S.Current->isRoot()); 990 CodePtr PC = S.Current->getPC(); 991 992 // Empty program. 993 if (!PC) 994 return true; 995 996 for (;;) { 997 auto Op = PC.read<Opcode>(); 998 CodePtr OpPC = PC; 999 1000 switch (Op) { 1001 #define GET_INTERP 1002 #include "Opcodes.inc" 1003 #undef GET_INTERP 1004 } 1005 } 1006 } 1007 1008 } // namespace interp 1009 } // namespace clang 1010