]> granicus.if.org Git - clang/commitdiff
Instantiation of a CXXMethodDecl may fail when the parameter type cannot be instantia...
authorNick Lewycky <nicholas@mxc.ca>
Fri, 2 Jan 2015 01:33:12 +0000 (01:33 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Fri, 2 Jan 2015 01:33:12 +0000 (01:33 +0000)
The FIXME in the test is caused by TemplateDeclInstantiator::VisitCXXRecordDecl
returning a nullptr instead of creating an invalid decl. This is a common
pattern across all of TemplateDeclInstantiator, so I'm not comfortable changing
it. The reason it's not invalid in the class template is due to support for an
MSVC extension, see r137573.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@225071 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplateInstantiateDecl.cpp
test/SemaTemplate/instantiate-method.cpp

index 9ba9c14559bd4e7ecd6d4fd1110fea155b38596f..40e86175b2cd0e64f524e4f1fa00a74561e73ac8 100644 (file)
@@ -2360,8 +2360,10 @@ Decl * TemplateDeclInstantiator
 Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl(
                                      ClassScopeFunctionSpecializationDecl *Decl) {
   CXXMethodDecl *OldFD = Decl->getSpecialization();
-  CXXMethodDecl *NewFD = cast<CXXMethodDecl>(VisitCXXMethodDecl(OldFD,
-                                                                nullptr, true));
+  CXXMethodDecl *NewFD =
+    cast_or_null<CXXMethodDecl>(VisitCXXMethodDecl(OldFD, nullptr, true));
+  if (!NewFD)
+    return nullptr;
 
   LookupResult Previous(SemaRef, NewFD->getNameInfo(), Sema::LookupOrdinaryName,
                         Sema::ForRedeclaration);
index 58cb8979555894a995d7bf42709ea99abdab6ba4..4cc40af7e123d5f3f924bf12dbbf1b0f41badf89 100644 (file)
@@ -182,3 +182,16 @@ namespace SameSignatureAfterInstantiation {
   };
   S<const int> s; // expected-note {{instantiation}}
 }
+
+namespace PR22040 {
+  template <typename T> struct Foobar {
+    template <> void bazqux(typename T::type) {}  // expected-error {{cannot specialize a function 'bazqux' within class scope}} expected-error 2{{cannot be used prior to '::' because it has no members}}
+  };
+
+  void test() {
+    // FIXME: we should suppress the "no member" errors
+    Foobar<void>::bazqux();  // expected-error{{no member named 'bazqux' in }}  expected-note{{in instantiation of template class }}
+    Foobar<int>::bazqux();  // expected-error{{no member named 'bazqux' in }}  expected-note{{in instantiation of template class }}
+    Foobar<int>::bazqux(3);  // expected-error{{no member named 'bazqux' in }}
+  }
+}