tbaeder updated this revision to Diff 545193.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156509/new/

https://reviews.llvm.org/D156509

Files:
  clang/lib/AST/Interp/ByteCodeExprGen.cpp
  clang/lib/AST/Interp/Interp.cpp
  clang/lib/AST/Interp/Interp.h
  clang/lib/AST/Interp/Opcodes.td
  clang/test/AST/Interp/functions.cpp

Index: clang/test/AST/Interp/functions.cpp
===================================================================
--- clang/test/AST/Interp/functions.cpp
+++ clang/test/AST/Interp/functions.cpp
@@ -1,5 +1,9 @@
 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify %s
+// RUN: %clang_cc1 -std=c++14 -fexperimental-new-constant-interpreter -verify %s
+// RUN: %clang_cc1 -std=c++20 -fexperimental-new-constant-interpreter -verify %s
 // RUN: %clang_cc1 -verify=ref %s
+// RUN: %clang_cc1 -std=c++14 -verify=ref %s
+// RUN: %clang_cc1 -std=c++20 -verify=ref %s
 
 constexpr void doNothing() {}
 constexpr int gimme5() {
@@ -300,3 +304,24 @@
   }
   static_assert((foo(),1) == 1, "");
 }
+
+namespace InvalidReclRefs {
+  void param(bool b) { // ref-note {{declared here}} \
+                       // expected-note {{declared here}}
+    static_assert(b, ""); // ref-error {{not an integral constant expression}} \
+                          // ref-note {{function parameter 'b' with unknown value}} \
+                          // expected-error {{not an integral constant expression}} \
+                          // expected-note {{function parameter 'b' with unknown value}}
+    static_assert(true ? true : b, "");
+  }
+
+#if __cplusplus >= 202002L
+  consteval void param2(bool b) { // ref-note {{declared here}} \
+                                 // expected-note {{declared here}}
+    static_assert(b, ""); // ref-error {{not an integral constant expression}} \
+                          // ref-note {{function parameter 'b' with unknown value}} \
+                          // expected-error {{not an integral constant expression}} \
+                          // expected-note {{function parameter 'b' with unknown value}}
+  }
+#endif
+}
Index: clang/lib/AST/Interp/Opcodes.td
===================================================================
--- clang/lib/AST/Interp/Opcodes.td
+++ clang/lib/AST/Interp/Opcodes.td
@@ -54,6 +54,7 @@
 def ArgCastKind : ArgType { let Name = "CastKind"; }
 def ArgCallExpr : ArgType { let Name = "const CallExpr *"; }
 def ArgOffsetOfExpr : ArgType { let Name = "const OffsetOfExpr *"; }
+def ArgDeclRef : ArgType { let Name = "const DeclRefExpr *"; }
 
 //===----------------------------------------------------------------------===//
 // Classes of types instructions operate on.
@@ -649,3 +650,7 @@
 def InvalidCast : Opcode {
   let Args = [ArgCastKind];
 }
+
+def InvalidDeclRef : Opcode {
+  let Args = [ArgDeclRef];
+}
Index: clang/lib/AST/Interp/Interp.h
===================================================================
--- clang/lib/AST/Interp/Interp.h
+++ clang/lib/AST/Interp/Interp.h
@@ -174,6 +174,9 @@
 bool CheckFloatResult(InterpState &S, CodePtr OpPC, const Floating &Result,
                       APFloat::opStatus Status);
 
+/// Checks why the given DeclRefExpr is invalid.
+bool CheckDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR);
+
 bool CheckBitcast(InterpState &S, CodePtr OpPC, unsigned IndeterminateBits,
                   bool TargetIsUCharOrByte);
 
@@ -1897,6 +1900,12 @@
   return false;
 }
 
+inline bool InvalidDeclRef(InterpState &S, CodePtr OpPC,
+                           const DeclRefExpr *DR) {
+  assert(DR);
+  return CheckDeclRef(S, OpPC, DR);
+}
+
 template <PrimType Name, class T = typename PrimConv<Name>::T>
 inline bool OffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E) {
   std::vector<int64_t> ArrayIndices;
Index: clang/lib/AST/Interp/Interp.cpp
===================================================================
--- clang/lib/AST/Interp/Interp.cpp
+++ clang/lib/AST/Interp/Interp.cpp
@@ -541,6 +541,20 @@
   return true;
 }
 
+/// We aleady know the given DeclRefExpr is invalid for some reason,
+/// now figure out why and print appropriate diagnostics.
+bool CheckDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR) {
+  const ValueDecl *D = DR->getDecl();
+  const SourceInfo &E = S.Current->getSource(OpPC);
+
+  if (isa<ParmVarDecl>(D)) {
+    S.FFDiag(E, diag::note_constexpr_function_param_value_unknown) << D;
+    S.Note(D->getLocation(), diag::note_declared_at) << D->getSourceRange();
+  }
+
+  return false;
+}
+
 bool CheckBitcast(InterpState &S, CodePtr OpPC, unsigned IndeterminateBits,
                   bool TargetIsUCharOrByte) {
 
Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp
===================================================================
--- clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -2499,7 +2499,7 @@
     return this->emitGetPtrThisField(Offset, E);
   }
 
-  return false;
+  return this->emitInvalidDeclRef(E, E);
 }
 
 template <class Emitter>
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to