xref: /llvm-project/clang/lib/AST/ByteCode/Interp.cpp (revision a07aba5d44204a7ca0d891a3da05af9960081e4c)
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     bool IsTemp = Ptr.isTemporary();
309 
310     S.FFDiag(Src, diag::note_constexpr_lifetime_ended, 1) << AK << !IsTemp;
311 
312     if (IsTemp)
313       S.Note(Ptr.getDeclLoc(), diag::note_constexpr_temporary_here);
314     else
315       S.Note(Ptr.getDeclLoc(), diag::note_declared_at);
316 
317     return false;
318   }
319 
320   return true;
321 }
322 
323 bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc) {
324   assert(Desc);
325 
326   auto IsConstType = [&S](const VarDecl *VD) -> bool {
327     QualType T = VD->getType();
328 
329     if (T.isConstant(S.getCtx()))
330       return true;
331 
332     if (S.getLangOpts().CPlusPlus && !S.getLangOpts().CPlusPlus11)
333       return (T->isSignedIntegerOrEnumerationType() ||
334               T->isUnsignedIntegerOrEnumerationType()) &&
335              T.isConstQualified();
336 
337     if (T.isConstQualified())
338       return true;
339 
340     if (const auto *RT = T->getAs<ReferenceType>())
341       return RT->getPointeeType().isConstQualified();
342 
343     if (const auto *PT = T->getAs<PointerType>())
344       return PT->getPointeeType().isConstQualified();
345 
346     return false;
347   };
348 
349   if (const auto *D = Desc->asVarDecl();
350       D && D->hasGlobalStorage() && D != S.EvaluatingDecl && !IsConstType(D)) {
351     diagnoseNonConstVariable(S, OpPC, D);
352     return false;
353   }
354 
355   return true;
356 }
357 
358 static bool CheckConstant(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
359   if (!Ptr.isBlockPointer())
360     return true;
361   return CheckConstant(S, OpPC, Ptr.getDeclDesc());
362 }
363 
364 bool CheckNull(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
365                CheckSubobjectKind CSK) {
366   if (!Ptr.isZero())
367     return true;
368   const SourceInfo &Loc = S.Current->getSource(OpPC);
369   S.FFDiag(Loc, diag::note_constexpr_null_subobject)
370       << CSK << S.Current->getRange(OpPC);
371 
372   return false;
373 }
374 
375 bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
376                 AccessKinds AK) {
377   if (!Ptr.isOnePastEnd())
378     return true;
379   const SourceInfo &Loc = S.Current->getSource(OpPC);
380   S.FFDiag(Loc, diag::note_constexpr_access_past_end)
381       << AK << S.Current->getRange(OpPC);
382   return false;
383 }
384 
385 bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
386                 CheckSubobjectKind CSK) {
387   if (!Ptr.isElementPastEnd())
388     return true;
389   const SourceInfo &Loc = S.Current->getSource(OpPC);
390   S.FFDiag(Loc, diag::note_constexpr_past_end_subobject)
391       << CSK << S.Current->getRange(OpPC);
392   return false;
393 }
394 
395 bool CheckSubobject(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
396                     CheckSubobjectKind CSK) {
397   if (!Ptr.isOnePastEnd())
398     return true;
399 
400   const SourceInfo &Loc = S.Current->getSource(OpPC);
401   S.FFDiag(Loc, diag::note_constexpr_past_end_subobject)
402       << CSK << S.Current->getRange(OpPC);
403   return false;
404 }
405 
406 bool CheckDowncast(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
407                    uint32_t Offset) {
408   uint32_t MinOffset = Ptr.getDeclDesc()->getMetadataSize();
409   uint32_t PtrOffset = Ptr.getByteOffset();
410 
411   // We subtract Offset from PtrOffset. The result must be at least
412   // MinOffset.
413   if (Offset < PtrOffset && (PtrOffset - Offset) >= MinOffset)
414     return true;
415 
416   const auto *E = cast<CastExpr>(S.Current->getExpr(OpPC));
417   QualType TargetQT = E->getType()->getPointeeType();
418   QualType MostDerivedQT = Ptr.getDeclPtr().getType();
419 
420   S.CCEDiag(E, diag::note_constexpr_invalid_downcast)
421       << MostDerivedQT << TargetQT;
422 
423   return false;
424 }
425 
426 bool CheckConst(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
427   assert(Ptr.isLive() && "Pointer is not live");
428   if (!Ptr.isConst() || Ptr.isMutable())
429     return true;
430 
431   // The This pointer is writable in constructors and destructors,
432   // even if isConst() returns true.
433   // TODO(perf): We could be hitting this code path quite a lot in complex
434   // constructors. Is there a better way to do this?
435   if (S.Current->getFunction()) {
436     for (const InterpFrame *Frame = S.Current; Frame; Frame = Frame->Caller) {
437       if (const Function *Func = Frame->getFunction();
438           Func && (Func->isConstructor() || Func->isDestructor()) &&
439           Ptr.block() == Frame->getThis().block()) {
440         return true;
441       }
442     }
443   }
444 
445   if (!Ptr.isBlockPointer())
446     return false;
447 
448   const QualType Ty = Ptr.getType();
449   const SourceInfo &Loc = S.Current->getSource(OpPC);
450   S.FFDiag(Loc, diag::note_constexpr_modify_const_type) << Ty;
451   return false;
452 }
453 
454 bool CheckMutable(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
455   assert(Ptr.isLive() && "Pointer is not live");
456   if (!Ptr.isMutable())
457     return true;
458 
459   // In C++14 onwards, it is permitted to read a mutable member whose
460   // lifetime began within the evaluation.
461   if (S.getLangOpts().CPlusPlus14 &&
462       Ptr.block()->getEvalID() == S.Ctx.getEvalID())
463     return true;
464 
465   const SourceInfo &Loc = S.Current->getSource(OpPC);
466   const FieldDecl *Field = Ptr.getField();
467   S.FFDiag(Loc, diag::note_constexpr_access_mutable, 1) << AK_Read << Field;
468   S.Note(Field->getLocation(), diag::note_declared_at);
469   return false;
470 }
471 
472 bool CheckVolatile(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
473                    AccessKinds AK) {
474   assert(Ptr.isLive());
475 
476   // FIXME: This check here might be kinda expensive. Maybe it would be better
477   // to have another field in InlineDescriptor for this?
478   if (!Ptr.isBlockPointer())
479     return true;
480 
481   QualType PtrType = Ptr.getType();
482   if (!PtrType.isVolatileQualified())
483     return true;
484 
485   const SourceInfo &Loc = S.Current->getSource(OpPC);
486   if (S.getLangOpts().CPlusPlus)
487     S.FFDiag(Loc, diag::note_constexpr_access_volatile_type) << AK << PtrType;
488   else
489     S.FFDiag(Loc);
490   return false;
491 }
492 
493 bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
494                       AccessKinds AK) {
495   assert(Ptr.isLive());
496 
497   if (Ptr.isInitialized())
498     return true;
499 
500   if (const auto *VD = Ptr.getDeclDesc()->asVarDecl();
501       VD && VD->hasGlobalStorage()) {
502     const SourceInfo &Loc = S.Current->getSource(OpPC);
503     if (VD->getAnyInitializer()) {
504       S.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << VD;
505       S.Note(VD->getLocation(), diag::note_declared_at);
506     } else {
507       diagnoseMissingInitializer(S, OpPC, VD);
508     }
509     return false;
510   }
511 
512   if (!S.checkingPotentialConstantExpression()) {
513     S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_uninit)
514         << AK << /*uninitialized=*/true << S.Current->getRange(OpPC);
515   }
516   return false;
517 }
518 
519 bool CheckGlobalInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
520   if (Ptr.isInitialized())
521     return true;
522 
523   assert(S.getLangOpts().CPlusPlus);
524   const auto *VD = cast<VarDecl>(Ptr.getDeclDesc()->asValueDecl());
525   if ((!VD->hasConstantInitialization() &&
526        VD->mightBeUsableInConstantExpressions(S.getCtx())) ||
527       (S.getLangOpts().OpenCL && !S.getLangOpts().CPlusPlus11 &&
528        !VD->hasICEInitializer(S.getCtx()))) {
529     const SourceInfo &Loc = S.Current->getSource(OpPC);
530     S.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << VD;
531     S.Note(VD->getLocation(), diag::note_declared_at);
532   }
533   return false;
534 }
535 
536 bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
537                AccessKinds AK) {
538   if (!CheckLive(S, OpPC, Ptr, AK))
539     return false;
540   if (!CheckConstant(S, OpPC, Ptr))
541     return false;
542 
543   if (!CheckDummy(S, OpPC, Ptr, AK))
544     return false;
545   if (!CheckExtern(S, OpPC, Ptr))
546     return false;
547   if (!CheckRange(S, OpPC, Ptr, AK))
548     return false;
549   if (!CheckActive(S, OpPC, Ptr, AK))
550     return false;
551   if (!CheckInitialized(S, OpPC, Ptr, AK))
552     return false;
553   if (!CheckTemporary(S, OpPC, Ptr, AK))
554     return false;
555   if (!CheckMutable(S, OpPC, Ptr))
556     return false;
557   if (!CheckVolatile(S, OpPC, Ptr, AK))
558     return false;
559   return true;
560 }
561 
562 bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
563   if (!CheckLive(S, OpPC, Ptr, AK_Assign))
564     return false;
565   if (!CheckDummy(S, OpPC, Ptr, AK_Assign))
566     return false;
567   if (!CheckExtern(S, OpPC, Ptr))
568     return false;
569   if (!CheckRange(S, OpPC, Ptr, AK_Assign))
570     return false;
571   if (!CheckGlobal(S, OpPC, Ptr))
572     return false;
573   if (!CheckConst(S, OpPC, Ptr))
574     return false;
575   return true;
576 }
577 
578 bool CheckInvoke(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
579   if (!CheckLive(S, OpPC, Ptr, AK_MemberCall))
580     return false;
581   if (!Ptr.isDummy()) {
582     if (!CheckExtern(S, OpPC, Ptr))
583       return false;
584     if (!CheckRange(S, OpPC, Ptr, AK_MemberCall))
585       return false;
586   }
587   return true;
588 }
589 
590 bool CheckInit(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
591   if (!CheckLive(S, OpPC, Ptr, AK_Assign))
592     return false;
593   if (!CheckRange(S, OpPC, Ptr, AK_Assign))
594     return false;
595   return true;
596 }
597 
598 bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) {
599 
600   if (F->isVirtual() && !S.getLangOpts().CPlusPlus20) {
601     const SourceLocation &Loc = S.Current->getLocation(OpPC);
602     S.CCEDiag(Loc, diag::note_constexpr_virtual_call);
603     return false;
604   }
605 
606   if (F->isConstexpr() && F->hasBody() &&
607       (F->getDecl()->isConstexpr() || F->getDecl()->hasAttr<MSConstexprAttr>()))
608     return true;
609 
610   // Implicitly constexpr.
611   if (F->isLambdaStaticInvoker())
612     return true;
613 
614   const SourceLocation &Loc = S.Current->getLocation(OpPC);
615   if (S.getLangOpts().CPlusPlus11) {
616     const FunctionDecl *DiagDecl = F->getDecl();
617 
618     // Invalid decls have been diagnosed before.
619     if (DiagDecl->isInvalidDecl())
620       return false;
621 
622     // If this function is not constexpr because it is an inherited
623     // non-constexpr constructor, diagnose that directly.
624     const auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
625     if (CD && CD->isInheritingConstructor()) {
626       const auto *Inherited = CD->getInheritedConstructor().getConstructor();
627       if (!Inherited->isConstexpr())
628         DiagDecl = CD = Inherited;
629     }
630 
631     // FIXME: If DiagDecl is an implicitly-declared special member function
632     // or an inheriting constructor, we should be much more explicit about why
633     // it's not constexpr.
634     if (CD && CD->isInheritingConstructor()) {
635       S.FFDiag(Loc, diag::note_constexpr_invalid_inhctor, 1)
636           << CD->getInheritedConstructor().getConstructor()->getParent();
637       S.Note(DiagDecl->getLocation(), diag::note_declared_at);
638     } else {
639       // Don't emit anything if the function isn't defined and we're checking
640       // for a constant expression. It might be defined at the point we're
641       // actually calling it.
642       bool IsExtern = DiagDecl->getStorageClass() == SC_Extern;
643       if (!DiagDecl->isDefined() && !IsExtern && DiagDecl->isConstexpr() &&
644           S.checkingPotentialConstantExpression())
645         return false;
646 
647       // If the declaration is defined, declared 'constexpr' _and_ has a body,
648       // the below diagnostic doesn't add anything useful.
649       if (DiagDecl->isDefined() && DiagDecl->isConstexpr() &&
650           DiagDecl->hasBody())
651         return false;
652 
653       S.FFDiag(Loc, diag::note_constexpr_invalid_function, 1)
654           << DiagDecl->isConstexpr() << (bool)CD << DiagDecl;
655 
656       if (DiagDecl->getDefinition())
657         S.Note(DiagDecl->getDefinition()->getLocation(),
658                diag::note_declared_at);
659       else
660         S.Note(DiagDecl->getLocation(), diag::note_declared_at);
661     }
662   } else {
663     S.FFDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
664   }
665 
666   return false;
667 }
668 
669 bool CheckCallDepth(InterpState &S, CodePtr OpPC) {
670   if ((S.Current->getDepth() + 1) > S.getLangOpts().ConstexprCallDepth) {
671     S.FFDiag(S.Current->getSource(OpPC),
672              diag::note_constexpr_depth_limit_exceeded)
673         << S.getLangOpts().ConstexprCallDepth;
674     return false;
675   }
676 
677   return true;
678 }
679 
680 bool CheckThis(InterpState &S, CodePtr OpPC, const Pointer &This) {
681   if (!This.isZero())
682     return true;
683 
684   const SourceInfo &Loc = S.Current->getSource(OpPC);
685 
686   bool IsImplicit = false;
687   if (const auto *E = dyn_cast_if_present<CXXThisExpr>(Loc.asExpr()))
688     IsImplicit = E->isImplicit();
689 
690   if (S.getLangOpts().CPlusPlus11)
691     S.FFDiag(Loc, diag::note_constexpr_this) << IsImplicit;
692   else
693     S.FFDiag(Loc);
694 
695   return false;
696 }
697 
698 bool CheckPure(InterpState &S, CodePtr OpPC, const CXXMethodDecl *MD) {
699   if (!MD->isPureVirtual())
700     return true;
701   const SourceInfo &E = S.Current->getSource(OpPC);
702   S.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << MD;
703   S.Note(MD->getLocation(), diag::note_declared_at);
704   return false;
705 }
706 
707 bool CheckFloatResult(InterpState &S, CodePtr OpPC, const Floating &Result,
708                       APFloat::opStatus Status) {
709   const SourceInfo &E = S.Current->getSource(OpPC);
710 
711   // [expr.pre]p4:
712   //   If during the evaluation of an expression, the result is not
713   //   mathematically defined [...], the behavior is undefined.
714   // FIXME: C++ rules require us to not conform to IEEE 754 here.
715   if (Result.isNan()) {
716     S.CCEDiag(E, diag::note_constexpr_float_arithmetic)
717         << /*NaN=*/true << S.Current->getRange(OpPC);
718     return S.noteUndefinedBehavior();
719   }
720 
721   // In a constant context, assume that any dynamic rounding mode or FP
722   // exception state matches the default floating-point environment.
723   if (S.inConstantContext())
724     return true;
725 
726   FPOptions FPO = E.asExpr()->getFPFeaturesInEffect(S.Ctx.getLangOpts());
727 
728   if ((Status & APFloat::opInexact) &&
729       FPO.getRoundingMode() == llvm::RoundingMode::Dynamic) {
730     // Inexact result means that it depends on rounding mode. If the requested
731     // mode is dynamic, the evaluation cannot be made in compile time.
732     S.FFDiag(E, diag::note_constexpr_dynamic_rounding);
733     return false;
734   }
735 
736   if ((Status != APFloat::opOK) &&
737       (FPO.getRoundingMode() == llvm::RoundingMode::Dynamic ||
738        FPO.getExceptionMode() != LangOptions::FPE_Ignore ||
739        FPO.getAllowFEnvAccess())) {
740     S.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
741     return false;
742   }
743 
744   if ((Status & APFloat::opStatus::opInvalidOp) &&
745       FPO.getExceptionMode() != LangOptions::FPE_Ignore) {
746     // There is no usefully definable result.
747     S.FFDiag(E);
748     return false;
749   }
750 
751   return true;
752 }
753 
754 bool CheckDynamicMemoryAllocation(InterpState &S, CodePtr OpPC) {
755   if (S.getLangOpts().CPlusPlus20)
756     return true;
757 
758   const SourceInfo &E = S.Current->getSource(OpPC);
759   S.CCEDiag(E, diag::note_constexpr_new);
760   return true;
761 }
762 
763 bool CheckNewDeleteForms(InterpState &S, CodePtr OpPC, bool NewWasArray,
764                          bool DeleteIsArray, const Descriptor *D,
765                          const Expr *NewExpr) {
766   if (NewWasArray == DeleteIsArray)
767     return true;
768 
769   QualType TypeToDiagnose;
770   // We need to shuffle things around a bit here to get a better diagnostic,
771   // because the expression we allocated the block for was of type int*,
772   // but we want to get the array size right.
773   if (D->isArray()) {
774     QualType ElemQT = D->getType()->getPointeeType();
775     TypeToDiagnose = S.getCtx().getConstantArrayType(
776         ElemQT, APInt(64, static_cast<uint64_t>(D->getNumElems()), false),
777         nullptr, ArraySizeModifier::Normal, 0);
778   } else
779     TypeToDiagnose = D->getType()->getPointeeType();
780 
781   const SourceInfo &E = S.Current->getSource(OpPC);
782   S.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
783       << DeleteIsArray << 0 << TypeToDiagnose;
784   S.Note(NewExpr->getExprLoc(), diag::note_constexpr_dynamic_alloc_here)
785       << NewExpr->getSourceRange();
786   return false;
787 }
788 
789 bool CheckDeleteSource(InterpState &S, CodePtr OpPC, const Expr *Source,
790                        const Pointer &Ptr) {
791   if (Source && isa<CXXNewExpr>(Source))
792     return true;
793 
794   // Whatever this is, we didn't heap allocate it.
795   const SourceInfo &Loc = S.Current->getSource(OpPC);
796   S.FFDiag(Loc, diag::note_constexpr_delete_not_heap_alloc)
797       << Ptr.toDiagnosticString(S.getCtx());
798 
799   if (Ptr.isTemporary())
800     S.Note(Ptr.getDeclLoc(), diag::note_constexpr_temporary_here);
801   else
802     S.Note(Ptr.getDeclLoc(), diag::note_declared_at);
803   return false;
804 }
805 
806 /// We aleady know the given DeclRefExpr is invalid for some reason,
807 /// now figure out why and print appropriate diagnostics.
808 bool CheckDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR) {
809   const ValueDecl *D = DR->getDecl();
810   return diagnoseUnknownDecl(S, OpPC, D);
811 }
812 
813 bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
814                 AccessKinds AK) {
815   if (!Ptr.isDummy())
816     return true;
817 
818   const Descriptor *Desc = Ptr.getDeclDesc();
819   const ValueDecl *D = Desc->asValueDecl();
820   if (!D)
821     return false;
822 
823   if (AK == AK_Read || AK == AK_Increment || AK == AK_Decrement)
824     return diagnoseUnknownDecl(S, OpPC, D);
825 
826   assert(AK == AK_Assign);
827   if (S.getLangOpts().CPlusPlus11) {
828     const SourceInfo &E = S.Current->getSource(OpPC);
829     S.FFDiag(E, diag::note_constexpr_modify_global);
830   }
831   return false;
832 }
833 
834 bool CheckNonNullArgs(InterpState &S, CodePtr OpPC, const Function *F,
835                       const CallExpr *CE, unsigned ArgSize) {
836   auto Args = llvm::ArrayRef(CE->getArgs(), CE->getNumArgs());
837   auto NonNullArgs = collectNonNullArgs(F->getDecl(), Args);
838   unsigned Offset = 0;
839   unsigned Index = 0;
840   for (const Expr *Arg : Args) {
841     if (NonNullArgs[Index] && Arg->getType()->isPointerType()) {
842       const Pointer &ArgPtr = S.Stk.peek<Pointer>(ArgSize - Offset);
843       if (ArgPtr.isZero()) {
844         const SourceLocation &Loc = S.Current->getLocation(OpPC);
845         S.CCEDiag(Loc, diag::note_non_null_attribute_failed);
846         return false;
847       }
848     }
849 
850     Offset += align(primSize(S.Ctx.classify(Arg).value_or(PT_Ptr)));
851     ++Index;
852   }
853   return true;
854 }
855 
856 // FIXME: This is similar to code we already have in Compiler.cpp.
857 // I think it makes sense to instead add the field and base destruction stuff
858 // to the destructor Function itself. Then destroying a record would really
859 // _just_ be calling its destructor. That would also help with the diagnostic
860 // difference when the destructor or a field/base fails.
861 static bool runRecordDestructor(InterpState &S, CodePtr OpPC,
862                                 const Pointer &BasePtr,
863                                 const Descriptor *Desc) {
864   assert(Desc->isRecord());
865   const Record *R = Desc->ElemRecord;
866   assert(R);
867 
868   if (Pointer::pointToSameBlock(BasePtr, S.Current->getThis())) {
869     const SourceInfo &Loc = S.Current->getSource(OpPC);
870     S.FFDiag(Loc, diag::note_constexpr_double_destroy);
871     return false;
872   }
873 
874   // Destructor of this record.
875   if (const CXXDestructorDecl *Dtor = R->getDestructor();
876       Dtor && !Dtor->isTrivial()) {
877     const Function *DtorFunc = S.getContext().getOrCreateFunction(Dtor);
878     if (!DtorFunc)
879       return false;
880 
881     S.Stk.push<Pointer>(BasePtr);
882     if (!Call(S, OpPC, DtorFunc, 0))
883       return false;
884   }
885   return true;
886 }
887 
888 bool RunDestructors(InterpState &S, CodePtr OpPC, const Block *B) {
889   assert(B);
890   const Descriptor *Desc = B->getDescriptor();
891 
892   if (Desc->isPrimitive() || Desc->isPrimitiveArray())
893     return true;
894 
895   assert(Desc->isRecord() || Desc->isCompositeArray());
896 
897   if (Desc->isCompositeArray()) {
898     const Descriptor *ElemDesc = Desc->ElemDesc;
899     assert(ElemDesc->isRecord());
900 
901     Pointer RP(const_cast<Block *>(B));
902     for (unsigned I = 0; I != Desc->getNumElems(); ++I) {
903       if (!runRecordDestructor(S, OpPC, RP.atIndex(I).narrow(), ElemDesc))
904         return false;
905     }
906     return true;
907   }
908 
909   assert(Desc->isRecord());
910   return runRecordDestructor(S, OpPC, Pointer(const_cast<Block *>(B)), Desc);
911 }
912 
913 void diagnoseEnumValue(InterpState &S, CodePtr OpPC, const EnumDecl *ED,
914                        const APSInt &Value) {
915   llvm::APInt Min;
916   llvm::APInt Max;
917 
918   if (S.EvaluatingDecl && !S.EvaluatingDecl->isConstexpr())
919     return;
920 
921   ED->getValueRange(Max, Min);
922   --Max;
923 
924   if (ED->getNumNegativeBits() &&
925       (Max.slt(Value.getSExtValue()) || Min.sgt(Value.getSExtValue()))) {
926     const SourceLocation &Loc = S.Current->getLocation(OpPC);
927     S.CCEDiag(Loc, diag::note_constexpr_unscoped_enum_out_of_range)
928         << llvm::toString(Value, 10) << Min.getSExtValue() << Max.getSExtValue()
929         << ED;
930   } else if (!ED->getNumNegativeBits() && Max.ult(Value.getZExtValue())) {
931     const SourceLocation &Loc = S.Current->getLocation(OpPC);
932     S.CCEDiag(Loc, diag::note_constexpr_unscoped_enum_out_of_range)
933         << llvm::toString(Value, 10) << Min.getZExtValue() << Max.getZExtValue()
934         << ED;
935   }
936 }
937 
938 bool Interpret(InterpState &S, APValue &Result) {
939   // The current stack frame when we started Interpret().
940   // This is being used by the ops to determine wheter
941   // to return from this function and thus terminate
942   // interpretation.
943   const InterpFrame *StartFrame = S.Current;
944   assert(!S.Current->isRoot());
945   CodePtr PC = S.Current->getPC();
946 
947   // Empty program.
948   if (!PC)
949     return true;
950 
951   for (;;) {
952     auto Op = PC.read<Opcode>();
953     CodePtr OpPC = PC;
954 
955     switch (Op) {
956 #define GET_INTERP
957 #include "Opcodes.inc"
958 #undef GET_INTERP
959     }
960   }
961 }
962 
963 } // namespace interp
964 } // namespace clang
965