tbaeder created this revision.
tbaeder added reviewers: aaron.ballman, erichkeane, shafik, cor3ntin.
Herald added a project: All.
tbaeder requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Diagnose used non-const and/or extern globals.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D156511
Files:
clang/lib/AST/Interp/Interp.cpp
clang/test/AST/Interp/literals.cpp
Index: clang/test/AST/Interp/literals.cpp
===
--- clang/test/AST/Interp/literals.cpp
+++ clang/test/AST/Interp/literals.cpp
@@ -1056,3 +1056,31 @@
int array[(intptr_t)(char*)0]; // ref-warning {{variable length array folded
to constant array}} \
// expected-warning {{variable length array
folded to constant array}}
}
+
+namespace InvalidDeclRefs {
+ bool b00; // ref-note {{declared here}} \
+// expected-note {{declared here}}
+ static_assert(b00, ""); // ref-error {{not an integral constant expression}}
\
+ // ref-note {{read of non-const variable}} \
+ // expected-error {{not an integral constant
expression}} \
+ // expected-note {{read of non-const variable}}
+
+ float b01; // ref-note {{declared here}} \
+ // expected-note {{declared here}}
+ static_assert(b01, ""); // ref-error {{not an integral constant expression}}
\
+ // ref-note {{read of non-constexpr variable}} \
+ // expected-error {{not an integral constant
expression}} \
+ // expected-note {{read of non-constexpr variable}}
+
+ extern const int b02; // ref-note {{declared here}} \
+// expected-note {{declared here}}
+ static_assert(b02, ""); // ref-error {{not an integral constant expression}}
\
+ // ref-note {{initializer of 'b02' is unknown}} \
+ // expected-error {{not an integral constant
expression}} \
+ // expected-note {{initializer of 'b02' is unknown}}
+
+ /// FIXME: This should also be diagnosed in the new interpreter.
+ int b03 = 3; // ref-note {{declared here}}
+ static_assert(b03, ""); // ref-error {{not an integral constant expression}}
\
+ // ref-note {{read of non-const variable}}
+}
Index: clang/lib/AST/Interp/Interp.cpp
===
--- clang/lib/AST/Interp/Interp.cpp
+++ clang/lib/AST/Interp/Interp.cpp
@@ -553,6 +553,25 @@
return false;
}
+ if (const auto *VD = dyn_cast(D)) {
+if (!VD->getType().isConstant(S.getCtx())) {
+ if (VD->getType()->isIntegralOrEnumerationType())
+S.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
+ else
+S.FFDiag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
+
+ S.Note(VD->getLocation(), diag::note_declared_at) <<
VD->getSourceRange();
+ return false;
+}
+
+// const, but no initializer.
+if (!VD->getAnyInitializer()) {
+ S.FFDiag(E, diag::note_constexpr_var_init_unknown, 1) << VD;
+ S.Note(VD->getLocation(), diag::note_declared_at) <<
VD->getSourceRange();
+ return false;
+}
+ }
+
return false;
}
Index: clang/test/AST/Interp/literals.cpp
===
--- clang/test/AST/Interp/literals.cpp
+++ clang/test/AST/Interp/literals.cpp
@@ -1056,3 +1056,31 @@
int array[(intptr_t)(char*)0]; // ref-warning {{variable length array folded to constant array}} \
// expected-warning {{variable length array folded to constant array}}
}
+
+namespace InvalidDeclRefs {
+ bool b00; // ref-note {{declared here}} \
+// expected-note {{declared here}}
+ static_assert(b00, ""); // ref-error {{not an integral constant expression}} \
+ // ref-note {{read of non-const variable}} \
+ // expected-error {{not an integral constant expression}} \
+ // expected-note {{read of non-const variable}}
+
+ float b01; // ref-note {{declared here}} \
+ // expected-note {{declared here}}
+ static_assert(b01, ""); // ref-error {{not an integral constant expression}} \
+ // ref-note {{read of non-constexpr variable}} \
+ // expected-error {{not an integral constant expression}} \
+ // expected-note {{read of non-constexpr variable}}
+
+ extern const int b02; // ref-note {{declared here}} \
+// expected-note {{declared here}}
+ static_assert(b02, ""); // ref-error {{not an integral constant expression}} \
+ // ref-note {{initializer of 'b02' is unknown}} \
+ // expected-error {{not an