On Sun, Nov 15, 2009 at 2:20 AM, Douglas Gregor <[email protected]> wrote: > Author: dgregor > Date: Sun Nov 15 03:20:52 2009 > New Revision: 88848 > > URL: http://llvm.org/viewvc/llvm-project?rev=88848&view=rev > Log: > When performing a static downcast as part of a static_cast, make sure > that we're dealing with canonical types like the documentation say > (yay, CanQualType). Alas, this is another instance where using > getQualifiers() on a non-canonical QualType got us in trouble. > > Good news: with this fix, Clang can now parse all of its own headers!
Woot! Very cool Doug! - Daniel > Modified: > cfe/trunk/lib/Sema/SemaCXXCast.cpp > cfe/trunk/test/SemaCXX/static-cast.cpp > > Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXCast.cpp?rev=88848&r1=88847&r2=88848&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaCXXCast.cpp (original) > +++ cfe/trunk/lib/Sema/SemaCXXCast.cpp Sun Nov 15 03:20:52 2009 > @@ -77,8 +77,8 @@ > const SourceRange &OpRange, > unsigned &msg, > CastExpr::CastKind &Kind); > -static TryCastResult TryStaticDowncast(Sema &Self, QualType SrcType, > - QualType DestType, bool CStyle, > +static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType, > + CanQualType DestType, bool CStyle, > const SourceRange &OpRange, > QualType OrigSrcType, > QualType OrigDestType, unsigned &msg, > @@ -190,7 +190,8 @@ > assert((DestType->isPointerType() || DestType->isMemberPointerType()) && > "Destination type is not pointer or pointer to member."); > > - QualType UnwrappedSrcType = SrcType, UnwrappedDestType = DestType; > + QualType UnwrappedSrcType = Self.Context.getCanonicalType(SrcType), > + UnwrappedDestType = Self.Context.getCanonicalType(DestType); > llvm::SmallVector<Qualifiers, 8> cv1, cv2; > > // Find the qualifications. > @@ -573,7 +574,9 @@ > > QualType DestPointee = DestReference->getPointeeType(); > > - return TryStaticDowncast(Self, SrcExpr->getType(), DestPointee, CStyle, > + return TryStaticDowncast(Self, > + Self.Context.getCanonicalType(SrcExpr->getType()), > + Self.Context.getCanonicalType(DestPointee), > CStyle, > OpRange, SrcExpr->getType(), DestType, msg, Kind); > } > > @@ -601,16 +604,17 @@ > return TC_NotApplicable; > } > > - return TryStaticDowncast(Self, SrcPointer->getPointeeType(), > - DestPointer->getPointeeType(), CStyle, > - OpRange, SrcType, DestType, msg, Kind); > + return TryStaticDowncast(Self, > + > Self.Context.getCanonicalType(SrcPointer->getPointeeType()), > + > Self.Context.getCanonicalType(DestPointer->getPointeeType()), > + CStyle, OpRange, SrcType, DestType, msg, Kind); > } > > /// TryStaticDowncast - Common functionality of TryStaticReferenceDowncast > and > /// TryStaticPointerDowncast. Tests whether a static downcast from SrcType to > -/// DestType, both of which must be canonical, is possible and allowed. > +/// DestType is possible and allowed. > TryCastResult > -TryStaticDowncast(Sema &Self, QualType SrcType, QualType DestType, > +TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType, > bool CStyle, const SourceRange &OpRange, QualType > OrigSrcType, > QualType OrigDestType, unsigned &msg, > CastExpr::CastKind &Kind) { > @@ -620,7 +624,7 @@ > return TC_NotApplicable; > > // Downcast can only happen in class hierarchies, so we need classes. > - if (!DestType->isRecordType() || !SrcType->isRecordType()) { > + if (!DestType->getAs<RecordType>() || !SrcType->getAs<RecordType>()) { > return TC_NotApplicable; > } > > @@ -676,12 +680,13 @@ > EE = PI->rend(); > EI != EE; ++EI) > PathDisplayStr += EI->Base->getType().getAsString() + " -> "; > - PathDisplayStr += DestType.getAsString(); > + PathDisplayStr += QualType(DestType).getAsString(); > } > } > > Self.Diag(OpRange.getBegin(), diag::err_ambiguous_base_to_derived_cast) > - << SrcType.getUnqualifiedType() << DestType.getUnqualifiedType() > + << QualType(SrcType).getUnqualifiedType() > + << QualType(DestType).getUnqualifiedType() > << PathDisplayStr << OpRange; > msg = 0; > return TC_Failed; > > Modified: cfe/trunk/test/SemaCXX/static-cast.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/static-cast.cpp?rev=88848&r1=88847&r2=88848&view=diff > > ============================================================================== > --- cfe/trunk/test/SemaCXX/static-cast.cpp (original) > +++ cfe/trunk/test/SemaCXX/static-cast.cpp Sun Nov 15 03:20:52 2009 > @@ -1,5 +1,4 @@ > // RUN: clang-cc -fsyntax-only -verify -faccess-control %s > - > struct A {}; > struct B : public A {}; // Single public base. > struct C1 : public virtual B {}; // Single virtual base. > @@ -162,3 +161,20 @@ > void test_ctor_init() { > (void)static_cast<X1>(X1()); > } > + > +// Casting away constness > +struct X2 { > +}; > + > +struct X3 : X2 { > +}; > + > +struct X4 { > + typedef const X3 X3_typedef; > + > + void f() const { > + (void)static_cast<X3_typedef*>(x2); > + } > + > + const X2 *x2; > +}; > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
