From d1e455aa3150f6ab36378137c8164093697172ce Mon Sep 17 00:00:00 2001 From: Faisal Vali Date: Wed, 18 Nov 2015 04:29:22 +0000 Subject: [PATCH] [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 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! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@253431 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Parse/ParseTemplate.cpp | 3 ++- test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index 3a964dd205..d661ce023a 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/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/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp b/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp index 3f70ca7c81..22ea018842 100644 --- a/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp +++ b/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 struct X0 { X0(); }; template X0::X0() { } @@ -95,3 +98,14 @@ namespace bad_args { int* iptr = &i; X0 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 //expected-error 2{{constant expression}} expected-note{{constant expression}} +int f(); +} +#endif // CPP11ONLY + +} \ No newline at end of file -- 2.40.0