Author: sepavloff Date: Tue Jul 14 05:02:10 2015 New Revision: 242132 URL: http://llvm.org/viewvc/llvm-project?rev=242132&view=rev Log: Classes inside lambdas are local not nested.
If a lambda used as default argument in a method declaration contained a local class, that class was incorrectly recognized as nested class. In this case compiler tried to postpone parsing of this class until the enclosing class is finished, which caused crashes in some cases. This change fixes PR13987. Differential Revision: http://reviews.llvm.org/D11006 Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp cfe/trunk/test/SemaCXX/lambda-expressions.cpp Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=242132&r1=242131&r2=242132&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original) +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Tue Jul 14 05:02:10 2015 @@ -2815,16 +2815,10 @@ void Parser::ParseCXXMemberSpecification break; } - if ((S->getFlags() & Scope::FnScope)) { - // If we're in a function or function template declared in the - // body of a class, then this is a local class rather than a - // nested class. - const Scope *Parent = S->getParent(); - if (Parent->isTemplateParamScope()) - Parent = Parent->getParent(); - if (Parent->isClassScope()) - break; - } + if ((S->getFlags() & Scope::FnScope)) + // If we're in a function or function template then this is a local + // class rather than a nested class. + break; } } Modified: cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp?rev=242132&r1=242131&r2=242132&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp (original) +++ cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp Tue Jul 14 05:02:10 2015 @@ -948,3 +948,41 @@ auto f(T x) { auto x = f(0)(); } + +namespace PR13987 { +class Enclosing { + void Method(char c = []()->char { + int d = [](auto x)->int { + struct LocalClass { + int Method() { return 0; } + }; + return 0; + }(0); + return d; }() + ); +}; + +class Enclosing2 { + void Method(char c = [](auto x)->char { + int d = []()->int { + struct LocalClass { + int Method() { return 0; } + }; + return 0; + }(); + return d; }(0) + ); +}; + +class Enclosing3 { + void Method(char c = [](auto x)->char { + int d = [](auto y)->int { + struct LocalClass { + int Method() { return 0; } + }; + return 0; + }(0); + return d; }(0) + ); +}; +} Modified: cfe/trunk/test/SemaCXX/lambda-expressions.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/lambda-expressions.cpp?rev=242132&r1=242131&r2=242132&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/lambda-expressions.cpp (original) +++ cfe/trunk/test/SemaCXX/lambda-expressions.cpp Tue Jul 14 05:02:10 2015 @@ -446,3 +446,33 @@ namespace PR21857 { template<typename Fn> fun<Fn> wrap(Fn fn); auto x = wrap([](){}); } + +namespace PR13987 { +class Enclosing { + void Method(char c = []()->char { + int d = []()->int { + struct LocalClass { + int Method() { return 0; } + }; + return 0; + }(); + return d; }() + ); +}; +} + +namespace PR23860 { +template <class> struct A { + void f(int x = []() { + struct B { + void g() {} + }; + return 0; + }()); +}; + +int main() { +} + +A<int> a; +} _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
