Skip to content

Commit 5b6d72c

Browse files
committed
Disable alias template CTAD for C++17
Alias template class template argument deduction is a C++20 feature. Also updated relevant CTAD test cases.
1 parent 4107544 commit 5b6d72c

File tree

4 files changed

+33
-27
lines changed

4 files changed

+33
-27
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8444,9 +8444,11 @@ let CategoryName = "Lambda Issue" in {
84448444
"C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
84458445

84468446
// C++20 class template argument deduction for alias templates.
8447-
def warn_cxx17_compat_ctad_for_alias_templates : Warning<
8448-
"class template argument deduction for alias templates is incompatible with "
8449-
"C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
8447+
def warn_cxx17_compat_ctad_for_alias_templates
8448+
: Warning<"class template argument deduction for alias templates is "
8449+
"incompatible with "
8450+
"C++ standards before C++20">,
8451+
InGroup<CXXPre20Compat>;
84508452
}
84518453

84528454
def err_return_in_captured_stmt : Error<

clang/lib/Sema/SemaInit.cpp

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9895,26 +9895,30 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
98959895
if (!Template) {
98969896
if (auto *AliasTemplate = dyn_cast_or_null<TypeAliasTemplateDecl>(
98979897
TemplateName.getAsTemplateDecl())) {
9898-
Diag(Kind.getLocation(),
9899-
diag::warn_cxx17_compat_ctad_for_alias_templates);
9900-
LookupTemplateDecl = AliasTemplate;
9901-
auto UnderlyingType = AliasTemplate->getTemplatedDecl()
9902-
->getUnderlyingType()
9903-
.getCanonicalType();
9904-
// C++ [over.match.class.deduct#3]: ..., the defining-type-id of A must be
9905-
// of the form
9906-
// [typename] [nested-name-specifier] [template] simple-template-id
9907-
if (const auto *TST =
9908-
UnderlyingType->getAs<TemplateSpecializationType>()) {
9909-
Template = dyn_cast_or_null<ClassTemplateDecl>(
9910-
TST->getTemplateName().getAsTemplateDecl());
9911-
} else if (const auto *RT = UnderlyingType->getAs<RecordType>()) {
9912-
// Cases where template arguments in the RHS of the alias are not
9913-
// dependent. e.g.
9914-
// using AliasFoo = Foo<bool>;
9915-
if (const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(
9916-
RT->getAsCXXRecordDecl()))
9917-
Template = CTSD->getSpecializedTemplate();
9898+
if (getLangOpts().CPlusPlus20) {
9899+
LookupTemplateDecl = AliasTemplate;
9900+
auto UnderlyingType = AliasTemplate->getTemplatedDecl()
9901+
->getUnderlyingType()
9902+
.getCanonicalType();
9903+
// C++ [over.match.class.deduct#3]: ..., the defining-type-id of A must
9904+
// be of the form
9905+
// [typename] [nested-name-specifier] [template] simple-template-id
9906+
if (const auto *TST =
9907+
UnderlyingType->getAs<TemplateSpecializationType>()) {
9908+
Template = dyn_cast_or_null<ClassTemplateDecl>(
9909+
TST->getTemplateName().getAsTemplateDecl());
9910+
} else if (const auto *RT = UnderlyingType->getAs<RecordType>()) {
9911+
// Cases where template arguments in the RHS of the alias are not
9912+
// dependent. e.g.
9913+
// using AliasFoo = Foo<bool>;
9914+
if (const auto *CTSD =
9915+
llvm::dyn_cast<ClassTemplateSpecializationDecl>(
9916+
RT->getAsCXXRecordDecl()))
9917+
Template = CTSD->getSpecializedTemplate();
9918+
}
9919+
} else {
9920+
Diag(Kind.getLocation(),
9921+
diag::warn_cxx17_compat_ctad_for_alias_templates);
99189922
}
99199923
}
99209924
}

clang/test/SemaCXX/cxx17-compat.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ template<typename T> struct A { A(T); };
137137
template<typename T> using B = A<T>;
138138
B b = {1};
139139
#if __cplusplus <= 201703L
140-
// FIXME: diagnose as well
141-
#else
142-
// expected-warning@-4 {{class template argument deduction for alias templates is incompatible with C++ standards before C++20}}
140+
// expected-error@-2 {{alias template 'B' requires template arguments; argument deduction only allowed for class templates or alias templates}}
141+
// expected-warning@-3 {{class template argument deduction for alias templates is incompatible with C++ standards before C++20}}
142+
// expected-note@-5 {{template is declared here}}
143143
#endif
144144
}

clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ namespace dependent {
113113
};
114114
template<typename T> void f() {
115115
typename T::X tx = 0;
116-
typename T::Y ty = 0;
116+
typename T::template Y<int> ty = 0;
117117
}
118118
template void f<B>();
119119

0 commit comments

Comments
 (0)