xref: /freebsd/contrib/llvm-project/clang/lib/AST/ByteCode/Context.cpp (revision 770cf0a5f02dc8983a89c6568d741fbc25baa999)
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