[clang] 2d38bec - [clang][Interp][NFC] Don't create variables in non-constant contexts

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 17 23:30:57 PDT 2024


Author: Timm Bäder
Date: 2024-06-18T08:30:43+02:00
New Revision: 2d38becda8afa48a031995d67ebf9a6383e01e4f

URL: https://github.com/llvm/llvm-project/commit/2d38becda8afa48a031995d67ebf9a6383e01e4f
DIFF: https://github.com/llvm/llvm-project/commit/2d38becda8afa48a031995d67ebf9a6383e01e4f.diff

LOG: [clang][Interp][NFC] Don't create variables in non-constant contexts

When the evaluation in a contant context fails, we would otherwise try
to access and use that variable later in a (maybe) non-constant context.
If the evaluation succeeds in the non-constant context, we never
reported success because we reported failure from the first time
we visited the variable.

Added: 
    

Modified: 
    clang/lib/AST/Interp/ByteCodeEmitter.h
    clang/lib/AST/Interp/ByteCodeExprGen.cpp
    clang/lib/AST/Interp/ByteCodeExprGen.h
    clang/lib/AST/Interp/EvalEmitter.cpp
    clang/lib/AST/Interp/EvalEmitter.h
    clang/lib/AST/Interp/EvaluationResult.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/ByteCodeEmitter.h b/clang/lib/AST/Interp/ByteCodeEmitter.h
index 5612a8c1481a7..d797a0ab4a1c9 100644
--- a/clang/lib/AST/Interp/ByteCodeEmitter.h
+++ b/clang/lib/AST/Interp/ByteCodeEmitter.h
@@ -46,7 +46,7 @@ class ByteCodeEmitter {
   /// Methods implemented by the compiler.
   virtual bool visitFunc(const FunctionDecl *E) = 0;
   virtual bool visitExpr(const Expr *E) = 0;
-  virtual bool visitDecl(const VarDecl *E) = 0;
+  virtual bool visitDecl(const VarDecl *E, bool ConstantContext) = 0;
 
   /// Emits jumps.
   bool jumpTrue(const LabelTy &Label);

diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 6ffa91d81d0e1..e65b2fc7ac233 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -3223,9 +3223,21 @@ bool ByteCodeExprGen<Emitter>::visitExpr(const Expr *E) {
 /// We get here from evaluateAsInitializer().
 /// We need to evaluate the initializer and return its value.
 template <class Emitter>
-bool ByteCodeExprGen<Emitter>::visitDecl(const VarDecl *VD) {
+bool ByteCodeExprGen<Emitter>::visitDecl(const VarDecl *VD,
+                                         bool ConstantContext) {
   assert(!VD->isInvalidDecl() && "Trying to constant evaluate an invalid decl");
 
+  std::optional<PrimType> VarT = classify(VD->getType());
+
+  // We only create variables if we're evaluating in a constant context.
+  // Otherwise, just evaluate the initializer and return it.
+  if (!ConstantContext) {
+    DeclScope<Emitter> LocalScope(this, VD);
+    if (!this->visit(VD->getAnyInitializer()))
+      return false;
+    return this->emitRet(VarT.value_or(PT_Ptr), VD);
+  }
+
   // If we've seen the global variable already and the initializer failed,
   // just return false immediately.
   if (std::optional<unsigned> Index = P.getGlobal(VD)) {
@@ -3241,7 +3253,6 @@ bool ByteCodeExprGen<Emitter>::visitDecl(const VarDecl *VD) {
   if (!this->visitVarDecl(VD))
     return false;
 
-  std::optional<PrimType> VarT = classify(VD->getType());
   // Get a pointer to the variable
   if (Context::shouldBeGloballyIndexed(VD)) {
     auto GlobalIndex = P.getGlobal(VD);

diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h
index b0faac8020fb2..19cbbc432e4b1 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -133,7 +133,7 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
 
 protected:
   bool visitExpr(const Expr *E) override;
-  bool visitDecl(const VarDecl *VD) override;
+  bool visitDecl(const VarDecl *VD, bool ConstantContext) override;
 
 protected:
   /// Emits scope cleanup instructions.

diff  --git a/clang/lib/AST/Interp/EvalEmitter.cpp b/clang/lib/AST/Interp/EvalEmitter.cpp
index 025b46b3d7886..77ff901634a46 100644
--- a/clang/lib/AST/Interp/EvalEmitter.cpp
+++ b/clang/lib/AST/Interp/EvalEmitter.cpp
@@ -66,7 +66,7 @@ EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD,
 
   EvalResult.setSource(VD);
 
-  if (!this->visitDecl(VD) && EvalResult.empty())
+  if (!this->visitDecl(VD, S.inConstantContext()) && EvalResult.empty())
     EvalResult.setInvalid();
 
   return std::move(this->EvalResult);

diff  --git a/clang/lib/AST/Interp/EvalEmitter.h b/clang/lib/AST/Interp/EvalEmitter.h
index 98d6026bbcce4..68accbc5214c2 100644
--- a/clang/lib/AST/Interp/EvalEmitter.h
+++ b/clang/lib/AST/Interp/EvalEmitter.h
@@ -55,7 +55,7 @@ class EvalEmitter : public SourceMapper {
 
   /// Methods implemented by the compiler.
   virtual bool visitExpr(const Expr *E) = 0;
-  virtual bool visitDecl(const VarDecl *VD) = 0;
+  virtual bool visitDecl(const VarDecl *VD, bool ConstantContext) = 0;
 
   /// Emits jumps.
   bool jumpTrue(const LabelTy &Label);

diff  --git a/clang/lib/AST/Interp/EvaluationResult.cpp b/clang/lib/AST/Interp/EvaluationResult.cpp
index 395e3f5b4348d..a62f3f635e6e0 100644
--- a/clang/lib/AST/Interp/EvaluationResult.cpp
+++ b/clang/lib/AST/Interp/EvaluationResult.cpp
@@ -124,9 +124,16 @@ static bool CheckFieldsInitialized(InterpState &S, SourceLocation Loc,
   for (const Record::Base &B : R->bases()) {
     Pointer P = BasePtr.atField(B.Offset);
     if (!P.isInitialized()) {
-      S.FFDiag(BasePtr.getDeclDesc()->asDecl()->getLocation(),
-               diag::note_constexpr_uninitialized_base)
-          << B.Desc->getType();
+      const Descriptor *Desc = BasePtr.getDeclDesc();
+      if (Desc->asDecl())
+        S.FFDiag(BasePtr.getDeclDesc()->asDecl()->getLocation(),
+                 diag::note_constexpr_uninitialized_base)
+            << B.Desc->getType();
+      else
+        S.FFDiag(BasePtr.getDeclDesc()->asExpr()->getExprLoc(),
+                 diag::note_constexpr_uninitialized_base)
+            << B.Desc->getType();
+
       return false;
     }
     Result &= CheckFieldsInitialized(S, Loc, P, B.R);


        


More information about the cfe-commits mailing list