[clang] [clang][bytecode] Diagnose invalid declrefs differently if we've... (PR #113140)

via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 21 02:42:32 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

<details>
<summary>Changes</summary>

... tried their initializer already. In that case, diagnose the non-const initializer instead of the reference to a non-constexpr variable later. This is used in a lot of openmp tests.

---
Full diff: https://github.com/llvm/llvm-project/pull/113140.diff


4 Files Affected:

- (modified) clang/lib/AST/ByteCode/Compiler.cpp (+3-2) 
- (modified) clang/lib/AST/ByteCode/Interp.h (+11-2) 
- (modified) clang/lib/AST/ByteCode/Opcodes.td (+1-1) 
- (added) clang/test/AST/ByteCode/openmp.cpp (+13) 


``````````diff
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 3f068aa8c189a9..b960954d4754a8 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -6097,7 +6097,8 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
 
           if (VD->evaluateValue())
             return revisit(VD);
-          return this->emitInvalidDeclRef(cast<DeclRefExpr>(E), E);
+          return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
+                                          /*InitializerFailed=*/true, E);
         }
       }
     } else {
@@ -6123,7 +6124,7 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
   }
 
   if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
-    return this->emitInvalidDeclRef(DRE, E);
+    return this->emitInvalidDeclRef(DRE, /*InitializerFailed=*/false, E);
   return false;
 }
 
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 1469fac5a17776..c95b18ef72c966 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -2818,9 +2818,18 @@ inline bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind,
   return false;
 }
 
-inline bool InvalidDeclRef(InterpState &S, CodePtr OpPC,
-                           const DeclRefExpr *DR) {
+inline bool InvalidDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR,
+                           bool InitializerFailed) {
   assert(DR);
+
+  if (InitializerFailed) {
+    const SourceInfo &Loc = S.Current->getSource(OpPC);
+    const auto *VD = cast<VarDecl>(DR->getDecl());
+    S.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << VD;
+    S.Note(VD->getLocation(), diag::note_declared_at);
+    return false;
+  }
+
   return CheckDeclRef(S, OpPC, DR);
 }
 
diff --git a/clang/lib/AST/ByteCode/Opcodes.td b/clang/lib/AST/ByteCode/Opcodes.td
index a1970f25ca977f..9136e6b51660d0 100644
--- a/clang/lib/AST/ByteCode/Opcodes.td
+++ b/clang/lib/AST/ByteCode/Opcodes.td
@@ -769,7 +769,7 @@ def InvalidCast : Opcode {
 }
 
 def InvalidDeclRef : Opcode {
-  let Args = [ArgDeclRef];
+  let Args = [ArgDeclRef, ArgBool];
 }
 
 def SizelessVectorElementSize : Opcode;
diff --git a/clang/test/AST/ByteCode/openmp.cpp b/clang/test/AST/ByteCode/openmp.cpp
new file mode 100644
index 00000000000000..e05fbe086625c8
--- /dev/null
+++ b/clang/test/AST/ByteCode/openmp.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both -fopenmp %s
+// RUN: %clang_cc1 -verify=ref,both -fopenmp %s
+
+int test1() {
+  int i;
+  int &j = i; // both-note {{declared here}}
+  float *f;
+  // both-note at +2 {{initializer of 'j' is not a constant expression}}
+  // both-error at +1 {{integral constant expression}}
+  #pragma omp for simd aligned(f:j)
+  for (int i = 0; i < 10; ++i);
+}
+

``````````

</details>


https://github.com/llvm/llvm-project/pull/113140


More information about the cfe-commits mailing list