]> granicus.if.org Git - clang/commitdiff
Do exception spec compatibility tests for member pointers, too.
authorSebastian Redl <sebastian.redl@getdesigned.at>
Wed, 14 Oct 2009 14:38:54 +0000 (14:38 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Wed, 14 Oct 2009 14:38:54 +0000 (14:38 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84098 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExceptionSpec.cpp
test/SemaCXX/exception-spec.cpp

index 4171ecea8a1b74375e0f315a3459c0616bfcdebe..261bebf9553c6393f9c9e2ee042f3deb6c41b637 100644 (file)
@@ -26,6 +26,8 @@ static const FunctionProtoType *GetUnderlyingFunction(QualType T)
     T = PtrTy->getPointeeType();
   else if (const ReferenceType *RefTy = T->getAs<ReferenceType>())
     T = RefTy->getPointeeType();
+  else if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>())
+    T = MPTy->getPointeeType();
   return T->getAs<FunctionProtoType>();
 }
 
@@ -171,6 +173,9 @@ bool Sema::CheckExceptionSpecSubset(unsigned DiagID, unsigned NoteID,
        SubE = Subset->exception_end(); SubI != SubE; ++SubI) {
     // Take one type from the subset.
     QualType CanonicalSubT = Context.getCanonicalType(*SubI);
+    // Unwrap pointers and references so that we can do checks within a class
+    // hierarchy. Don't unwrap member pointers; they don't have hierarchy
+    // conversions on the pointee.
     bool SubIsPointer = false;
     if (const ReferenceType *RefTy = CanonicalSubT->getAs<ReferenceType>())
       CanonicalSubT = RefTy->getPointeeType();
index bd22bf3ddd9e3c757590ba234fb11f0a886ef975..f55a4494ea4db02ee3dda9df1531dc0463c6f13c 100644 (file)
@@ -166,3 +166,17 @@ void fnptrs()
   void (*t11)(void (*)() throw(A)) = &s9;  // expected-error {{argument types differ}} expected-error {{incompatible type}} expected-warning{{disambiguated}}
   void (*t12)(void (*)() throw(D)) = &s9;  // expected-error {{argument types differ}} expected-error {{incompatible type}} expected-warning{{disambiguated}}
 }
+
+// Member function stuff
+
+struct Str1 { void f() throw(int); }; // expected-note {{previous declaration}}
+void Str1::f() // expected-error {{does not match previous declaration}}
+{
+}
+
+void mfnptr()
+{
+  void (Str1::*pfn1)() throw(int) = &Str1::f; // valid
+  void (Str1::*pfn2)() = &Str1::f; // valid
+  void (Str1::*pfn3)() throw() = &Str1::f; // expected-error {{not superset}} expected-error {{incompatible type}}
+}