Skip to content

Commit 57c24eb

Browse files
committed
Reland "[clang] CTAD: Fix require-clause is not transformed." (#89476)
This relands the c8e65e1, which was reverted in b48ea2d due to the breakage of windows builtbot. The reland contains some adjustments in the lit test deduction-gudie.cpp, to make the checking text less strict.
1 parent eef5798 commit 57c24eb

File tree

4 files changed

+61
-17
lines changed

4 files changed

+61
-17
lines changed

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2962,19 +2962,6 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
29622962
Context.getCanonicalTemplateArgument(
29632963
Context.getInjectedTemplateArg(NewParam));
29642964
}
2965-
// Substitute new template parameters into requires-clause if present.
2966-
Expr *RequiresClause =
2967-
transformRequireClause(SemaRef, F, TemplateArgsForBuildingFPrime);
2968-
// FIXME: implement the is_deducible constraint per C++
2969-
// [over.match.class.deduct]p3.3:
2970-
// ... and a constraint that is satisfied if and only if the arguments
2971-
// of A are deducible (see below) from the return type.
2972-
auto *FPrimeTemplateParamList = TemplateParameterList::Create(
2973-
Context, AliasTemplate->getTemplateParameters()->getTemplateLoc(),
2974-
AliasTemplate->getTemplateParameters()->getLAngleLoc(),
2975-
FPrimeTemplateParams,
2976-
AliasTemplate->getTemplateParameters()->getRAngleLoc(),
2977-
/*RequiresClause=*/RequiresClause);
29782965

29792966
// To form a deduction guide f' from f, we leverage clang's instantiation
29802967
// mechanism, we construct a template argument list where the template
@@ -3020,6 +3007,20 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
30203007
F, TemplateArgListForBuildingFPrime, AliasTemplate->getLocation(),
30213008
Sema::CodeSynthesisContext::BuildingDeductionGuides)) {
30223009
auto *GG = cast<CXXDeductionGuideDecl>(FPrime);
3010+
// Substitute new template parameters into requires-clause if present.
3011+
Expr *RequiresClause =
3012+
transformRequireClause(SemaRef, F, TemplateArgsForBuildingFPrime);
3013+
// FIXME: implement the is_deducible constraint per C++
3014+
// [over.match.class.deduct]p3.3:
3015+
// ... and a constraint that is satisfied if and only if the arguments
3016+
// of A are deducible (see below) from the return type.
3017+
auto *FPrimeTemplateParamList = TemplateParameterList::Create(
3018+
Context, AliasTemplate->getTemplateParameters()->getTemplateLoc(),
3019+
AliasTemplate->getTemplateParameters()->getLAngleLoc(),
3020+
FPrimeTemplateParams,
3021+
AliasTemplate->getTemplateParameters()->getRAngleLoc(),
3022+
/*RequiresClause=*/RequiresClause);
3023+
30233024
buildDeductionGuide(SemaRef, AliasTemplate, FPrimeTemplateParamList,
30243025
GG->getCorrespondingConstructor(),
30253026
GG->getExplicitSpecifier(), GG->getTypeSourceInfo(),

clang/lib/Sema/SemaTemplateInstantiate.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2502,10 +2502,7 @@ TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,
25022502
assert(Arg.getKind() == TemplateArgument::Type &&
25032503
"unexpected nontype template argument kind in template rewrite");
25042504
QualType NewT = Arg.getAsType();
2505-
assert(isa<TemplateTypeParmType>(NewT) &&
2506-
"type parm not rewritten to type parm");
2507-
auto NewTL = TLB.push<TemplateTypeParmTypeLoc>(NewT);
2508-
NewTL.setNameLoc(TL.getNameLoc());
2505+
TLB.pushTrivial(SemaRef.Context, NewT, TL.getNameLoc());
25092506
return NewT;
25102507
}
25112508

clang/test/SemaCXX/cxx20-ctad-type-alias.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,3 +289,21 @@ using String = Array<char, N>;
289289
// Verify no crash on constructing the aggregate deduction guides.
290290
String s("hello");
291291
} // namespace test21
292+
293+
// GH89013
294+
namespace test22 {
295+
class Base {};
296+
template <typename T>
297+
class Derived final : public Base {};
298+
299+
template <typename T, typename D>
300+
requires __is_base_of(Base, D)
301+
struct Foo {
302+
explicit Foo(D) {}
303+
};
304+
305+
template <typename U>
306+
using AFoo = Foo<int, Derived<U>>;
307+
308+
AFoo a(Derived<int>{});
309+
} // namespace test22

clang/test/SemaTemplate/deduction-guide.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,3 +260,31 @@ AG ag = {1};
260260
// CHECK: |-TemplateArgument type 'int'
261261
// CHECK: | `-BuiltinType {{.*}} 'int'
262262
// CHECK: `-ParmVarDecl {{.*}} 'int'
263+
264+
template <typename D>
265+
requires (sizeof(D) == 4)
266+
struct Foo {
267+
Foo(D);
268+
};
269+
270+
template <typename U>
271+
using AFoo = Foo<G<U>>;
272+
// Verify that the require-clause from the Foo deduction guide is transformed.
273+
// The D occurrence should be rewritten to G<type-parameter-0-0>.
274+
//
275+
// CHECK-LABEL: Dumping <deduction guide for AFoo>
276+
// CHECK: FunctionTemplateDecl {{.*}} implicit <deduction guide for AFoo>
277+
// CHECK-NEXT: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 0 U
278+
// CHECK-NEXT: |-ParenExpr {{.*}} 'bool'
279+
// CHECK-NEXT: | `-BinaryOperator {{.*}} 'bool' '=='
280+
// CHECK-NEXT: | |-UnaryExprOrTypeTraitExpr {{.*}} 'G<type-parameter-0-0>'
281+
// CHECK-NEXT: | `-ImplicitCastExpr {{.*}}
282+
// CHECK-NEXT: | `-IntegerLiteral {{.*}}
283+
// CHECK-NEXT: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for AFoo> 'auto (G<type-parameter-0-0>) -> Foo<G<type-parameter-0-0>>'
284+
// CHECK-NEXT: | `-ParmVarDecl {{.*}} 'G<type-parameter-0-0>'
285+
// CHECK-NEXT: `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for AFoo> 'auto (G<int>) -> Foo<G<int>>' implicit_instantiation
286+
// CHECK-NEXT: |-TemplateArgument type 'int'
287+
// CHECK-NEXT: | `-BuiltinType {{.*}} 'int'
288+
// CHECK-NEXT: `-ParmVarDecl {{.*}} 'G<int>'
289+
290+
AFoo aa(G<int>{});

0 commit comments

Comments
 (0)