diff options
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index d8c0896147..8bb306e66d 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -7724,9 +7724,9 @@ checkPointerTypesForAssignment(Sema &S, QualType LHSType, QualType RHSType) { } if (!lhq.compatiblyIncludes(rhq)) { - // Treat address-space mismatches as fatal. TODO: address subspaces + // Treat address-space mismatches as fatal. if (!lhq.isAddressSpaceSupersetOf(rhq)) - ConvTy = Sema::IncompatiblePointerDiscardsQualifiers; + return Sema::IncompatiblePointerDiscardsQualifiers; // It's okay to add or remove GC or lifetime qualifiers when converting to // and from void*. @@ -7799,8 +7799,22 @@ checkPointerTypesForAssignment(Sema &S, QualType LHSType, QualType RHSType) { // level of indirection, this must be the issue. if (isa<PointerType>(lhptee) && isa<PointerType>(rhptee)) { do { - lhptee = cast<PointerType>(lhptee)->getPointeeType().getTypePtr(); - rhptee = cast<PointerType>(rhptee)->getPointeeType().getTypePtr(); + std::tie(lhptee, lhq) = + cast<PointerType>(lhptee)->getPointeeType().split().asPair(); + std::tie(rhptee, rhq) = + cast<PointerType>(rhptee)->getPointeeType().split().asPair(); + + // Inconsistent address spaces at this point is invalid, even if the + // address spaces would be compatible. + // FIXME: This doesn't catch address space mismatches for pointers of + // different nesting levels, like: + // __local int *** a; + // int ** b = a; + // It's not clear how to actually determine when such pointers are + // invalidly incompatible. + if (lhq.getAddressSpace() != rhq.getAddressSpace()) + return Sema::IncompatibleNestedPointerAddressSpaceMismatch; + } while (isa<PointerType>(lhptee) && isa<PointerType>(rhptee)); if (lhptee == rhptee) @@ -14213,6 +14227,9 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, case IncompatibleNestedPointerQualifiers: DiagKind = diag::ext_nested_pointer_qualifier_mismatch; break; + case IncompatibleNestedPointerAddressSpaceMismatch: + DiagKind = diag::err_typecheck_incompatible_nested_address_space; + break; case IntToBlockPointer: DiagKind = diag::err_int_to_block_pointer; break; |