https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/76811
>From 1164c705a8515d39bc9d4404e8523da8876d81cf Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Wed, 3 Jan 2024 19:33:01 +0800 Subject: [PATCH 1/3] [Clang] Correctly construct template arguments for file-scope template template parameters This fixes the bug introduced by https://github.com/llvm/llvm-project/commit/6db007a0654ed7a6ed5c3aa3b61a937c19a6bc6b. We construct placeholder template arguments for template-template parameters to avoid mismatching argument substitution since they have different depths with their corresponding template arguments. In this case, ```cpp template <template <Concept C> class T> void foo(T<int>); ``` T lies at the depth 0, and C lies at 1. The corresponding argument, of which there is exactly one, int, is at depth 0. If we consider the argument as the outermost one, then we would end up substituting 'int' into the wrong parameter T. We used to perform such placeholder construction during the context walk-up. In the previous patch, we slipped through that inadvertently because we would walk up to the parent, which is precisely a FileContext for template-template parameters, after adding innermost arguments. Besides, this patch moves the sanity check up to the context switch. That way, we avoid dereferencing null pointers if ND is unspecified. Closes https://github.com/llvm/llvm-project/issues/57410. --- clang/docs/ReleaseNotes.rst | 3 +++ clang/lib/Sema/SemaTemplateInstantiate.cpp | 12 ++++++--- .../temp/temp.arg/temp.arg.template/p3-2a.cpp | 25 +++++++++++++++++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 0c8fec691bf3c9..7193d711333780 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -843,6 +843,9 @@ Bug Fixes to C++ Support - Fix crash when parsing nested requirement. Fixes: (`#73112 <https://github.com/llvm/llvm-project/issues/73112>`_) +- Fix a regression where clang forgets how to substitute into constraints on template-template + parameters. Fixes: (`#57410 <https://github.com/llvm/llvm-project/issues/57410>`_) + Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ - Fixed an import failure of recursive friend class template. diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index df6b40999e645c..4420280efebb86 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -345,15 +345,19 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs( using namespace TemplateInstArgsHelpers; const Decl *CurDecl = ND; + + if (!ND) + CurDecl = Decl::castFromDeclContext(DC); + if (Innermost) { Result.addOuterTemplateArguments(const_cast<NamedDecl *>(ND), Innermost->asArray(), Final); - CurDecl = Response::UseNextDecl(ND).NextDecl; + if (CurDecl->getDeclContext()->isFileContext()) + if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(CurDecl)) + HandleDefaultTempArgIntoTempTempParam(TTP, Result); + CurDecl = Response::UseNextDecl(CurDecl).NextDecl; } - if (!ND) - CurDecl = Decl::castFromDeclContext(DC); - while (!CurDecl->isFileContextDecl()) { Response R; if (const auto *VarTemplSpec = diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp index 449b6232542e24..277935f6b3b2f0 100644 --- a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp +++ b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp @@ -59,3 +59,28 @@ struct Nothing {}; // FIXME: Wait the standard to clarify the intent. template<> template<> Z<Nothing> S5<Z>::V<Nothing>; + +namespace GH57410 { + +template<typename T> +concept True = true; + +template<typename T> +concept False = false; // #False + +template<template<True T> typename Wrapper> +using Test = Wrapper<int>; + +template<template<False T> typename Wrapper> // #TTP-Wrapper +using Test = Wrapper<int>; // expected-error {{constraints not satisfied for template template parameter 'Wrapper' [with T = int]}} + +// expected-note@#TTP-Wrapper {{'int' does not satisfy 'False'}} +// expected-note@#False {{evaluated to false}} + +template <template<False> typename T> // #TTP-foo +void foo(T<int>); // expected-error {{constraints not satisfied for template template parameter 'T' [with $0 = int]}} + +// expected-note@#TTP-foo {{'int' does not satisfy 'False'}} +// expected-note@#False {{evaluated to false}} + +} >From 8d5a7cdb39b0e64d350b8e4540738ef6eae7dc5c Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Fri, 5 Jan 2024 16:37:05 +0800 Subject: [PATCH 2/3] Address comments and poke the CI --- clang/lib/Sema/SemaTemplateInstantiate.cpp | 22 ++++++++++++------- .../temp/temp.arg/temp.arg.template/p3-2a.cpp | 12 ++++++---- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 4420280efebb86..35b329e14ed9fc 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -346,15 +346,23 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs( using namespace TemplateInstArgsHelpers; const Decl *CurDecl = ND; - if (!ND) + if (!CurDecl) CurDecl = Decl::castFromDeclContext(DC); if (Innermost) { Result.addOuterTemplateArguments(const_cast<NamedDecl *>(ND), Innermost->asArray(), Final); - if (CurDecl->getDeclContext()->isFileContext()) - if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(CurDecl)) - HandleDefaultTempArgIntoTempTempParam(TTP, Result); + // Populate placeholder template arguments for TemplateTemplateParmDecls + // that live in a file-scope DeclContext. This is essential for the case + // e.g. + // + // template <class> concept Concept = false; + // template <template <Concept C> class T> void foo(T<int>) + // + // where parameter C has a depth of 1 but the substituting argument `int` + // has a depth of 0. + if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(CurDecl)) + HandleDefaultTempArgIntoTempTempParam(TTP, Result); CurDecl = Response::UseNextDecl(CurDecl).NextDecl; } @@ -385,10 +393,8 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs( R = Response::ChangeDecl(CTD->getLexicalDeclContext()); } else if (!isa<DeclContext>(CurDecl)) { R = Response::DontClearRelativeToPrimaryNextDecl(CurDecl); - if (CurDecl->getDeclContext()->isTranslationUnit()) { - if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(CurDecl)) { - R = HandleDefaultTempArgIntoTempTempParam(TTP, Result); - } + if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(CurDecl)) { + R = HandleDefaultTempArgIntoTempTempParam(TTP, Result); } } else { R = HandleGenericDeclContext(CurDecl); diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp index 277935f6b3b2f0..f586069638614b 100644 --- a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp +++ b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp @@ -68,6 +68,8 @@ concept True = true; template<typename T> concept False = false; // #False +template <class> struct S {}; + template<template<True T> typename Wrapper> using Test = Wrapper<int>; @@ -77,10 +79,12 @@ using Test = Wrapper<int>; // expected-error {{constraints not satisfied for tem // expected-note@#TTP-Wrapper {{'int' does not satisfy 'False'}} // expected-note@#False {{evaluated to false}} -template <template<False> typename T> // #TTP-foo -void foo(T<int>); // expected-error {{constraints not satisfied for template template parameter 'T' [with $0 = int]}} +template <typename U, template<False> typename T> +void foo(T<U>); // #foo -// expected-note@#TTP-foo {{'int' does not satisfy 'False'}} -// expected-note@#False {{evaluated to false}} +void bar() { + foo<int>(S<int>{}); // expected-error {{no matching function for call to 'foo'}} + // expected-note@#foo {{substitution failure [with U = int]: constraints not satisfied for template template parameter 'T' [with $0 = int]}} +} } >From 617d42708639c5819a58800d4907d6d3c15ec4ec Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Fri, 5 Jan 2024 16:49:06 +0800 Subject: [PATCH 3/3] Add the other issue to the release note --- clang/docs/ReleaseNotes.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 7193d711333780..fff887285dd080 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -844,7 +844,9 @@ Bug Fixes to C++ Support (`#73112 <https://github.com/llvm/llvm-project/issues/73112>`_) - Fix a regression where clang forgets how to substitute into constraints on template-template - parameters. Fixes: (`#57410 <https://github.com/llvm/llvm-project/issues/57410>`_) + parameters. Fixes: + (`#57410 <https://github.com/llvm/llvm-project/issues/57410>`_) and + (`#76604 <https://github.com/llvm/llvm-project/issues/76604>`_). Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits