diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 8ebc9bcf025e..0c04f03f06d6 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -14739,6 +14739,7 @@ static bool isPotentiallyConstantEvaluatedContext(Sema &SemaRef) { case Sema::ExpressionEvaluationContext::ConstantEvaluated: // -- a manifestly constant-evaluated expression, case Sema::ExpressionEvaluationContext::PotentiallyEvaluated: + case Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed: case Sema::ExpressionEvaluationContext::DiscardedStatement: // -- a potentially-evaluated expression, case Sema::ExpressionEvaluationContext::UnevaluatedList: @@ -14754,11 +14755,6 @@ static bool isPotentiallyConstantEvaluatedContext(Sema &SemaRef) { case Sema::ExpressionEvaluationContext::UnevaluatedAbstract: // Expressions in this context are never evaluated. return false; - - case Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed: - // FIXME: This is wrong. Default arguemnts are potentially constant - // evaluated even if they are never used. - return false; } llvm_unreachable("Invalid context"); } diff --git a/clang/test/SemaCXX/default1.cpp b/clang/test/SemaCXX/default1.cpp index fcaa2c839d6c..3bc6f832b686 100644 --- a/clang/test/SemaCXX/default1.cpp +++ b/clang/test/SemaCXX/default1.cpp @@ -78,3 +78,21 @@ void PR20769(int = 2); void PR20769_b(int = 1); void PR20769_b() { void PR20769_b(int = 2); } + +#if __cplusplus >= 201103L +template constexpr int f1() { return 0; } +// This is OK, but in order to see that we must instantiate f, despite it +// being in an unused default argument. +void g1(char c = {f1()}) {} // expected-warning {{braces around scalar}} + +// This is formally ill-formed, but we choose to not trigger instantiation here +// (at least, not until g2 is actually called in a way that uses the default +// argument). +template int f2() { return T::error; } +void g2(int c = f2()) {} + +// FIXME: Provide a note pointing at the first use of the default argument? +template int f3() { return T::error; } // expected-error {{no members}} +void g3(int c = f3()) {} // expected-note {{in instantiation of}} +void use_g3() { g3(); } +#endif