r361670 - Default arguments are potentially constant evaluated.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Fri May 24 14:08:13 PDT 2019


Author: rsmith
Date: Fri May 24 14:08:12 2019
New Revision: 361670

URL: http://llvm.org/viewvc/llvm-project?rev=361670&view=rev
Log:
Default arguments are potentially constant evaluated.

We need to eagerly instantiate constexpr functions used in them even if
the default argument is never actually used, because we might evaluate
portions of it when performing semantic checks.

Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/SemaCXX/default1.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=361670&r1=361669&r2=361670&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri May 24 14:08:12 2019
@@ -14739,6 +14739,7 @@ static bool isPotentiallyConstantEvaluat
     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 isPotentiallyConstantEvaluat
     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");
 }

Modified: cfe/trunk/test/SemaCXX/default1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/default1.cpp?rev=361670&r1=361669&r2=361670&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/default1.cpp (original)
+++ cfe/trunk/test/SemaCXX/default1.cpp Fri May 24 14:08:12 2019
@@ -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<typename T> constexpr int f1() { return 0; }
+// This is OK, but in order to see that we must instantiate f<int>, despite it
+// being in an unused default argument.
+void g1(char c = {f1<int>()}) {} // 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<typename T> int f2() { return T::error; }
+void g2(int c = f2<int>()) {}
+
+// FIXME: Provide a note pointing at the first use of the default argument?
+template<typename T> int f3() { return T::error; } // expected-error {{no members}}
+void g3(int c = f3<int>()) {} // expected-note {{in instantiation of}}
+void use_g3() { g3(); }
+#endif




More information about the cfe-commits mailing list