aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp27
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp5
-rw-r--r--clang/test/SemaCXX/cxx20-ctad-type-alias.cpp18
-rw-r--r--clang/test/SemaTemplate/deduction-guide.cpp28
4 files changed, 61 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index d4976f9..4bda31b 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2962,19 +2962,6 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
Context.getCanonicalTemplateArgument(
Context.getInjectedTemplateArg(NewParam));
}
- // Substitute new template parameters into requires-clause if present.
- Expr *RequiresClause =
- transformRequireClause(SemaRef, F, TemplateArgsForBuildingFPrime);
- // FIXME: implement the is_deducible constraint per C++
- // [over.match.class.deduct]p3.3:
- // ... 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=*/RequiresClause);
// To form a deduction guide f' from f, we leverage clang's instantiation
// mechanism, we construct a template argument list where the template
@@ -3020,6 +3007,20 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
F, TemplateArgListForBuildingFPrime, AliasTemplate->getLocation(),
Sema::CodeSynthesisContext::BuildingDeductionGuides)) {
auto *GG = cast<CXXDeductionGuideDecl>(FPrime);
+ // Substitute new template parameters into requires-clause if present.
+ Expr *RequiresClause =
+ transformRequireClause(SemaRef, F, TemplateArgsForBuildingFPrime);
+ // FIXME: implement the is_deducible constraint per C++
+ // [over.match.class.deduct]p3.3:
+ // ... 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=*/RequiresClause);
+
buildDeductionGuide(SemaRef, AliasTemplate, FPrimeTemplateParamList,
GG->getCorrespondingConstructor(),
GG->getExplicitSpecifier(), GG->getTypeSourceInfo(),
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 3e6676f..98d5c7c 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2502,10 +2502,7 @@ TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,
assert(Arg.getKind() == TemplateArgument::Type &&
"unexpected nontype template argument kind in template rewrite");
QualType NewT = Arg.getAsType();
- assert(isa<TemplateTypeParmType>(NewT) &&
- "type parm not rewritten to type parm");
- auto NewTL = TLB.push<TemplateTypeParmTypeLoc>(NewT);
- NewTL.setNameLoc(TL.getNameLoc());
+ TLB.pushTrivial(SemaRef.Context, NewT, TL.getNameLoc());
return NewT;
}
diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
index 6f04264..508a3a5 100644
--- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
+++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
@@ -289,3 +289,21 @@ using String = Array<char, N>;
// Verify no crash on constructing the aggregate deduction guides.
String s("hello");
} // namespace test21
+
+// GH89013
+namespace test22 {
+class Base {};
+template <typename T>
+class Derived final : public Base {};
+
+template <typename T, typename D>
+requires __is_base_of(Base, D)
+struct Foo {
+ explicit Foo(D) {}
+};
+
+template <typename U>
+using AFoo = Foo<int, Derived<U>>;
+
+AFoo a(Derived<int>{});
+} // namespace test22
diff --git a/clang/test/SemaTemplate/deduction-guide.cpp b/clang/test/SemaTemplate/deduction-guide.cpp
index 58f08aa..29cc5a9 100644
--- a/clang/test/SemaTemplate/deduction-guide.cpp
+++ b/clang/test/SemaTemplate/deduction-guide.cpp
@@ -260,3 +260,31 @@ AG ag = {1};
// CHECK: |-TemplateArgument type 'int'
// CHECK: | `-BuiltinType {{.*}} 'int'
// CHECK: `-ParmVarDecl {{.*}} 'int'
+
+template <typename D>
+requires (sizeof(D) == 4)
+struct Foo {
+ Foo(D);
+};
+
+template <typename U>
+using AFoo = Foo<G<U>>;
+// Verify that the require-clause from the Foo deduction guide is transformed.
+// The D occurrence should be rewritten to G<type-parameter-0-0>.
+//
+// CHECK-LABEL: Dumping <deduction guide for AFoo>
+// CHECK: FunctionTemplateDecl {{.*}} implicit <deduction guide for AFoo>
+// CHECK-NEXT: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 0 U
+// CHECK-NEXT: |-ParenExpr {{.*}} 'bool'
+// CHECK-NEXT: | `-BinaryOperator {{.*}} 'bool' '=='
+// CHECK-NEXT: | |-UnaryExprOrTypeTraitExpr {{.*}} 'unsigned long' sizeof 'G<type-parameter-0-0>'
+// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'unsigned long' <IntegralCast>
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} 'int' 4
+// CHECK-NEXT: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for AFoo> 'auto (G<type-parameter-0-0>) -> Foo<G<type-parameter-0-0>>'
+// CHECK-NEXT: | `-ParmVarDecl {{.*}} 'G<type-parameter-0-0>'
+// CHECK-NEXT: `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for AFoo> 'auto (G<int>) -> Foo<G<int>>' implicit_instantiation
+// CHECK-NEXT: |-TemplateArgument type 'int'
+// CHECK-NEXT: | `-BuiltinType {{.*}} 'int'
+// CHECK-NEXT: `-ParmVarDecl {{.*}} 'G<int>'
+
+AFoo aa(G<int>{});