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