Skip to content

Commit caf055b

Browse files
committed
Address review comments, and add more tests.
1 parent 05740ec commit caf055b

File tree

3 files changed

+57
-13
lines changed

3 files changed

+57
-13
lines changed

clang/lib/Sema/SemaInit.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10621,6 +10621,8 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
1062110621
if (const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(
1062210622
RT->getAsCXXRecordDecl()))
1062310623
Template = CTSD->getSpecializedTemplate();
10624+
} else {
10625+
assert(false && "unexpected underlying type of alias template");
1062410626
}
1062510627
}
1062610628
}

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
#include "clang/AST/ASTConsumer.h"
1313
#include "clang/AST/ASTContext.h"
1414
#include "clang/AST/Decl.h"
15-
#include "clang/AST/DeclBase.h"
1615
#include "clang/AST/DeclFriend.h"
1716
#include "clang/AST/DeclTemplate.h"
1817
#include "clang/AST/Expr.h"
@@ -40,7 +39,6 @@
4039
#include "llvm/ADT/SmallBitVector.h"
4140
#include "llvm/ADT/SmallString.h"
4241
#include "llvm/ADT/StringExtras.h"
43-
#include "llvm/Support/Casting.h"
4442

4543
#include <iterator>
4644
#include <optional>
@@ -2716,9 +2714,12 @@ FindAppearedTemplateParamsInAlias(ArrayRef<TemplateArgument> DeducedArgs,
27162714
return Results;
27172715
}
27182716

