diff options
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 11 | ||||
| -rw-r--r-- | clang/test/SemaCXX/cxx1y-generic-lambdas.cpp | 62 |
2 files changed, 71 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index dc8e66dae4c..07d7ceebdb8 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -870,7 +870,16 @@ DeclContext *Sema::getContainingDC(DeclContext *DC) { // Functions defined inline within classes aren't parsed until we've // finished parsing the top-level class, so the top-level class is // the context we'll need to return to. - if (isa<FunctionDecl>(DC)) { + // A Lambda call operator whose parent is a class must not be treated + // as an inline member function. A Lambda can be used legally + // either as an in-class member initializer or a default argument. These + // are parsed once the class has been marked complete and so the containing + // context would be the nested class (when the lambda is defined in one); + // If the class is not complete, then the lambda is being used in an + // ill-formed fashion (such as to specify the width of a bit-field, or + // in an array-bound) - in which case we still want to return the + // lexically containing DC (which could be a nested class). + if (isa<FunctionDecl>(DC) && !isLambdaCallOperator(DC)) { DC = DC->getLexicalParent(); // A function not defined within a class will always return to its diff --git a/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp b/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp index a8518a3a40b..20e06f48a1c 100644 --- a/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp +++ b/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp @@ -844,5 +844,65 @@ void Do() { [=] { v.size(); }; } +} + +namespace inclass_lambdas_within_nested_classes { +namespace ns1 { + +struct X1 { + struct X2 { + enum { E = [](auto i) { return i; }(3) }; //expected-error{{inside of a constant expression}}\ + //expected-error{{not an integral constant}} + int L = ([] (int i) { return i; })(2); + void foo(int i = ([] (int i) { return i; })(2)) { } + int B : ([](int i) { return i; })(3); //expected-error{{inside of a constant expression}}\ + //expected-error{{not an integral constant}} + int arr[([](int i) { return i; })(3)]; //expected-error{{inside of a constant expression}}\ + //expected-error{{must have a constant size}} + int (*fp)(int) = [](int i) { return i; }; + void fooptr(int (*fp)(char) = [](char c) { return 0; }) { } + int L2 = ([](auto i) { return i; })(2); + void fooG(int i = ([] (auto i) { return i; })(2)) { } + int BG : ([](auto i) { return i; })(3); //expected-error{{inside of a constant expression}} \ + //expected-error{{not an integral constant}} + int arrG[([](auto i) { return i; })(3)]; //expected-error{{inside of a constant expression}}\ + //expected-error{{must have a constant size}} + int (*fpG)(int) = [](auto i) { return i; }; + void fooptrG(int (*fp)(char) = [](auto c) { return 0; }) { } + }; +}; +} //end ns + +namespace ns2 { +struct X1 { + template<class T> + struct X2 { + int L = ([] (T i) { return i; })(2); + void foo(int i = ([] (int i) { return i; })(2)) { } + int B : ([](T i) { return i; })(3); //expected-error{{inside of a constant expression}}\ + //expected-error{{not an integral constant}} + int arr[([](T i) { return i; })(3)]; //expected-error{{inside of a constant expression}}\ + //expected-error{{must have a constant size}} + int (*fp)(T) = [](T i) { return i; }; + void fooptr(T (*fp)(char) = [](char c) { return 0; }) { } + int L2 = ([](auto i) { return i; })(2); + void fooG(T i = ([] (auto i) { return i; })(2)) { } + int BG : ([](auto i) { return i; })(3); //expected-error{{not an integral constant}} + int arrG[([](auto i) { return i; })(3)]; //expected-error{{must have a constant size}} + int (*fpG)(T) = [](auto i) { return i; }; + void fooptrG(T (*fp)(char) = [](auto c) { return 0; }) { } + template<class U = char> int fooG2(T (*fp)(U) = [](auto a) { return 0; }) { return 0; } + template<class U = char> int fooG3(T (*fp)(U) = [](auto a) { return 0; }); + }; +}; +template<class T> +template<class U> +int X1::X2<T>::fooG3(T (*fp)(U)) { return 0; } +X1::X2<int> x2; //expected-note 3{{in instantiation of}} +int run1 = x2.fooG2(); +int run2 = x2.fooG3(); +} // end ns + + -}
\ No newline at end of file +} //end ns inclass_lambdas_within_nested_classes
\ No newline at end of file |

