diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-12-01 21:43:58 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-12-01 21:43:58 +0000 |
commit | da80f74d8a3f9a78a48d5fdc2d26eb125b70e0d7 (patch) | |
tree | 6f221ae17e54b15f99eea6402cece7fb2eb4ed6e /lib/Sema/SemaOverload.cpp | |
parent | 846eabd187be4bfe992e8bca131166b734d86e0d (diff) |
Improve our handling of cv-qualifiers in Objective-C pointer
conversions. Previously, we would end up collapsing qualification
conversions into the Objective-C pointer conversion step, including
(possibly) stripping qualifiers that shouldn't be removed.
This generalizes BuildSimilarlyQualifiedPointerType() to also work on
Objective-C object pointers, then eliminates the (redundant, not
totally correct) BuildSimilarlyQualifiedObjCObjectPointerType()
function.
Fixes <rdar://problem/8714395>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@120607 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 59 |
1 files changed, 30 insertions, 29 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 5da655907c..ce66c3c0fc 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -1358,10 +1358,14 @@ bool Sema::IsComplexPromotion(QualType FromType, QualType ToType) { /// if non-empty, will be a pointer to ToType that may or may not have /// the right set of qualifiers on its pointee. static QualType -BuildSimilarlyQualifiedPointerType(const PointerType *FromPtr, +BuildSimilarlyQualifiedPointerType(const Type *FromPtr, QualType ToPointee, QualType ToType, ASTContext &Context) { - QualType CanonFromPointee = Context.getCanonicalType(FromPtr->getPointeeType()); + assert((FromPtr->getTypeClass() == Type::Pointer || + FromPtr->getTypeClass() == Type::ObjCObjectPointer) && + "Invalid similarly-qualified pointer type"); + QualType CanonFromPointee + = Context.getCanonicalType(FromPtr->getPointeeType()); QualType CanonToPointee = Context.getCanonicalType(ToPointee); Qualifiers Quals = CanonFromPointee.getQualifiers(); @@ -1373,32 +1377,18 @@ BuildSimilarlyQualifiedPointerType(const PointerType *FromPtr, // Build a pointer to ToPointee. It has the right qualifiers // already. + if (isa<ObjCObjectPointerType>(ToType)) + return Context.getObjCObjectPointerType(ToPointee); return Context.getPointerType(ToPointee); } // Just build a canonical type that has the right qualifiers. - return Context.getPointerType( - Context.getQualifiedType(CanonToPointee.getLocalUnqualifiedType(), - Quals)); -} - -/// BuildSimilarlyQualifiedObjCObjectPointerType - In a pointer conversion from -/// the FromType, which is an objective-c pointer, to ToType, which may or may -/// not have the right set of qualifiers. -static QualType -BuildSimilarlyQualifiedObjCObjectPointerType(QualType FromType, - QualType ToType, - ASTContext &Context) { - QualType CanonFromType = Context.getCanonicalType(FromType); - QualType CanonToType = Context.getCanonicalType(ToType); - Qualifiers Quals = CanonFromType.getQualifiers(); - - // Exact qualifier match -> return the pointer type we're converting to. - if (CanonToType.getLocalQualifiers() == Quals) - return ToType; + QualType QualifiedCanonToPointee + = Context.getQualifiedType(CanonToPointee.getLocalUnqualifiedType(), Quals); - // Just build a canonical type that has the right qualifiers. - return Context.getQualifiedType(CanonToType.getLocalUnqualifiedType(), Quals); + if (isa<ObjCObjectPointerType>(ToType)) + return Context.getObjCObjectPointerType(QualifiedCanonToPointee); + return Context.getPointerType(QualifiedCanonToPointee); } static bool isNullPointerConstantForConversion(Expr *Expr, @@ -1482,10 +1472,11 @@ bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType, // , including objective-c pointers. QualType ToPointeeType = ToTypePtr->getPointeeType(); if (FromType->isObjCObjectPointerType() && ToPointeeType->isVoidType()) { - ConvertedType = BuildSimilarlyQualifiedObjCObjectPointerType(FromType, + ConvertedType = BuildSimilarlyQualifiedPointerType( + FromType->getAs<ObjCObjectPointerType>(), + ToPointeeType, ToType, Context); return true; - } const PointerType *FromTypePtr = FromType->getAs<PointerType>(); if (!FromTypePtr) @@ -1561,6 +1552,12 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType, FromType->getAs<ObjCObjectPointerType>(); if (ToObjCPtr && FromObjCPtr) { + // If the pointee types are the same (ignoring qualifications), + // then this is not a pointer conversion. + if (Context.hasSameUnqualifiedType(ToObjCPtr->getPointeeType(), + FromObjCPtr->getPointeeType())) + return false; + // Objective C++: We're able to convert between "id" or "Class" and a // pointer to any interface (in both directions). if (ToObjCPtr->isObjCBuiltinType() && FromObjCPtr->isObjCBuiltinType()) { @@ -1584,7 +1581,9 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType, !ToObjCPtr->getPointeeType().isAtLeastAsQualifiedAs( FromObjCPtr->getPointeeType())) return false; - ConvertedType = ToType; + ConvertedType = BuildSimilarlyQualifiedPointerType(FromObjCPtr, + ToObjCPtr->getPointeeType(), + ToType, Context); return true; } @@ -1593,7 +1592,9 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType, // interfaces, which is permitted. However, we're going to // complain about it. IncompatibleObjC = true; - ConvertedType = FromType; + ConvertedType = BuildSimilarlyQualifiedPointerType(FromObjCPtr, + ToObjCPtr->getPointeeType(), + ToType, Context); return true; } } @@ -1636,7 +1637,7 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType, IncompatibleObjC)) { // We always complain about this conversion. IncompatibleObjC = true; - ConvertedType = ToType; + ConvertedType = Context.getPointerType(ConvertedType); return true; } // Allow conversion of pointee being objective-c pointer to another one; @@ -1645,7 +1646,7 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType, ToPointeeType->getAs<ObjCObjectPointerType>() && isObjCPointerConversion(FromPointeeType, ToPointeeType, ConvertedType, IncompatibleObjC)) { - ConvertedType = ToType; + ConvertedType = Context.getPointerType(ConvertedType); return true; } |