[clang] 0fd3d37 - Improve diagnostic for an expression that's not constant because it uses
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 10 17:03:30 PDT 2020
Author: Richard Smith
Date: 2020-08-10T17:03:19-07:00
New Revision: 0fd3d379e26da3cb02b6d960198e2efbc5190650
URL: https://github.com/llvm/llvm-project/commit/0fd3d379e26da3cb02b6d960198e2efbc5190650
DIFF: https://github.com/llvm/llvm-project/commit/0fd3d379e26da3cb02b6d960198e2efbc5190650.diff
LOG: Improve diagnostic for an expression that's not constant because it uses
the address of a constexpr local variable.
Suggest adding 'static' to give the constexpr local variable a constant
address.
Added:
Modified:
clang/include/clang/Basic/DiagnosticASTKinds.td
clang/lib/AST/ExprConstant.cpp
clang/test/SemaCXX/builtins.cpp
clang/test/SemaCXX/constant-expression-cxx11.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td
index 10bedaaf7aba..9be75f375119 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -54,6 +54,9 @@ def note_constexpr_nonliteral : Note<
def note_constexpr_non_global : Note<
"%select{pointer|reference}0 to %select{|subobject of }1"
"%select{temporary|%3}2 is not a constant expression">;
+def note_constexpr_not_static : Note<
+ "address of non-static constexpr variable %0 may
diff er on each invocation "
+ "of the enclosing function; add 'static' to give it a constant address">;
def note_constexpr_dynamic_alloc : Note<
"%select{pointer|reference}0 to %select{|subobject of }1"
"heap-allocated object is not a constant expression">;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 11ba8db24355..4238adb5a947 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2055,7 +2055,20 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
<< IsReferenceType << !Designator.Entries.empty()
<< !!VD << VD;
- NoteLValueLocation(Info, Base);
+
+ auto *VarD = dyn_cast_or_null<VarDecl>(VD);
+ if (VarD && VarD->isConstexpr()) {
+ // Non-static local constexpr variables have unintuitive semantics:
+ // constexpr int a = 1;
+ // constexpr const int *p = &a;
+ // ... is invalid because the address of 'a' is not constant. Suggest
+ // adding a 'static' in this case.
+ Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
+ << VarD
+ << FixItHint::CreateInsertion(VarD->getBeginLoc(), "static ");
+ } else {
+ NoteLValueLocation(Info, Base);
+ }
} else {
Info.FFDiag(Loc);
}
diff --git a/clang/test/SemaCXX/builtins.cpp b/clang/test/SemaCXX/builtins.cpp
index 80f75c8232c2..8869b6bef04c 100644
--- a/clang/test/SemaCXX/builtins.cpp
+++ b/clang/test/SemaCXX/builtins.cpp
@@ -113,7 +113,7 @@ static_assert(&const_int == const_ptr, "");
static_assert(const_ptr != test_constexpr_launder(&const_int2), "");
void test_non_constexpr() {
- constexpr int i = 42; // expected-note {{declared here}}
+ constexpr int i = 42; // expected-note {{address of non-static constexpr variable 'i' may
diff er on each invocation}}
constexpr const int *ip = __builtin_launder(&i); // expected-error {{constexpr variable 'ip' must be initialized by a constant expression}}
// expected-note at -1 {{pointer to 'i' is not a constant expression}}
}
diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index 14d36543cb20..c3529fc68266 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -2343,3 +2343,8 @@ namespace flexible_array {
// constant-evaluate it properly.
constexpr A c = {1, 2, 3}; // expected-error {{initialization of flexible array member}}
}
+
+void local_constexpr_var() {
+ constexpr int a = 0; // expected-note {{address of non-static constexpr variable 'a' may
diff er on each invocation of the enclosing function; add 'static' to give it a constant address}}
+ constexpr const int *p = &a; // expected-error {{constant expression}} expected-note {{pointer to 'a' is not a constant expression}}
+}
More information about the cfe-commits
mailing list