diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaCast.cpp | 18 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 24 |
2 files changed, 32 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index a905ebc6730..7a8cbca1e3f 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -2311,6 +2311,24 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, return SuccessResult; } + // Diagnose address space conversion in nested pointers. + QualType DestPtee = DestType->getPointeeType().isNull() + ? DestType->getPointeeType() + : DestType->getPointeeType()->getPointeeType(); + QualType SrcPtee = SrcType->getPointeeType().isNull() + ? SrcType->getPointeeType() + : SrcType->getPointeeType()->getPointeeType(); + while (!DestPtee.isNull() && !SrcPtee.isNull()) { + if (DestPtee.getAddressSpace() != SrcPtee.getAddressSpace()) { + Self.Diag(OpRange.getBegin(), + diag::warn_bad_cxx_cast_nested_pointer_addr_space) + << CStyle << SrcType << DestType << SrcExpr.get()->getSourceRange(); + break; + } + DestPtee = DestPtee->getPointeeType(); + SrcPtee = SrcPtee->getPointeeType(); + } + // C++ 5.2.10p7: A pointer to an object can be explicitly converted to // a pointer to an object of different type. // Void pointers are not specified, but supported by every compiler out there. diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 9a9843827b3..db1884acd34 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -3176,7 +3176,7 @@ static bool isNonTrivialObjCLifetimeConversion(Qualifiers FromQuals, /// FromType and \p ToType is permissible, given knowledge about whether every /// outer layer is const-qualified. static bool isQualificationConversionStep(QualType FromType, QualType ToType, - bool CStyle, + bool CStyle, bool IsTopLevel, bool &PreviousToQualsIncludeConst, bool &ObjCLifetimeConversion) { Qualifiers FromQuals = FromType.getQualifiers(); @@ -3213,11 +3213,15 @@ static bool isQualificationConversionStep(QualType FromType, QualType ToType, if (!CStyle && !ToQuals.compatiblyIncludes(FromQuals)) return false; - // For a C-style cast, just require the address spaces to overlap. - // FIXME: Does "superset" also imply the representation of a pointer is the - // same? We're assuming that it does here and in compatiblyIncludes. - if (CStyle && !ToQuals.isAddressSpaceSupersetOf(FromQuals) && - !FromQuals.isAddressSpaceSupersetOf(ToQuals)) + // If address spaces mismatch: + // - in top level it is only valid to convert to addr space that is a + // superset in all cases apart from C-style casts where we allow + // conversions between overlapping address spaces. + // - in non-top levels it is not a valid conversion. + if (ToQuals.getAddressSpace() != FromQuals.getAddressSpace() && + (!IsTopLevel || + !(ToQuals.isAddressSpaceSupersetOf(FromQuals) || + (CStyle && FromQuals.isAddressSpaceSupersetOf(ToQuals))))) return false; // -- if the cv 1,j and cv 2,j are different, then const is in @@ -3258,9 +3262,9 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType, bool PreviousToQualsIncludeConst = true; bool UnwrappedAnyPointer = false; while (Context.UnwrapSimilarTypes(FromType, ToType)) { - if (!isQualificationConversionStep(FromType, ToType, CStyle, - PreviousToQualsIncludeConst, - ObjCLifetimeConversion)) + if (!isQualificationConversionStep( + FromType, ToType, CStyle, !UnwrappedAnyPointer, + PreviousToQualsIncludeConst, ObjCLifetimeConversion)) return false; UnwrappedAnyPointer = true; } @@ -4499,7 +4503,7 @@ Sema::CompareReferenceRelationship(SourceLocation Loc, // If we find a qualifier mismatch, the types are not reference-compatible, // but are still be reference-related if they're similar. bool ObjCLifetimeConversion = false; - if (!isQualificationConversionStep(T2, T1, /*CStyle=*/false, + if (!isQualificationConversionStep(T2, T1, /*CStyle=*/false, TopLevel, PreviousToQualsIncludeConst, ObjCLifetimeConversion)) return (ConvertedReferent || Context.hasSimilarType(T1, T2)) |