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:
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");
}
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