Skip to content

Commit 2a02404

Browse files
authored
[clang] fix a crash in error recovery in expressions resolving to templates (#135893)
We were using AssumedTemplate incorrectly for error recovery. Fixes #135621
1 parent 3264a50 commit 2a02404

File tree

4 files changed

+23
-6
lines changed

4 files changed

+23
-6
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ Bug Fixes in This Version
402402
when using the ``INTn_C`` macros. (#GH85995)
403403
- Fixed an assertion failure in the expansion of builtin macros like ``__has_embed()`` with line breaks before the
404404
closing paren. (#GH133574)
405+
- Fixed a crash in error recovery for expressions resolving to templates. (#GH135621)
405406
- Clang no longer accepts invalid integer constants which are too large to fit
406407
into any (standard or extended) integer type when the constant is unevaluated.
407408
Merely forming the token is sufficient to render the program invalid. Code
@@ -544,7 +545,7 @@ Arm and AArch64 Support
544545
^^^^^^^^^^^^^^^^^^^^^^^
545546
- For ARM targets, cc1as now considers the FPU's features for the selected CPU or Architecture.
546547
- The ``+nosimd`` attribute is now fully supported for ARM. Previously, this had no effect when being used with
547-
ARM targets, however this will now disable NEON instructions being generated. The ``simd`` option is
548+
ARM targets, however this will now disable NEON instructions being generated. The ``simd`` option is
548549
also now printed when the ``--print-supported-extensions`` option is used.
549550

550551
- Support for __ptrauth type qualifier has been added.

clang/lib/AST/Type.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4401,7 +4401,8 @@ TemplateSpecializationType::TemplateSpecializationType(
44014401
T.getKind() == TemplateName::SubstTemplateTemplateParmPack ||
44024402
T.getKind() == TemplateName::UsingTemplate ||
44034403
T.getKind() == TemplateName::QualifiedTemplate ||
4404-
T.getKind() == TemplateName::DeducedTemplate) &&
4404+
T.getKind() == TemplateName::DeducedTemplate ||
4405+
T.getKind() == TemplateName::AssumedTemplate) &&
44054406
"Unexpected template name for TemplateSpecializationType");
44064407

44074408
auto *TemplateArgs =

clang/lib/Sema/SemaExpr.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21111,11 +21111,15 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
2111121111
const bool IsTypeAliasTemplateDecl = isa<TypeAliasTemplateDecl>(Temp);
2111221112

2111321113
NestedNameSpecifier *NNS = ULE->getQualifierLoc().getNestedNameSpecifier();
21114-
TemplateName TN(dyn_cast<TemplateDecl>(Temp));
21115-
if (TN.isNull())
21114+
// FIXME: AssumedTemplate is not very appropriate for error recovery here,
21115+
// as it models only the unqualified-id case, where this case can clearly be
21116+
// qualified. Thus we can't just qualify an assumed template.
21117+
TemplateName TN;
21118+
if (auto *TD = dyn_cast<TemplateDecl>(Temp))
21119+
TN = Context.getQualifiedTemplateName(NNS, ULE->hasTemplateKeyword(),
21120+
TemplateName(TD));
21121+
else
2111621122
TN = Context.getAssumedTemplateName(NameInfo.getName());
21117-
TN = Context.getQualifiedTemplateName(NNS,
21118-
/*TemplateKeyword=*/true, TN);
2111921123

2112021124
Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_type_template)
2112121125
<< TN << ULE->getSourceRange() << IsTypeAliasTemplateDecl;

clang/test/SemaTemplate/recovery-crash.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,14 @@ namespace test1 {
6767
// expected-note@#defined-here {{defined here}}
6868
void NonTemplateClass::UndeclaredMethod() {}
6969
}
70+
71+
namespace GH135621 {
72+
template <class T> struct S {};
73+
// expected-note@-1 {{class template declared here}}
74+
template <class T2> void f() {
75+
S<T2>::template S<int>;
76+
// expected-error@-1 {{'S' is expected to be a non-type template, but instantiated to a class template}}
77+
}
78+
template void f<int>();
79+
// expected-note@-1 {{requested here}}
80+
} // namespace GH135621

0 commit comments

Comments
 (0)