tbaeder updated this revision to Diff 545028.
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
@@ -300,3 +300,14 @@
}
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);
+ }
+}
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,21 @@
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;
+ }
+
+ 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
@@ -2501,7 +2501,7 @@
return this->emitGetPtrThisField(Offset, E);
}
- return false;
+ return this->emitInvalidDeclRef(E, E);
}
template <class Emitter>
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits