bviyer updated this revision to Diff 158870. bviyer added a comment. Simplified the case a bit more as requested by Erik. I also induced some errors in the test so that if someone symbolic-linked clang to /bin/true, the test will fail.
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,23 @@ +// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s + +template <typename k> void func(k&&); + +template <typename k> +void n(k o) { + [f = o](auto) { // expected-note + {{instantiation of function template}} + func([](auto)->int { return sizeof(f); }); // expected-error{{recursive template instantiation exceeded}} expected-note + {{instantiation of function template}} + }(0); +} + +template <typename k> +void func(k &&o) +{ + o(0); + n(o); // expected-note + {{instantiation of function template}} expected-note + {{skipping}} +} + +int main() { + auto f = [](auto) {}; + func(f); // expected-note + {{instantiation of function template}} +} 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,23 @@ +// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s + +template <typename k> void func(k&&); + +template <typename k> +void n(k o) { + [f = o](auto) { // expected-note + {{instantiation of function template}} + func([](auto)->int { return sizeof(f); }); // expected-error{{recursive template instantiation exceeded}} expected-note + {{instantiation of function template}} + }(0); +} + +template <typename k> +void func(k &&o) +{ + o(0); + n(o); // expected-note + {{instantiation of function template}} expected-note + {{skipping}} +} + +int main() { + auto f = [](auto) {}; + func(f); // expected-note + {{instantiation of function template}} +} 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