Skip to content

Commit c52264e

Browse files
committed
[clang] fix a crash in error recovery in expressions resolving to templates
We were using AssumedTemplate incorrectly for error recovery. Fixes #135621
1 parent 2b983a2 commit c52264e

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
@@ -406,6 +406,7 @@ Bug Fixes in This Version
406406
when using the ``INTn_C`` macros. (#GH85995)
407407
- Fixed an assertion failure in the expansion of builtin macros like ``__has_embed()`` with line breaks before the
408408
closing paren. (#GH133574)
409+
- Fixed a crash in error recovery for expressions. (#GH135621)
409410
- Clang no longer accepts invalid integer constants which are too large to fit
410411
into any (standard or extended) integer type when the constant is unevaluated.
411412
Merely forming the token is sufficient to render the program invalid. Code
@@ -549,7 +550,7 @@ Arm and AArch64 Support
549550
^^^^^^^^^^^^^^^^^^^^^^^
550551
- For ARM targets, cc1as now considers the FPU's features for the selected CPU or Architecture.
551552
- The ``+nosimd`` attribute is now fully supported for ARM. Previously, this had no effect when being used with
552-
ARM targets, however this will now disable NEON instructions being generated. The ``simd`` option is
553+
ARM targets, however this will now disable NEON instructions being generated. The ``simd`` option is
553554
also now printed when the ``--print-supported-extensions`` option is used.
554555

555556
- 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)