2719-
bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext* DC) {
2717+
bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext *DC) {
27202718
// Check whether we've already declared deduction guides for this template.
27212719
// FIXME: Consider storing a flag on the template to indicate this.
2720+
assert(Name.getNameKind() ==
2721+
DeclarationName::NameKind::CXXDeductionGuideName &&
2722+
"name must be a deduction guide name");
27222723
auto Existing = DC->lookup(Name);
27232724
for (auto *D : Existing)
27242725
if (D->isImplicit())
@@ -2737,14 +2738,14 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
27372738
Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate),
27382739
AliasTemplate->getDeclContext()))
27392740
return;
2740-
// Unrap the sugar ElaboratedType.
2741+
// Unwrap the sugared ElaboratedType.
27412742
auto RhsType = AliasTemplate->getTemplatedDecl()
27422743
->getUnderlyingType()
27432744
.getSingleStepDesugaredType(Context);
27442745
TemplateDecl *Template = nullptr;
27452746
llvm::ArrayRef<TemplateArgument> AliasRhsTemplateArgs;
27462747
if (const auto *TST = RhsType->getAs<TemplateSpecializationType>()) {
2747-
// TemplateName in TEST can be a TypeAliasTemplateDecl if
2748+
// TemplateName in TST can be a TypeAliasTemplateDecl if
27482749
// the right hand side of the alias is also a type alias, e.g.
27492750
//
27502751
// template<typename T>
@@ -2787,7 +2788,7 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
27872788
else if (const auto *ET = RType->getAs<ElaboratedType>())
27882789
// explicit deduction guide.
27892790
FReturnType = ET->getNamedType()->getAs<TemplateSpecializationType>();
2790-
assert(FReturnType);
2791+
assert(FReturnType && "expected to see a return type");
27912792
// Deduce template arguments of the deduction guide f from the RHS of
27922793
// the alias.
27932794
//
@@ -2812,9 +2813,12 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
28122813
// Must initialize n elements, this is required by DeduceTemplateArguments.
28132814
SmallVector<DeducedTemplateArgument> DeduceResults(
28142815
F->getTemplateParameters()->size());
2816+
28152817
// FIXME: DeduceTemplateArguments stops immediately at the first
2816-
// non-deducible template parameter, extend it to continue performing
2817-
// deduction for rest of parameters.
2818+
// non-deducible template argument. However, this doesn't seem to casue
2819+
// issues for practice cases, we probably need to extend it to continue
2820+
// performing deduction for rest of arguments to align with the C++
2821+
// standard.
28182822
SemaRef.DeduceTemplateArguments(
28192823
F->getTemplateParameters(), FReturnType->template_arguments(),
28202824
AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,
@@ -2902,7 +2906,7 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
29022906
FPrimeTemplateParams.push_back(NewParam);
29032907

29042908
assert(TemplateArgsForBuildingFPrime[FTemplateParamIdx].isNull() &&
2905-
"InstantiatedArgs must be null before setting");
2909+
"The argument must be null before setting");
29062910
TemplateArgsForBuildingFPrime[FTemplateParamIdx] =
29072911
Context.getCanonicalTemplateArgument(
29082912
Context.getInjectedTemplateArg(NewParam));
@@ -2936,7 +2940,9 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
29362940
const auto &D = DeduceResults[Index];
29372941
if (D.isNull()) {
29382942
// 2): Non-deduced template parameter has been built already.
2939-
assert(!TemplateArgsForBuildingFPrime[Index].isNull());
2943+
assert(!TemplateArgsForBuildingFPrime[Index].isNull() &&
2944+
"template arguments for non-deduced template parameters should "
2945+
"be been set!");
29402946
continue;
29412947
}
29422948
TemplateArgumentLoc Input = SemaRef.getTrivialTemplateArgumentLoc(
@@ -2956,7 +2962,7 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
29562962
F, TemplateArgListForBuildingFPrime, AliasTemplate->getLocation(),
29572963
Sema::CodeSynthesisContext::BuildingDeductionGuides)) {
29582964
auto *GG = dyn_cast<CXXDeductionGuideDecl>(FPrime);
2959-
// FIXME: implement the assoicated constraint per C++
2965+
// FIXME: implement the associated constraint per C++
29602966
// [over.match.class.deduct]p3.3:
29612967
// The associated constraints ([temp.constr.decl]) are the
29622968
// conjunction of the associated constraints of g and a

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

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %clang_cc1 -fsyntax-only -Wno-c++11-narrowing -Wno-literal-conversion -std=c++20 -verify %s
2-
// expected-no-diagnostics
2+
33
namespace test1 {
44
template <typename T>
55
struct Foo { T t; };
@@ -172,6 +172,22 @@ auto b = AFoo{};
172172
} // namespace test13
173173

174174
namespace test14 {
175+
template<typename T>
176+
concept IsInt = __is_same(decltype(T()), int);
177+
178+
template<IsInt T, int N>
179+
struct Foo {
180+
Foo(T const (&)[N]);
181+
};
182+
183+
template <int K>
184+
using Bar = Foo<double, K>; // expected-note {{constraints not satisfied for class template 'Foo'}}
185+
// expected-note@-1 {{candidate template ignored: could not match}}
186+
double abc[3];
187+
Bar s2 = {abc}; // expected-error {{no viable constructor or deduction guide for deduction }}
188+
} // namespace test14
189+
190+
namespace test15 {
175191
template <class T> struct Foo { Foo(T); };
176192

177193
template<class V> using AFoo = Foo<V *>;
@@ -183,4 +199,24 @@ AFoo a1(&i); // OK, deduce Foo<int *>
183199
// FIXME: we should reject this case as the W is not deduced from the deduced
184200
// type Foo<int *>.
185201
BFoo b2(&i);
186-
} // namespace test14
202+
} // namespace test15
203+
204+
namespace test16 {
205+
struct X { X(int); X(const X&); };
206+
template<class T>
207+
struct Foo {
208+
T t;
209+
Foo(T t) : t(t) {}
210+
};
211+
template<class T>
212+
using AFoo = Foo<T>;
213+
int i = 0;
214+
AFoo s{i};
215+
static_assert(__is_same(decltype(s.t), int));
216+
217+
// explicit deduction guide.
218+
Foo(int) -> Foo<X>;
219+
AFoo s2{i};
220+
// FIXME: the type should be X because of the above explicit deduction guide.
221+
static_assert(__is_same(decltype(s2.t), int));
222+
} // namespace test16

0 commit comments

Comments
 (0)