From: Erik Pilkington Date: Tue, 3 Jul 2018 22:15:36 +0000 (+0000) Subject: [Sema] Discarded statment should be an evaluatable context. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7cb94b0502fe0fbf58c5c6f213f1da9386c08034;p=clang [Sema] Discarded statment should be an evaluatable context. The constexpr evaluator was erroring out because these templates weren't defined. Despite being used in a discarded statement, we still need to constexpr evaluate them, which means that we need to instantiate them. Fixes PR37585. Differential revision: https://reviews.llvm.org/D48322 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@336233 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index a713136b64..820e5a9553 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -14237,13 +14237,13 @@ static bool isEvaluatableContext(Sema &SemaRef) { switch (SemaRef.ExprEvalContexts.back().Context) { case Sema::ExpressionEvaluationContext::Unevaluated: case Sema::ExpressionEvaluationContext::UnevaluatedAbstract: - case Sema::ExpressionEvaluationContext::DiscardedStatement: // Expressions in this context are never evaluated. return false; case Sema::ExpressionEvaluationContext::UnevaluatedList: case Sema::ExpressionEvaluationContext::ConstantEvaluated: case Sema::ExpressionEvaluationContext::PotentiallyEvaluated: + case Sema::ExpressionEvaluationContext::DiscardedStatement: // Expressions in this context could be evaluated. return true; diff --git a/test/SemaCXX/constant-expression-cxx1z.cpp b/test/SemaCXX/constant-expression-cxx1z.cpp index a48c9b11b8..2b366adf2e 100644 --- a/test/SemaCXX/constant-expression-cxx1z.cpp +++ b/test/SemaCXX/constant-expression-cxx1z.cpp @@ -46,3 +46,16 @@ namespace Cxx17CD_NB_GB19 { const int &r = 0; constexpr int n = r; } + +namespace PR37585 { +template struct S { static constexpr bool value = true; }; +template constexpr bool f() { return true; } +template constexpr bool v = true; + +void test() { + if constexpr (true) {} + else if constexpr (f()) {} + else if constexpr (S::value) {} + else if constexpr (v) {} +} +}