diff options
author | Anastasia Stulova <anastasia.stulova@arm.com> | 2019-05-08 14:23:49 +0000 |
---|---|---|
committer | Anastasia Stulova <anastasia.stulova@arm.com> | 2019-05-08 14:23:49 +0000 |
commit | a5d10485549e0c79cd825773460453351afd2fb5 (patch) | |
tree | e13de13ba79931a29f9754a90b900e01f51d1102 /lib/Sema/SemaExpr.cpp | |
parent | d8337696a9075f7e9b6555296fb9b9363cd87c91 (diff) | |
download | clang-a5d10485549e0c79cd825773460453351afd2fb5.tar.gz |
[Sema][OpenCL] Make address space conversions a bit stricter.
The semantics for converting nested pointers between address
spaces are not very well defined. Some conversions which do not
really carry any meaning only produce warnings, and in some cases
warnings hide invalid conversions, such as 'global int*' to
'local float*'!
This patch changes the logic in checkPointerTypesForAssignment
and checkAddressSpaceCast to fail properly on implicit conversions
that should definitely not be permitted. We also dig deeper into the
pointer types and warn on explicit conversions where the address
space in a nested pointer changes, regardless of whether the address
space is compatible with the corresponding pointer nesting level
on the destination type.
Fixes PR39674!
Patch by ebevhan (Bevin Hansson)!
Differential Revision: https://reviews.llvm.org/D58236
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@360258 91177308-0d34-0410-b5e6-96231b3b80d8
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; |