[PATCH] D19175: Fix for PR27015 (variable template initialized with a generic lambda expression)
Akira Hatanaka via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 28 11:59:29 PDT 2016
ahatanak updated this revision to Diff 55453.
ahatanak added a comment.
Use ParseScopeFlags to clear the TemplateParamScope rather than calling setFlags directly.
I tried calling Init(AnyParent, F) is Scope::setFlags, but it caused a lot of test cases to fail, which I'm currently investigating.
http://reviews.llvm.org/D19175
Files:
lib/Parse/ParseTemplate.cpp
lib/Sema/SemaLambda.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
test/SemaCXX/vartemplate-lambda.cpp
Index: test/SemaCXX/vartemplate-lambda.cpp
===================================================================
--- /dev/null
+++ test/SemaCXX/vartemplate-lambda.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+template <class> auto fn0 = [] {};
+template <typename> void foo0() { fn0<char>(); }
+
+template<typename T> auto fn1 = [](auto a) { return a + T(1); };
+
+template <typename X>
+int foo2() {
+ X a = 0x61;
+ fn1<char>(a);
+ return 0;
+}
+
+int main() {
+ foo2<int>();
+}
Index: test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
===================================================================
--- test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
+++ test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
@@ -195,7 +195,7 @@
namespace default_args {
#ifdef CPP11ONLY
namespace lambdas {
-template<int I = ([] { return 5; }())> //expected-error 2{{constant expression}} expected-note{{constant expression}}
+template<int I = ([] { return 5; }())> //expected-error {{constant expression}}
int f();
}
#endif // CPP11ONLY
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -3907,9 +3907,14 @@
PushExpressionEvaluationContext(Sema::PotentiallyEvaluated, OldVar);
// Instantiate the initializer.
- ExprResult Init =
- SubstInitializer(OldVar->getInit(), TemplateArgs,
- OldVar->getInitStyle() == VarDecl::CallInit);
+ ExprResult Init;
+
+ {
+ ContextRAII SwitchContext(*this, Var->getDeclContext());
+ Init = SubstInitializer(OldVar->getInit(), TemplateArgs,
+ OldVar->getInitStyle() == VarDecl::CallInit);
+ }
+
if (!Init.isInvalid()) {
bool TypeMayContainAuto = true;
Expr *InitExpr = Init.get();
Index: lib/Sema/SemaLambda.cpp
===================================================================
--- lib/Sema/SemaLambda.cpp
+++ lib/Sema/SemaLambda.cpp
@@ -814,8 +814,8 @@
// The lambda-expression's closure type might be dependent even if its
// semantic context isn't, if it appears within a default argument of a
// function template.
- if (Scope *TmplScope = CurScope->getTemplateParamParent())
- if (!TmplScope->decl_empty())
+ if (auto *TmplScope = CurScope->getTemplateParamParent())
+ if (TmplScope->isTemplateParamScope())
KnownDependent = true;
// Determine the signature of the call operator.
Index: lib/Parse/ParseTemplate.cpp
===================================================================
--- lib/Parse/ParseTemplate.cpp
+++ lib/Parse/ParseTemplate.cpp
@@ -147,6 +147,9 @@
}
} while (Tok.isOneOf(tok::kw_export, tok::kw_template));
+ unsigned NewFlags = getCurScope()->getFlags() & ~Scope::TemplateParamScope;
+ ParseScopeFlags TemplateScopeFlags(this, NewFlags, isSpecialization);
+
// Parse the actual template declaration.
return ParseSingleDeclarationAfterTemplate(Context,
ParsedTemplateInfo(&ParamLists,
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D19175.55453.patch
Type: text/x-patch
Size: 3158 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160428/a720e95e/attachment-0001.bin>
More information about the cfe-commits
mailing list