Skip to content

Commit ccab3dc

Browse files
committed
Handle invalid variable template specialization whose type depends on itself
1 parent fb96d51 commit ccab3dc

File tree

4 files changed

+30
-0
lines changed

4 files changed

+30
-0
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,8 @@ Bug Fixes to C++ Support
414414
- Clang now issues an error when placement new is used to modify a const-qualified variable
415415
in a ``constexpr`` function. (#GH131432)
416416
- Clang now emits a warning when class template argument deduction for alias templates is used in C++17. (#GH133806)
417+
- No longer crashes when instantiating invalid variable template specialization
418+
whose type depends on itself. (#GH51347)
417419

418420
Bug Fixes to AST Handling
419421
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5259,6 +5259,9 @@ def err_template_member_noparams : Error<
52595259
"extraneous 'template<>' in declaration of member %0">;
52605260
def err_template_tag_noparams : Error<
52615261
"extraneous 'template<>' in declaration of %0 %1">;
5262+
def err_var_template_spec_type_depends_on_self : Error<
5263+
"the type of variable template specialization %0 declared with deduced type "
5264+
"%1 depends on itself">;
52625265

52635266
def warn_unqualified_call_to_std_cast_function : Warning<
52645267
"unqualified call to '%0'">, InGroup<DiagGroup<"unqualified-std-cast-call">>;

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4377,6 +4377,13 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc,
43774377
if (VarTemplateSpecializationDecl *Spec =
43784378
Template->findSpecialization(CTAI.CanonicalConverted, InsertPos)) {
43794379
checkSpecializationReachability(TemplateNameLoc, Spec);
4380+
if (Spec->getType()->isUndeducedType()) {
4381+
// We are substituting the initializer of this variable template
4382+
// specialization.
4383+
Diag(TemplateNameLoc, diag::err_var_template_spec_type_depends_on_self)
4384+
<< Spec << Spec->getType();
4385+
return true;
4386+
}
43804387
// If we already have a variable template specialization, return it.
43814388
return Spec;
43824389
}

clang/test/SemaTemplate/instantiate-var-template.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,21 @@ namespace InvalidInsertPos {
4747
template<> int v<int, 0>;
4848
int k = v<int, 500>;
4949
}
50+
51+
namespace GH51347 {
52+
template <typename T>
53+
auto p = p<T>; // expected-error {{the type of variable template specialization 'p<int>'}}
54+
55+
auto x = p<int>; // expected-note {{in instantiation of variable template specialization 'GH51347::p'}}
56+
}
57+
58+
namespace GH97881_comment {
59+
template <bool B>
60+
auto g = sizeof(g<!B>);
61+
// expected-error@-1 {{the type of variable template specialization 'g<false>'}}
62+
// expected-note@-2 {{in instantiation of variable template specialization 'GH97881_comment::g'}}
63+
64+
void test() {
65+
(void)sizeof(g<false>); // expected-note {{in instantiation of variable template specialization 'GH97881_comment::g'}}
66+
}
67+
}

0 commit comments

Comments
 (0)