[clang] cde1390 - [clang][Sema] Fix a crash when instantiating a non-type template argument in a dependent scope.
via cfe-commits
cfe-commits at lists.llvm.org
Wed May 24 06:47:03 PDT 2023
Author: Sheng
Date: 2023-05-24T21:46:31+08:00
New Revision: cde139016a4eb2d71950e135f9c037987ecdb7cf
URL: https://github.com/llvm/llvm-project/commit/cde139016a4eb2d71950e135f9c037987ecdb7cf
DIFF: https://github.com/llvm/llvm-project/commit/cde139016a4eb2d71950e135f9c037987ecdb7cf.diff
LOG: [clang][Sema] Fix a crash when instantiating a non-type template argument in a dependent scope.
The type alias template is not diagnosed when instantiating an expected non-type template argument in a dependent scope, causing ICE.
Besides that, the diagnostic message has been updated to account for the fact that the function template is not the only non-type template.
Fixes #62533
Reviewed By: #clang-language-wg, erichkeane
Differential Revision: https://reviews.llvm.org/D151062
Added:
clang/test/SemaCXX/PR62533.cpp
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaTemplate.cpp
clang/test/SemaTemplate/ms-sizeof-missing-typename.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 92fe909e5e8a6..38a1347368c4c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -437,7 +437,8 @@ Bug Fixes in This Version
``__builtin_dynamic_object_size`` on structs containing flexible array
members.
(`#62789 <https://github.com/llvm/llvm-project/issues/62789>`_).
-
+- Fix a crash when instantiating a non-type template argument in a dependent scope.
+ (`#62533 <https://github.com/llvm/llvm-project/issues/62533>`_).
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d21cb62cd0423..0cbc2fc8c8949 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5490,10 +5490,10 @@ def note_template_kw_refers_to_non_template : Note<
def err_template_kw_refers_to_dependent_non_template : Error<
"%0%select{| following the 'template' keyword}1 "
"cannot refer to a dependent template">;
-def err_template_kw_refers_to_class_template : Error<
- "'%0%1' instantiated to a class template, not a function template">;
-def note_referenced_class_template : Note<
- "class template declared here">;
+def err_template_kw_refers_to_type_template : Error<
+ "'%0%1' is expected to be a non-type template, but instantiated to a %select{class|type alias}2 template">;
+def note_referenced_type_template : Note<
+ "%select{class|type alias}0 template declared here">;
def err_template_kw_missing : Error<
"missing 'template' keyword prior to dependent template name '%0%1'">;
def ext_template_outside_of_template : ExtWarn<
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 7a545214596ba..063ddb418c431 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -5001,13 +5001,20 @@ Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS,
return ExprError();
}
- if (ClassTemplateDecl *Temp = R.getAsSingle<ClassTemplateDecl>()) {
- Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_class_template)
- << SS.getScopeRep()
- << NameInfo.getName().getAsString() << SS.getRange();
- Diag(Temp->getLocation(), diag::note_referenced_class_template);
+ auto DiagnoseTypeTemplateDecl = [&](TemplateDecl *Temp,
+ bool isTypeAliasTemplateDecl) {
+ Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_type_template)
+ << SS.getScopeRep() << NameInfo.getName().getAsString() << SS.getRange()
+ << isTypeAliasTemplateDecl;
+ Diag(Temp->getLocation(), diag::note_referenced_type_template) << 0;
return ExprError();
- }
+ };
+
+ if (ClassTemplateDecl *Temp = R.getAsSingle<ClassTemplateDecl>())
+ return DiagnoseTypeTemplateDecl(Temp, false);
+
+ if (TypeAliasTemplateDecl *Temp = R.getAsSingle<TypeAliasTemplateDecl>())
+ return DiagnoseTypeTemplateDecl(Temp, true);
return BuildTemplateIdExpr(SS, TemplateKWLoc, R, /*ADL*/ false, TemplateArgs);
}
diff --git a/clang/test/SemaCXX/PR62533.cpp b/clang/test/SemaCXX/PR62533.cpp
new file mode 100644
index 0000000000000..920ea54d4b00e
--- /dev/null
+++ b/clang/test/SemaCXX/PR62533.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct test {
+ template<typename> using fun_
diff = char; // expected-note 2{{class template declared here}}
+};
+
+template<typename T, typename V>
+decltype(T::template fun_
diff <V>) foo1() {}
+// expected-note at -1 {{candidate template ignored: substitution failure [with T = test<int>, V = int]: 'test<int>::fun_
diff ' is expected to be a non-type template, but instantiated to a type alias template}}
+
+template<typename T>
+void foo2() {
+ // expected-error at +1 {{test<int>::fun_
diff ' is expected to be a non-type template, but instantiated to a type alias template}}
+ int a = test<T>::template fun_
diff <int>;
+}
+
+template<typename T, typename V>
+struct has_fun_
diff {
+ using type = double;
+};
+
+template<typename T>
+struct has_fun_
diff <T, int> {
+ // expected-error at +1 {{'test<int>::fun_
diff ' is expected to be a non-type template, but instantiated to a type alias template}}
+ using type = decltype(T::template fun_
diff <int>);
+};
+
+void bar() {
+ foo1<test<int>, int>(); // expected-error {{no matching function for call to 'foo1'}}
+ foo2<int>(); // expected-note {{in instantiation of function template specialization}}
+ has_fun_
diff <test<int>, int>::type a; // expected-note {{in instantiation of template class}}
+}
diff --git a/clang/test/SemaTemplate/ms-sizeof-missing-typename.cpp b/clang/test/SemaTemplate/ms-sizeof-missing-typename.cpp
index 9bafe6c98c2b7..fcba385be5ab4 100644
--- a/clang/test/SemaTemplate/ms-sizeof-missing-typename.cpp
+++ b/clang/test/SemaTemplate/ms-sizeof-missing-typename.cpp
@@ -50,7 +50,7 @@ template struct Foo<Bar>; // expected-note-re {{in instantiation {{.*}} requeste
}
namespace ambiguous_missing_parens {
-// expected-error at +1 {{'Q::U' instantiated to a class template, not a function template}}
+// expected-error at +1 {{'Q::U' is expected to be a non-type template, but instantiated to a class template}}
template <typename T> void f() { int a = sizeof T::template U<0> + 4; }
struct Q {
// expected-note at +1 {{class template declared here}}
More information about the cfe-commits
mailing list