From: David Majnemer Date: Thu, 16 Jan 2014 12:02:55 +0000 (+0000) Subject: Sema: Fix crash during member pointer conversion involving incomplete classes X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b52564aa96febc1e791dd26213c87c4a591251dc;p=clang Sema: Fix crash during member pointer conversion involving incomplete classes 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 --- diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp index ef229cf838..63cb15db52 100644 --- a/lib/Sema/SemaCast.cpp +++ b/lib/Sema/SemaCast.cpp @@ -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; } diff --git a/test/SemaCXX/static-cast.cpp b/test/SemaCXX/static-cast.cpp index 03ee160ca3..06fd8636e5 100644 --- a/test/SemaCXX/static-cast.cpp +++ b/test/SemaCXX/static-cast.cpp @@ -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 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 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 J::*)0); // expected-error {{static_cast from 'int J::*' to 'int I::*' is not allowed}} } // PR 5261 - static_cast should instantiate template if possible