]> granicus.if.org Git - clang/commitdiff
Sema: Fix crash during member pointer conversion involving incomplete classes
authorDavid Majnemer <david.majnemer@gmail.com>
Thu, 16 Jan 2014 12:02:55 +0000 (12:02 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Thu, 16 Jan 2014 12:02:55 +0000 (12:02 +0000)
We would attempt to determine the inheritance relationship between
classes 'A' and 'B' during static_cast if we tried to convert from 'int
A::*' to 'int B::*'.  However, the question "does A derive from B" is
not meaningful when 'A' isn't defined.

Handle this case by requiring that 'A' be defined.

This fixes PR18506.

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

lib/Sema/SemaCast.cpp
test/SemaCXX/static-cast.cpp

index ef229cf838be145e0a68de62b4901c353654a7aa..63cb15db52905a1c5a3cfbf2c3dd99ff10617756 100644 (file)
@@ -1346,7 +1346,8 @@ TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, QualType SrcType,
   QualType DestClass(DestMemPtr->getClass(), 0);
   CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
                   /*DetectVirtual=*/true);
-  if (!Self.IsDerivedFrom(SrcClass, DestClass, Paths)) {
+  if (Self.RequireCompleteType(OpRange.getBegin(), SrcClass, 0) ||
+      !Self.IsDerivedFrom(SrcClass, DestClass, Paths)) {
     return TC_NotApplicable;
   }
 
index 03ee160ca3e0c237da666ef38650b78755cfa48a..06fd8636e5d6d7d27a24f211af24ea93510bbe17 100644 (file)
@@ -9,6 +9,8 @@ struct F : public C1 {};            // Single path to B with virtual.
 struct G1 : public B {};
 struct G2 : public B {};
 struct H : public G1, public G2 {}; // Ambiguous path to B.
+struct I;                           // Incomplete.
+struct J;                           // Incomplete.
 
 enum Enum { En1, En2 };
 enum Onom { On1, On2 };
@@ -131,6 +133,7 @@ void t_529_9()
   // Bad code below
   (void)static_cast<int A::*>((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'H' to pointer to member of base class 'A':}}
   (void)static_cast<int A::*>((int F::*)0); // expected-error {{conversion from pointer to member of class 'F' to pointer to member of class 'A' via virtual base 'B' is not allowed}}
+  (void)static_cast<int I::*>((int J::*)0); // expected-error {{static_cast from 'int J::*' to 'int I::*' is not allowed}}
 }
 
 // PR 5261 - static_cast should instantiate template if possible