This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGcde139016a4e: [clang][Sema] Fix a crash when instantiating a 
non-type template argument in a… (authored by 0x59616e).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Changed prior to commit:
  https://reviews.llvm.org/D151062?vs=525157&id=525160#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151062/new/

https://reviews.llvm.org/D151062

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/SemaCXX/PR62533.cpp
  clang/test/SemaTemplate/ms-sizeof-missing-typename.cpp

Index: clang/test/SemaTemplate/ms-sizeof-missing-typename.cpp
===================================================================
--- clang/test/SemaTemplate/ms-sizeof-missing-typename.cpp
+++ clang/test/SemaTemplate/ms-sizeof-missing-typename.cpp
@@ -50,7 +50,7 @@
 }
 
 namespace ambiguous_missing_parens {
-// expected-error@+1 {{'Q::U' instantiated to a class template, not a function template}}
+// expected-error@+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@+1 {{class template declared here}}
Index: clang/test/SemaCXX/PR62533.cpp
===================================================================
--- /dev/null
+++ 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@-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@+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@+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}}
+}
Index: clang/lib/Sema/SemaTemplate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -5001,13 +5001,20 @@
     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);
 }
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5490,10 +5490,10 @@
 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<
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -437,7 +437,8 @@
   ``__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
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to