1 //===--- Context.cpp - Context 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 "Context.h" 10 #include "ByteCodeEmitter.h" 11 #include "Compiler.h" 12 #include "EvalEmitter.h" 13 #include "Interp.h" 14 #include "InterpFrame.h" 15 #include "InterpStack.h" 16 #include "PrimType.h" 17 #include "Program.h" 18 #include "clang/AST/Expr.h" 19 #include "clang/Basic/TargetInfo.h" 20 21 using namespace clang; 22 using namespace clang::interp; 23 24 Context::Context(ASTContext &Ctx) : Ctx(Ctx), P(new Program(*this)) { 25 this->ShortWidth = Ctx.getTargetInfo().getShortWidth(); 26 this->IntWidth = Ctx.getTargetInfo().getIntWidth(); 27 this->LongWidth = Ctx.getTargetInfo().getLongWidth(); 28 this->LongLongWidth = Ctx.getTargetInfo().getLongLongWidth(); 29 assert(Ctx.getTargetInfo().getCharWidth() == 8 && 30 "We're assuming 8 bit chars"); 31 } 32 33 Context::~Context() {} 34 35 bool Context::isPotentialConstantExpr(State &Parent, const FunctionDecl *FD) { 36 assert(Stk.empty()); 37 38 // Get a function handle. 39 const Function *Func = getOrCreateFunction(FD); 40 if (!Func) 41 return false; 42 43 // Compile the function. 44 Compiler<ByteCodeEmitter>(*this, *P).compileFunc( 45 FD, const_cast<Function *>(Func)); 46 47 ++EvalID; 48 // And run it. 49 if (!Run(Parent, Func)) 50 return false; 51 52 return Func->isValid(); 53 } 54 55 bool Context::evaluateAsRValue(State &Parent, const Expr *E, APValue &Result) { 56 ++EvalID; 57 bool Recursing = !Stk.empty(); 58 size_t StackSizeBefore = Stk.size(); 59 Compiler<EvalEmitter> C(*this, *P, Parent, Stk); 60 61 auto Res = C.interpretExpr(E, /*ConvertResultToRValue=*/E->isGLValue()); 62 63 if (Res.isInvalid()) { 64 C.cleanup(); 65 Stk.clearTo(StackSizeBefore); 66 return false; 67 } 68 69 if (!Recursing) { 70 // We *can* actually get here with a non-empty stack, since 71 // things like InterpState::noteSideEffect() exist. 72 C.cleanup(); 73 #ifndef NDEBUG 74 // Make sure we don't rely on some value being still alive in 75 // InterpStack memory. 76 Stk.clearTo(StackSizeBefore); 77 #endif 78 } 79 80 Result = Res.toAPValue(); 81 82 return true; 83 } 84 85 bool Context::evaluate(State &Parent, const Expr *E, APValue &Result, 86 ConstantExprKind Kind) { 87 ++EvalID; 88 bool Recursing = !Stk.empty(); 89 size_t StackSizeBefore = Stk.size(); 90 Compiler<EvalEmitter> C(*this, *P, Parent, Stk); 91 92 auto Res = C.interpretExpr(E, /*ConvertResultToRValue=*/false, 93 /*DestroyToplevelScope=*/true); 94 if (Res.isInvalid()) { 95 C.cleanup(); 96 Stk.clearTo(StackSizeBefore); 97 return false; 98 } 99 100 if (!Recursing) { 101 assert(Stk.empty()); 102 C.cleanup(); 103 #ifndef NDEBUG 104 // Make sure we don't rely on some value being still alive in 105 // InterpStack memory. 106 Stk.clearTo(StackSizeBefore); 107 #endif 108 } 109 110 Result = Res.toAPValue(); 111 return true; 112 } 113 114 bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD, 115 APValue &Result) { 116 ++EvalID; 117 bool Recursing = !Stk.empty(); 118 size_t StackSizeBefore = Stk.size(); 119 Compiler<EvalEmitter> C(*this, *P, Parent, Stk); 120 121 bool CheckGlobalInitialized = 122 shouldBeGloballyIndexed(VD) && 123 (VD->getType()->isRecordType() || VD->getType()->isArrayType()); 124 auto Res = C.interpretDecl(VD, CheckGlobalInitialized); 125 if (Res.isInvalid()) { 126 C.cleanup(); 127 Stk.clearTo(StackSizeBefore); 128 129 return false; 130 } 131 132 if (!Recursing) { 133 assert(Stk.empty()); 134 C.cleanup(); 135 #ifndef NDEBUG 136 // Make sure we don't rely on some value being still alive in 137 // InterpStack memory. 138 Stk.clearTo(StackSizeBefore); 139 #endif 140 } 141 142 Result = Res.toAPValue(); 143 return true; 144 } 145 146 template <typename ResultT> 147 bool Context::evaluateStringRepr(State &Parent, const Expr *SizeExpr, 148 const Expr *PtrExpr, ResultT &Result) { 149 assert(Stk.empty()); 150 Compiler<EvalEmitter> C(*this, *P, Parent, Stk); 151 152 // Evaluate size value. 153 APValue SizeValue; 154 if (!evaluateAsRValue(Parent, SizeExpr, SizeValue)) 155 return false; 156 157 if (!SizeValue.isInt()) 158 return false; 159 uint64_t Size = SizeValue.getInt().getZExtValue(); 160 161 auto PtrRes = C.interpretAsPointer(PtrExpr, [&](const Pointer &Ptr) { 162 if (Size == 0) { 163 if constexpr (std::is_same_v<ResultT, APValue>) 164 Result = APValue(APValue::UninitArray{}, 0, 0); 165 return true; 166 } 167 168 if (!Ptr.isLive() || !Ptr.getFieldDesc()->isPrimitiveArray()) 169 return false; 170 171 // Must be char. 172 if (Ptr.getFieldDesc()->getElemSize() != 1 /*bytes*/) 173 return false; 174 175 if (Size > Ptr.getNumElems()) { 176 Parent.FFDiag(SizeExpr, diag::note_constexpr_access_past_end) << AK_Read; 177 Size = Ptr.getNumElems(); 178 } 179 180 if constexpr (std::is_same_v<ResultT, APValue>) { 181 QualType CharTy = PtrExpr->getType()->getPointeeType(); 182 Result = APValue(APValue::UninitArray{}, Size, Size); 183 for (uint64_t I = 0; I != Size; ++I) { 184 if (std::optional<APValue> ElemVal = 185 Ptr.atIndex(I).toRValue(*this, CharTy)) 186 Result.getArrayInitializedElt(I) = *ElemVal; 187 else 188 return false; 189 } 190 } else { 191 assert((std::is_same_v<ResultT, std::string>)); 192 if (Size < Result.max_size()) 193 Result.resize(Size); 194 Result.assign(reinterpret_cast<const char *>(Ptr.getRawAddress()), Size); 195 } 196 197 return true; 198 }); 199 200 if (PtrRes.isInvalid()) { 201 C.cleanup(); 202 Stk.clear(); 203 return false; 204 } 205 206 return true; 207 } 208 209 bool Context::evaluateCharRange(State &Parent, const Expr *SizeExpr, 210 const Expr *PtrExpr, APValue &Result) { 211 assert(SizeExpr); 212 assert(PtrExpr); 213 214 return evaluateStringRepr(Parent, SizeExpr, PtrExpr, Result); 215 } 216 217 bool Context::evaluateCharRange(State &Parent, const Expr *SizeExpr, 218 const Expr *PtrExpr, std::string &Result) { 219 assert(SizeExpr); 220 assert(PtrExpr); 221 222 return evaluateStringRepr(Parent, SizeExpr, PtrExpr, Result); 223 } 224 225 const LangOptions &Context::getLangOpts() const { return Ctx.getLangOpts(); } 226 227 static PrimType integralTypeToPrimTypeS(unsigned BitWidth) { 228 switch (BitWidth) { 229 case 64: 230 return PT_Sint64; 231 case 32: 232 return PT_Sint32; 233 case 16: 234 return PT_Sint16; 235 case 8: 236 return PT_Sint8; 237 default: 238 return PT_IntAPS; 239 } 240 llvm_unreachable("Unhandled BitWidth"); 241 } 242 243 static PrimType integralTypeToPrimTypeU(unsigned BitWidth) { 244 switch (BitWidth) { 245 case 64: 246 return PT_Uint64; 247 case 32: 248 return PT_Uint32; 249 case 16: 250 return PT_Uint16; 251 case 8: 252 return PT_Uint8; 253 default: 254 return PT_IntAP; 255 } 256 llvm_unreachable("Unhandled BitWidth"); 257 } 258 259 std::optional<PrimType> Context::classify(QualType T) const { 260 261 if (const auto *BT = dyn_cast<BuiltinType>(T.getCanonicalType())) { 262 auto Kind = BT->getKind(); 263 if (Kind == BuiltinType::Bool) 264 return PT_Bool; 265 if (Kind == BuiltinType::NullPtr) 266 return PT_Ptr; 267 if (Kind == BuiltinType::BoundMember) 268 return PT_MemberPtr; 269 270 // Just trying to avoid the ASTContext::getIntWidth call below. 271 if (Kind == BuiltinType::Short) 272 return integralTypeToPrimTypeS(this->ShortWidth); 273 if (Kind == BuiltinType::UShort) 274 return integralTypeToPrimTypeU(this->ShortWidth); 275 276 if (Kind == BuiltinType::Int) 277 return integralTypeToPrimTypeS(this->IntWidth); 278 if (Kind == BuiltinType::UInt) 279 return integralTypeToPrimTypeU(this->IntWidth); 280 if (Kind == BuiltinType::Long) 281 return integralTypeToPrimTypeS(this->LongWidth); 282 if (Kind == BuiltinType::ULong) 283 return integralTypeToPrimTypeU(this->LongWidth); 284 if (Kind == BuiltinType::LongLong) 285 return integralTypeToPrimTypeS(this->LongLongWidth); 286 if (Kind == BuiltinType::ULongLong) 287 return integralTypeToPrimTypeU(this->LongLongWidth); 288 289 if (Kind == BuiltinType::SChar || Kind == BuiltinType::Char_S) 290 return integralTypeToPrimTypeS(8); 291 if (Kind == BuiltinType::UChar || Kind == BuiltinType::Char_U || 292 Kind == BuiltinType::Char8) 293 return integralTypeToPrimTypeU(8); 294 295 if (BT->isSignedInteger()) 296 return integralTypeToPrimTypeS(Ctx.getIntWidth(T)); 297 if (BT->isUnsignedInteger()) 298 return integralTypeToPrimTypeU(Ctx.getIntWidth(T)); 299 300 if (BT->isFloatingPoint()) 301 return PT_Float; 302 } 303 304 if (T->isPointerOrReferenceType()) 305 return PT_Ptr; 306 307 if (T->isMemberPointerType()) 308 return PT_MemberPtr; 309 310 if (const auto *BT = T->getAs<BitIntType>()) { 311 if (BT->isSigned()) 312 return integralTypeToPrimTypeS(BT->getNumBits()); 313 return integralTypeToPrimTypeU(BT->getNumBits()); 314 } 315 316 if (const auto *ET = T->getAs<EnumType>()) { 317 const auto *D = ET->getDecl(); 318 if (!D->isComplete()) 319 return std::nullopt; 320 return classify(D->getIntegerType()); 321 } 322 323 if (const auto *AT = T->getAs<AtomicType>()) 324 return classify(AT->getValueType()); 325 326 if (const auto *DT = dyn_cast<DecltypeType>(T)) 327 return classify(DT->getUnderlyingType()); 328 329 if (T->isObjCObjectPointerType() || T->isBlockPointerType()) 330 return PT_Ptr; 331 332 if (T->isFixedPointType()) 333 return PT_FixedPoint; 334 335 // Vector and complex types get here. 336 return std::nullopt; 337 } 338 339 unsigned Context::getCharBit() const { 340 return Ctx.getTargetInfo().getCharWidth(); 341 } 342 343 /// Simple wrapper around getFloatTypeSemantics() to make code a 344 /// little shorter. 345 const llvm::fltSemantics &Context::getFloatSemantics(QualType T) const { 346 return Ctx.getFloatTypeSemantics(T); 347 } 348 349 bool Context::Run(State &Parent, const Function *Func) { 350 351 { 352 InterpState State(Parent, *P, Stk, *this, Func); 353 if (Interpret(State)) { 354 assert(Stk.empty()); 355 return true; 356 } 357 // State gets destroyed here, so the Stk.clear() below doesn't accidentally 358 // remove values the State's destructor might access. 359 } 360 361 Stk.clear(); 362 return false; 363 } 364 365 // TODO: Virtual bases? 366 const CXXMethodDecl * 367 Context::getOverridingFunction(const CXXRecordDecl *DynamicDecl, 368 const CXXRecordDecl *StaticDecl, 369 const CXXMethodDecl *InitialFunction) const { 370 assert(DynamicDecl); 371 assert(StaticDecl); 372 assert(InitialFunction); 373 374 const CXXRecordDecl *CurRecord = DynamicDecl; 375 const CXXMethodDecl *FoundFunction = InitialFunction; 376 for (;;) { 377 const CXXMethodDecl *Overrider = 378 FoundFunction->getCorrespondingMethodDeclaredInClass(CurRecord, false); 379 if (Overrider) 380 return Overrider; 381 382 // Common case of only one base class. 383 if (CurRecord->getNumBases() == 1) { 384 CurRecord = CurRecord->bases_begin()->getType()->getAsCXXRecordDecl(); 385 continue; 386 } 387 388 // Otherwise, go to the base class that will lead to the StaticDecl. 389 for (const CXXBaseSpecifier &Spec : CurRecord->bases()) { 390 const CXXRecordDecl *Base = Spec.getType()->getAsCXXRecordDecl(); 391 if (Base == StaticDecl || Base->isDerivedFrom(StaticDecl)) { 392 CurRecord = Base; 393 break; 394 } 395 } 396 } 397 398 llvm_unreachable( 399 "Couldn't find an overriding function in the class hierarchy?"); 400 return nullptr; 401 } 402 403 const Function *Context::getOrCreateFunction(const FunctionDecl *FuncDecl) { 404 assert(FuncDecl); 405 FuncDecl = FuncDecl->getMostRecentDecl(); 406 407 if (const Function *Func = P->getFunction(FuncDecl)) 408 return Func; 409 410 // Manually created functions that haven't been assigned proper 411 // parameters yet. 412 if (!FuncDecl->param_empty() && !FuncDecl->param_begin()) 413 return nullptr; 414 415 bool IsLambdaStaticInvoker = false; 416 if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl); 417 MD && MD->isLambdaStaticInvoker()) { 418 // For a lambda static invoker, we might have to pick a specialized 419 // version if the lambda is generic. In that case, the picked function 420 // will *NOT* be a static invoker anymore. However, it will still 421 // be a non-static member function, this (usually) requiring an 422 // instance pointer. We suppress that later in this function. 423 IsLambdaStaticInvoker = true; 424 425 const CXXRecordDecl *ClosureClass = MD->getParent(); 426 assert(ClosureClass->captures_begin() == ClosureClass->captures_end()); 427 if (ClosureClass->isGenericLambda()) { 428 const CXXMethodDecl *LambdaCallOp = ClosureClass->getLambdaCallOperator(); 429 assert(MD->isFunctionTemplateSpecialization() && 430 "A generic lambda's static-invoker function must be a " 431 "template specialization"); 432 const TemplateArgumentList *TAL = MD->getTemplateSpecializationArgs(); 433 FunctionTemplateDecl *CallOpTemplate = 434 LambdaCallOp->getDescribedFunctionTemplate(); 435 void *InsertPos = nullptr; 436 const FunctionDecl *CorrespondingCallOpSpecialization = 437 CallOpTemplate->findSpecialization(TAL->asArray(), InsertPos); 438 assert(CorrespondingCallOpSpecialization); 439 FuncDecl = CorrespondingCallOpSpecialization; 440 } 441 } 442 // Set up argument indices. 443 unsigned ParamOffset = 0; 444 SmallVector<PrimType, 8> ParamTypes; 445 SmallVector<unsigned, 8> ParamOffsets; 446 llvm::DenseMap<unsigned, Function::ParamDescriptor> ParamDescriptors; 447 448 // If the return is not a primitive, a pointer to the storage where the 449 // value is initialized in is passed as the first argument. See 'RVO' 450 // elsewhere in the code. 451 QualType Ty = FuncDecl->getReturnType(); 452 bool HasRVO = false; 453 if (!Ty->isVoidType() && !classify(Ty)) { 454 HasRVO = true; 455 ParamTypes.push_back(PT_Ptr); 456 ParamOffsets.push_back(ParamOffset); 457 ParamOffset += align(primSize(PT_Ptr)); 458 } 459 460 // If the function decl is a member decl, the next parameter is 461 // the 'this' pointer. This parameter is pop()ed from the 462 // InterpStack when calling the function. 463 bool HasThisPointer = false; 464 if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl)) { 465 if (!IsLambdaStaticInvoker) { 466 HasThisPointer = MD->isInstance(); 467 if (MD->isImplicitObjectMemberFunction()) { 468 ParamTypes.push_back(PT_Ptr); 469 ParamOffsets.push_back(ParamOffset); 470 ParamOffset += align(primSize(PT_Ptr)); 471 } 472 } 473 474 if (isLambdaCallOperator(MD)) { 475 // The parent record needs to be complete, we need to know about all 476 // the lambda captures. 477 if (!MD->getParent()->isCompleteDefinition()) 478 return nullptr; 479 llvm::DenseMap<const ValueDecl *, FieldDecl *> LC; 480 FieldDecl *LTC; 481 482 MD->getParent()->getCaptureFields(LC, LTC); 483 484 if (MD->isStatic() && !LC.empty()) { 485 // Static lambdas cannot have any captures. If this one does, 486 // it has already been diagnosed and we can only ignore it. 487 return nullptr; 488 } 489 } 490 } 491 492 // Assign descriptors to all parameters. 493 // Composite objects are lowered to pointers. 494 for (const ParmVarDecl *PD : FuncDecl->parameters()) { 495 std::optional<PrimType> T = classify(PD->getType()); 496 PrimType PT = T.value_or(PT_Ptr); 497 Descriptor *Desc = P->createDescriptor(PD, PT); 498 ParamDescriptors.insert({ParamOffset, {PT, Desc}}); 499 ParamOffsets.push_back(ParamOffset); 500 ParamOffset += align(primSize(PT)); 501 ParamTypes.push_back(PT); 502 } 503 504 // Create a handle over the emitted code. 505 assert(!P->getFunction(FuncDecl)); 506 const Function *Func = P->createFunction( 507 FuncDecl, ParamOffset, std::move(ParamTypes), std::move(ParamDescriptors), 508 std::move(ParamOffsets), HasThisPointer, HasRVO, IsLambdaStaticInvoker); 509 return Func; 510 } 511 512 const Function *Context::getOrCreateObjCBlock(const BlockExpr *E) { 513 const BlockDecl *BD = E->getBlockDecl(); 514 // Set up argument indices. 515 unsigned ParamOffset = 0; 516 SmallVector<PrimType, 8> ParamTypes; 517 SmallVector<unsigned, 8> ParamOffsets; 518 llvm::DenseMap<unsigned, Function::ParamDescriptor> ParamDescriptors; 519 520 // Assign descriptors to all parameters. 521 // Composite objects are lowered to pointers. 522 for (const ParmVarDecl *PD : BD->parameters()) { 523 std::optional<PrimType> T = classify(PD->getType()); 524 PrimType PT = T.value_or(PT_Ptr); 525 Descriptor *Desc = P->createDescriptor(PD, PT); 526 ParamDescriptors.insert({ParamOffset, {PT, Desc}}); 527 ParamOffsets.push_back(ParamOffset); 528 ParamOffset += align(primSize(PT)); 529 ParamTypes.push_back(PT); 530 } 531 532 if (BD->hasCaptures()) 533 return nullptr; 534 535 // Create a handle over the emitted code. 536 Function *Func = 537 P->createFunction(E, ParamOffset, std::move(ParamTypes), 538 std::move(ParamDescriptors), std::move(ParamOffsets), 539 /*HasThisPointer=*/false, /*HasRVO=*/false, 540 /*IsLambdaStaticInvoker=*/false); 541 542 assert(Func); 543 Func->setDefined(true); 544 // We don't compile the BlockDecl code at all right now. 545 Func->setIsFullyCompiled(true); 546 return Func; 547 } 548 549 unsigned Context::collectBaseOffset(const RecordDecl *BaseDecl, 550 const RecordDecl *DerivedDecl) const { 551 assert(BaseDecl); 552 assert(DerivedDecl); 553 const auto *FinalDecl = cast<CXXRecordDecl>(BaseDecl); 554 const RecordDecl *CurDecl = DerivedDecl; 555 const Record *CurRecord = P->getOrCreateRecord(CurDecl); 556 assert(CurDecl && FinalDecl); 557 558 unsigned OffsetSum = 0; 559 for (;;) { 560 assert(CurRecord->getNumBases() > 0); 561 // One level up 562 for (const Record::Base &B : CurRecord->bases()) { 563 const auto *BaseDecl = cast<CXXRecordDecl>(B.Decl); 564 565 if (BaseDecl == FinalDecl || BaseDecl->isDerivedFrom(FinalDecl)) { 566 OffsetSum += B.Offset; 567 CurRecord = B.R; 568 CurDecl = BaseDecl; 569 break; 570 } 571 } 572 if (CurDecl == FinalDecl) 573 break; 574 } 575 576 assert(OffsetSum > 0); 577 return OffsetSum; 578 } 579 580 const Record *Context::getRecord(const RecordDecl *D) const { 581 return P->getOrCreateRecord(D); 582 } 583 584 bool Context::isUnevaluatedBuiltin(unsigned ID) { 585 return ID == Builtin::BI__builtin_classify_type || 586 ID == Builtin::BI__builtin_os_log_format_buffer_size || 587 ID == Builtin::BI__builtin_constant_p || ID == Builtin::BI__noop; 588 } 589