Skip to content

Commit ece4440

Browse files
efriedma-quictru
authored andcommitted
[clang] Fix potential constant expression checking with constexpr-unknown.
0717657 improved constexpr-unknown diagnostics, but potential constant expression checking broke in the process: we produce diagnostics in more cases. Suppress the diagnostics as appropriate. This fix affects -Winvalid-constexpr and the enable_if attribute. (The -Winvalid-constexpr diagnostic isn't really important right now, but it will become important if we allow constexpr-unknown with pre-C++23 standards.) Fixes #149041. Fixes #149188. (cherry picked from commit 6a60f18)
1 parent 52dfd4a commit ece4440

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

clang/lib/AST/ExprConstant.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4441,7 +4441,8 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
44414441
}
44424442
} else if (!IsAccess) {
44434443
return CompleteObject(LVal.getLValueBase(), nullptr, BaseType);
4444-
} else if (IsConstant && Info.checkingPotentialConstantExpression() &&
4444+
} else if ((IsConstant || BaseType->isReferenceType()) &&
4445+
Info.checkingPotentialConstantExpression() &&
44454446
BaseType->isLiteralType(Info.Ctx) && !VD->hasDefinition()) {
44464447
// This variable might end up being constexpr. Don't diagnose it yet.
44474448
} else if (IsConstant) {
@@ -4478,9 +4479,11 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
44784479
// a null BaseVal. Any constexpr-unknown variable seen here is an error:
44794480
// we can't access a constexpr-unknown object.
44804481
if (!BaseVal) {
4481-
Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
4482-
<< AK << VD;
4483-
Info.Note(VD->getLocation(), diag::note_declared_at);
4482+
if (!Info.checkingPotentialConstantExpression()) {
4483+
Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
4484+
<< AK << VD;
4485+
Info.Note(VD->getLocation(), diag::note_declared_at);
4486+
}
44844487
return CompleteObject();
44854488
}
44864489
} else if (DynamicAllocLValue DA = LVal.Base.dyn_cast<DynamicAllocLValue>()) {

clang/test/SemaCXX/constant-expression-p2280r4.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,3 +357,29 @@ namespace pointer_comparisons {
357357
static_assert(!f4()); // expected-error {{static assertion expression is not an integral constant expression}} \
358358
// expected-note {{in call to 'f4()'}}
359359
}
360+
361+
namespace GH149188 {
362+
namespace enable_if_1 {
363+
template <__SIZE_TYPE__ N>
364+
constexpr void foo(const char (&Str)[N])
365+
__attribute((enable_if(__builtin_strlen(Str), ""))) {}
366+
367+
void x() {
368+
foo("1234");
369+
}
370+
}
371+
372+
namespace enable_if_2 {
373+
constexpr const char (&f())[];
374+
extern const char (&Str)[];
375+
constexpr int foo()
376+
__attribute((enable_if(__builtin_strlen(Str), "")))
377+
{return __builtin_strlen(Str);}
378+
379+
constexpr const char (&f())[] {return "a";}
380+
constexpr const char (&Str)[] = f();
381+
void x() {
382+
constexpr int x = foo();
383+
}
384+
}
385+
}

clang/test/SemaCXX/constexpr-never-constant.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,10 @@ constexpr void other_func() {
2424

2525
throw 12;
2626
}
27+
28+
namespace GH149041 {
29+
// Make sure these don't trigger the diagnostic.
30+
extern const bool& b;
31+
constexpr bool fun1() { return b; }
32+
constexpr bool fun2(const bool& b) { return b; }
33+
}

0 commit comments

Comments
 (0)