This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rGaf10d6f350ff: [clang] don't instantiate templates with injected arguments (authored by mizvekov).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D110727/new/ https://reviews.llvm.org/D110727 Files: clang/lib/Sema/SemaTemplateInstantiate.cpp clang/test/SemaTemplate/generic-lambda.cpp Index: clang/test/SemaTemplate/generic-lambda.cpp =================================================================== --- /dev/null +++ clang/test/SemaTemplate/generic-lambda.cpp @@ -0,0 +1,62 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s + +// expected-no-diagnostics + +template <class T, class U> constexpr bool is_same_v = false; +template <class T> constexpr bool is_same_v<T, T> = true; +template <class T, class U> +concept is_same = is_same_v<T, U>; + +template <class T> struct X {}; +template <class T, class U> +concept C1 = is_same<T, X<U>>; + +template <class T1> X<X<X<T1>>> t1() { + return []<class T2>(T2) -> X<X<T2>> { + struct S { + static X<X<T2>> f() { + return []<class T3>(T3) -> X<T3> { + static_assert(is_same<T2, X<T1>>); + static_assert(is_same<T3, X<T2>>); + return X<T3>(); + }(X<T2>()); + } + }; + return S::f(); + }(X<T1>()); +}; +template X<X<X<int>>> t1<int>(); + +#if 0 // FIXME: crashes +template<class T1> auto t2() { + return []<class T2>(T2) { + struct S { + static auto f() { + return []<class T3>(T3) { + static_assert(is_same<T2, X<T1>>); + static_assert(is_same<T3, X<T2>>); + return X<T3>(); + }(X<T2>()); + } + }; + return S::f(); + }(X<T1>()); +}; +template auto t2<int>(); +static_assert(is_same<decltype(t2<int>()), X<X<X<int>>>>); + +template<class T1> C1<X<X<T1>>> auto t3() { + return []<C1<T1> T2>(T2) -> C1<X<T2>> auto { + struct S { + static auto f() { + return []<C1<T2> T3>(T3) -> C1<T3> auto { + return X<T3>(); + }(X<T2>()); + } + }; + return S::f(); + }(X<T1>()); +}; +template C1<X<X<int>>> auto t3<int>(); +static_assert(is_same<decltype(t3<int>()), X<X<X<int>>>>); +#endif Index: clang/lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiate.cpp +++ clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -161,10 +161,9 @@ if (isGenericLambdaCallOperatorOrStaticInvokerSpecialization(Function)) break; - } else if (FunctionTemplateDecl *FunTmpl - = Function->getDescribedFunctionTemplate()) { - // Add the "injected" template arguments. - Result.addOuterTemplateArguments(FunTmpl->getInjectedTemplateArgs()); + } else if (Function->getDescribedFunctionTemplate()) { + assert(Result.getNumSubstitutedLevels() == 0 && + "Outer template not instantiated?"); } // If this is a friend declaration and it declares an entity at @@ -180,11 +179,8 @@ } } else if (CXXRecordDecl *Rec = dyn_cast<CXXRecordDecl>(Ctx)) { if (ClassTemplateDecl *ClassTemplate = Rec->getDescribedClassTemplate()) { - QualType T = ClassTemplate->getInjectedClassNameSpecialization(); - const TemplateSpecializationType *TST = - cast<TemplateSpecializationType>(Context.getCanonicalType(T)); - Result.addOuterTemplateArguments( - llvm::makeArrayRef(TST->getArgs(), TST->getNumArgs())); + assert(Result.getNumSubstitutedLevels() == 0 && + "Outer template not instantiated?"); if (ClassTemplate->isMemberSpecialization()) break; }
Index: clang/test/SemaTemplate/generic-lambda.cpp =================================================================== --- /dev/null +++ clang/test/SemaTemplate/generic-lambda.cpp @@ -0,0 +1,62 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s + +// expected-no-diagnostics + +template <class T, class U> constexpr bool is_same_v = false; +template <class T> constexpr bool is_same_v<T, T> = true; +template <class T, class U> +concept is_same = is_same_v<T, U>; + +template <class T> struct X {}; +template <class T, class U> +concept C1 = is_same<T, X<U>>; + +template <class T1> X<X<X<T1>>> t1() { + return []<class T2>(T2) -> X<X<T2>> { + struct S { + static X<X<T2>> f() { + return []<class T3>(T3) -> X<T3> { + static_assert(is_same<T2, X<T1>>); + static_assert(is_same<T3, X<T2>>); + return X<T3>(); + }(X<T2>()); + } + }; + return S::f(); + }(X<T1>()); +}; +template X<X<X<int>>> t1<int>(); + +#if 0 // FIXME: crashes +template<class T1> auto t2() { + return []<class T2>(T2) { + struct S { + static auto f() { + return []<class T3>(T3) { + static_assert(is_same<T2, X<T1>>); + static_assert(is_same<T3, X<T2>>); + return X<T3>(); + }(X<T2>()); + } + }; + return S::f(); + }(X<T1>()); +}; +template auto t2<int>(); +static_assert(is_same<decltype(t2<int>()), X<X<X<int>>>>); + +template<class T1> C1<X<X<T1>>> auto t3() { + return []<C1<T1> T2>(T2) -> C1<X<T2>> auto { + struct S { + static auto f() { + return []<C1<T2> T3>(T3) -> C1<T3> auto { + return X<T3>(); + }(X<T2>()); + } + }; + return S::f(); + }(X<T1>()); +}; +template C1<X<X<int>>> auto t3<int>(); +static_assert(is_same<decltype(t3<int>()), X<X<X<int>>>>); +#endif Index: clang/lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiate.cpp +++ clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -161,10 +161,9 @@ if (isGenericLambdaCallOperatorOrStaticInvokerSpecialization(Function)) break; - } else if (FunctionTemplateDecl *FunTmpl - = Function->getDescribedFunctionTemplate()) { - // Add the "injected" template arguments. - Result.addOuterTemplateArguments(FunTmpl->getInjectedTemplateArgs()); + } else if (Function->getDescribedFunctionTemplate()) { + assert(Result.getNumSubstitutedLevels() == 0 && + "Outer template not instantiated?"); } // If this is a friend declaration and it declares an entity at @@ -180,11 +179,8 @@ } } else if (CXXRecordDecl *Rec = dyn_cast<CXXRecordDecl>(Ctx)) { if (ClassTemplateDecl *ClassTemplate = Rec->getDescribedClassTemplate()) { - QualType T = ClassTemplate->getInjectedClassNameSpecialization(); - const TemplateSpecializationType *TST = - cast<TemplateSpecializationType>(Context.getCanonicalType(T)); - Result.addOuterTemplateArguments( - llvm::makeArrayRef(TST->getArgs(), TST->getNumArgs())); + assert(Result.getNumSubstitutedLevels() == 0 && + "Outer template not instantiated?"); if (ClassTemplate->isMemberSpecialization()) break; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits