[clang] [clang] CTAD: Respect requires-clause of the original function template (PR #84913)
Haojian Wu via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 12 06:44:39 PDT 2024
https://github.com/hokein created https://github.com/llvm/llvm-project/pull/84913
for the synthesized deduction guide.
We ignored the require-clause of the original template when building the deduction guide for type-alias CTAD, this resulted in accepting code which should be rejected (see the test case), this patch fixes it, part of #84492.
>From 5e411ee4a0337ac719ba4cc605e6aea74499f011 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Tue, 12 Mar 2024 14:32:42 +0100
Subject: [PATCH] [clang] CTAD: Respect requires-clause of the original
function template for the synthesized deduction guide.
We ignored the require-clause of the original template when building the
deduction guide for type-alis CTAD, this resulted in accepting code
which should be reject (see the testcase), this patch fixes it, part of
---
clang/lib/Sema/SemaTemplate.cpp | 19 ++++++++++++++-----
clang/test/SemaCXX/cxx20-ctad-type-alias.cpp | 17 +++++++++++++++++
2 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index d62095558d0ffb..95b7c92ca70d51 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2906,18 +2906,27 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
Context.getCanonicalTemplateArgument(
Context.getInjectedTemplateArg(NewParam));
}
- // FIXME: implement the associated constraint per C++
+ // Substitute new template parameters into requires-clause if present.
+ Expr *RequiresClause = nullptr;
+ if (Expr *InnerRC = F->getTemplateParameters()->getRequiresClause()) {
+ MultiLevelTemplateArgumentList Args;
+ Args.setKind(TemplateSubstitutionKind::Rewrite);
+ Args.addOuterTemplateArguments(TemplateArgsForBuildingFPrime);
+ ExprResult E = SemaRef.SubstExpr(InnerRC, Args);
+ if (E.isInvalid())
+ return;
+ RequiresClause = E.getAs<Expr>();
+ }
+ // FIXME: implement the is_deducible constraint per C++
// [over.match.class.deduct]p3.3:
- // The associated constraints ([temp.constr.decl]) are the
- // conjunction of the associated constraints of g and a
- // constraint that is satisfied if and only if the arguments
+ // ... and a constraint that is satisfied if and only if the arguments
// of A are deducible (see below) from the return type.
auto *FPrimeTemplateParamList = TemplateParameterList::Create(
Context, AliasTemplate->getTemplateParameters()->getTemplateLoc(),
AliasTemplate->getTemplateParameters()->getLAngleLoc(),
FPrimeTemplateParams,
AliasTemplate->getTemplateParameters()->getRAngleLoc(),
- /*RequiresClause=*/nullptr);
+ /*RequiresClause=*/RequiresClause);
// To form a deduction guide f' from f, we leverage clang's instantiation
// mechanism, we construct a template argument list where the template
diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
index 794496ed418489..3ce26c8fcd984e 100644
--- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
+++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
@@ -230,3 +230,20 @@ using AFoo = Foo<U>*; // expected-note {{template is declared here}}
AFoo s = {1}; // expected-error {{alias template 'AFoo' requires template arguments; argument deduction only allowed for}}
} // namespace test17
+
+namespace test18 {
+template<typename T>
+concept False = false; // expected-note {{because 'false' evaluated to false}}
+
+template <typename T> struct Foo { T t; };
+
+template<typename T> requires False<T> // expected-note {{because 'int' does not satisfy 'False'}}
+Foo(T) -> Foo<int>;
+
+template <typename U>
+using Bar = Foo<U>; // expected-note {{could not match 'Foo<type-parameter-0-0>' against 'int'}} \
+ // expected-note {{candidate template ignored: constraints not satisfied}} \
+ // expected-note {{candidate function template not viable}}
+
+Bar s = {1}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments}}
+} // namespace test18
More information about the cfe-commits
mailing list