aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFaisal Vali <faisalv@yahoo.com>2015-11-18 04:29:22 +0000
committerFaisal Vali <faisalv@yahoo.com>2015-11-18 04:29:22 +0000
commit0374bf0d07f3a39f31b70bf1ee8035a3ec7e9e4e (patch)
treedb64655d5ad942a9093292615541591e6ed6a99d
parent8447ff6357b27725ad04abc042dcedc521630831 (diff)
downloadllvm-0374bf0d07f3a39f31b70bf1ee8035a3ec7e9e4e.zip
llvm-0374bf0d07f3a39f31b70bf1ee8035a3ec7e9e4e.tar.gz
llvm-0374bf0d07f3a39f31b70bf1ee8035a3ec7e9e4e.tar.bz2
[NFC] Change the evaluation context of a non-type default template argument from Unevaluated to ConstantEvaluated.
This patch emits a more appropriate (but still noisy) diagnostic stream when a lambda-expression is encountered within a non-type default argument. For e.g. template<int N = ([] { return 5; }())> int f(); As opposed to complaining that a lambda expression is not allowed in an unevaluated operand, the patch complains about the lambda being forbidden in a constant expression context (which will be allowed in C++17 now that they have been accepted by EWG, unless of course CWG or national bodies (that have so far shown no signs of concern) rise in protest) As I start submitting patches for constexpr lambdas (http://wg21.link/P0170R0) under C++1z (OK'd by Richard Smith at Kona), this will be one less change to make. Thanks! llvm-svn: 253431
-rw-r--r--clang/lib/Parse/ParseTemplate.cpp3
-rw-r--r--clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp14
2 files changed, 16 insertions, 1 deletions
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index 3a964dd..d661ce0 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -695,7 +695,8 @@ Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {
// end of the template-parameter-list rather than a greater-than
// operator.
GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
- EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(Actions,
+ Sema::ConstantEvaluated);
DefaultArg = Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
if (DefaultArg.isInvalid())
diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
index 3f70ca7..22ea018 100644
--- a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
+++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify -triple=x86_64-linux-gnu %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -triple=x86_64-linux-gnu %s -DCPP11ONLY
// C++11 [temp.arg.nontype]p1:
//
@@ -6,6 +7,8 @@
// be one of:
// -- an integral constant expression; or
// -- the name of a non-type template-parameter ; or
+#ifndef CPP11ONLY
+
namespace non_type_tmpl_param {
template <int N> struct X0 { X0(); };
template <int N> X0<N>::X0() { }
@@ -95,3 +98,14 @@ namespace bad_args {
int* iptr = &i;
X0<iptr> x0b; // expected-error{{non-type template argument for template parameter of pointer type 'int *' must have its address taken}}
}
+#endif // CPP11ONLY
+
+namespace default_args {
+#ifdef CPP11ONLY
+namespace lambdas {
+template<int I = ([] { return 5; }())> //expected-error 2{{constant expression}} expected-note{{constant expression}}
+int f();
+}
+#endif // CPP11ONLY
+
+} \ No newline at end of file