bviyer created this revision. bviyer added reviewers: erik.pilkington, ahatanak, arphaman, dexonsmith. Herald added a subscriber: cfe-commits.
When a variable is defined in the init capture and it is of type struct that is dependent on additional structure, its definition is not found. An exception is created in the findInstantiatedDecl () function. Repository: rC Clang https://reviews.llvm.org/D50122 Files: lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaCXX/lambda-init-capture-vardefine.cpp Index: test/SemaCXX/lambda-init-capture-vardefine.cpp =================================================================== --- /dev/null +++ test/SemaCXX/lambda-init-capture-vardefine.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s +// expected-no-diagnostics + +template <typename...> using a = void; +template <int b> struct c { static const int d = b; }; +template <class, class = a<>> struct e : c<true> {}; +template <class g> g h(int); +template <class g> decltype(h<g>(0)) i; +template <class j> struct e<j, a<decltype(i<j>())>>; +template <typename k> auto func(k &&); +template <int> struct l { + template <typename k> static auto n(k o) { + return [f{o}](auto) { func([](auto...) -> decltype(f) {}); }; + } +}; +template <typename k> auto func(k &&o) { return l<e<decltype(o)>::d>::n(o); } +int main(void) { + auto f = [](auto) {}; + func(f)(1); +} Index: lib/Sema/SemaTemplateInstantiateDecl.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiateDecl.cpp +++ lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4962,6 +4962,14 @@ return cast<TypeDecl>(Inst); } + // If the variable is in InitCapture and variable types are of type + // mentioned in the above comment (the comment starting as "Normally + // this function...") then its existance won't be known so we have to + // make an exclusion for them. + if (const VarDecl *VD = dyn_cast<VarDecl>(D)) + if (VD->isInitCapture()) + return nullptr; + // If we didn't find the decl, then we must have a label decl that hasn't // been found yet. Lazily instantiate it and return it now. assert(isa<LabelDecl>(D)); Index: lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiate.cpp +++ lib/Sema/SemaTemplateInstantiate.cpp @@ -2913,6 +2913,9 @@ // error recovery. if (isa<EnumDecl>(D)) return nullptr; + if (const VarDecl *VD = dyn_cast<VarDecl>(D)) + if (VD->isInitCapture()) + return nullptr; // If we didn't find the decl, then we either have a sema bug, or we have a // forward reference to a label declaration. Return null to indicate that
Index: test/SemaCXX/lambda-init-capture-vardefine.cpp =================================================================== --- /dev/null +++ test/SemaCXX/lambda-init-capture-vardefine.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s +// expected-no-diagnostics + +template <typename...> using a = void; +template <int b> struct c { static const int d = b; }; +template <class, class = a<>> struct e : c<true> {}; +template <class g> g h(int); +template <class g> decltype(h<g>(0)) i; +template <class j> struct e<j, a<decltype(i<j>())>>; +template <typename k> auto func(k &&); +template <int> struct l { + template <typename k> static auto n(k o) { + return [f{o}](auto) { func([](auto...) -> decltype(f) {}); }; + } +}; +template <typename k> auto func(k &&o) { return l<e<decltype(o)>::d>::n(o); } +int main(void) { + auto f = [](auto) {}; + func(f)(1); +} Index: lib/Sema/SemaTemplateInstantiateDecl.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiateDecl.cpp +++ lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4962,6 +4962,14 @@ return cast<TypeDecl>(Inst); } + // If the variable is in InitCapture and variable types are of type + // mentioned in the above comment (the comment starting as "Normally + // this function...") then its existance won't be known so we have to + // make an exclusion for them. + if (const VarDecl *VD = dyn_cast<VarDecl>(D)) + if (VD->isInitCapture()) + return nullptr; + // If we didn't find the decl, then we must have a label decl that hasn't // been found yet. Lazily instantiate it and return it now. assert(isa<LabelDecl>(D)); Index: lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiate.cpp +++ lib/Sema/SemaTemplateInstantiate.cpp @@ -2913,6 +2913,9 @@ // error recovery. if (isa<EnumDecl>(D)) return nullptr; + if (const VarDecl *VD = dyn_cast<VarDecl>(D)) + if (VD->isInitCapture()) + return nullptr; // If we didn't find the decl, then we either have a sema bug, or we have a // forward reference to a label declaration. Return null to indicate that
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits