[Sema] Discarded statment should be an evaluatable context.
authorErik Pilkington <erik.pilkington@gmail.com>
Tue, 3 Jul 2018 22:15:36 +0000 (22:15 +0000)
committerErik Pilkington <erik.pilkington@gmail.com>
Tue, 3 Jul 2018 22:15:36 +0000 (22:15 +0000)
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

llvm-svn: 336233

clang/lib/Sema/SemaExpr.cpp
clang/test/SemaCXX/constant-expression-cxx1z.cpp

index a713136..820e5a9 100644 (file)
@@ -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;
 
index a48c9b1..2b366ad 100644 (file)
@@ -46,3 +46,16 @@ namespace Cxx17CD_NB_GB19 {
   const int &r = 0;
   constexpr int n = r;
 }
+
+namespace PR37585 {
+template <class T> struct S { static constexpr bool value = true; };
+template <class T> constexpr bool f() { return true; }
+template <class T> constexpr bool v = true;
+
+void test() {
+  if constexpr (true) {}
+  else if constexpr (f<int>()) {}
+  else if constexpr (S<int>::value) {}
+  else if constexpr (v<int>) {}
+}
+}