summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaCast.cpp
diff options
context:
space:
mode:
authorAnastasia Stulova <anastasia.stulova@arm.com>2019-05-08 14:23:49 +0000
committerAnastasia Stulova <anastasia.stulova@arm.com>2019-05-08 14:23:49 +0000
commit5b6dda33d1227e9f9c2a3ec8464a7ddd90df45d2 (patch)
treedeada0ef5812e1c9a664c0ee76b2972e28f627f1 /clang/lib/Sema/SemaCast.cpp
parent4ba5269f33ffd7252125d831418316e9f9e3b4a6 (diff)
downloadbcm5719-llvm-5b6dda33d1227e9f9c2a3ec8464a7ddd90df45d2.tar.gz
bcm5719-llvm-5b6dda33d1227e9f9c2a3ec8464a7ddd90df45d2.zip
[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 llvm-svn: 360258
Diffstat (limited to 'clang/lib/Sema/SemaCast.cpp')
-rw-r--r--clang/lib/Sema/SemaCast.cpp46
1 files changed, 34 insertions, 12 deletions
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 21a4d107ba2..0958943f9ef 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -2323,19 +2323,41 @@ void CastOperation::checkAddressSpaceCast(QualType SrcType, QualType DestType) {
// In OpenCL only conversions between pointers to objects in overlapping
// addr spaces are allowed. v2.0 s6.5.5 - Generic addr space overlaps
// with any named one, except for constant.
+
+ // Converting the top level pointee addrspace is permitted for compatible
+ // addrspaces (such as 'generic int *' to 'local int *' or vice versa), but
+ // if any of the nested pointee addrspaces differ, we emit a warning
+ // regardless of addrspace compatibility. This makes
+ // local int ** p;
+ // return (generic int **) p;
+ // warn even though local -> generic is permitted.
if (Self.getLangOpts().OpenCL) {
- auto SrcPtrType = SrcType->getAs<PointerType>();
- if (!SrcPtrType)
- return;
- auto DestPtrType = DestType->getAs<PointerType>();
- if (!DestPtrType)
- return;
- if (!DestPtrType->isAddressSpaceOverlapping(*SrcPtrType)) {
- Self.Diag(OpRange.getBegin(),
- diag::err_typecheck_incompatible_address_space)
- << SrcType << DestType << Sema::AA_Casting
- << SrcExpr.get()->getSourceRange();
- SrcExpr = ExprError();
+ const Type *DestPtr, *SrcPtr;
+ bool Nested = false;
+ unsigned DiagID = diag::err_typecheck_incompatible_address_space;
+ DestPtr = Self.getASTContext().getCanonicalType(DestType.getTypePtr()),
+ SrcPtr = Self.getASTContext().getCanonicalType(SrcType.getTypePtr());
+
+ while (isa<PointerType>(DestPtr) && isa<PointerType>(SrcPtr)) {
+ const PointerType *DestPPtr = cast<PointerType>(DestPtr);
+ const PointerType *SrcPPtr = cast<PointerType>(SrcPtr);
+ QualType DestPPointee = DestPPtr->getPointeeType();
+ QualType SrcPPointee = SrcPPtr->getPointeeType();
+ if (Nested ? DestPPointee.getAddressSpace() !=
+ SrcPPointee.getAddressSpace()
+ : !DestPPtr->isAddressSpaceOverlapping(*SrcPPtr)) {
+ Self.Diag(OpRange.getBegin(), DiagID)
+ << SrcType << DestType << Sema::AA_Casting
+ << SrcExpr.get()->getSourceRange();
+ if (!Nested)
+ SrcExpr = ExprError();
+ return;
+ }
+
+ DestPtr = DestPPtr->getPointeeType().getTypePtr();
+ SrcPtr = SrcPPtr->getPointeeType().getTypePtr();
+ Nested = true;
+ DiagID = diag::ext_nested_pointer_qualifier_mismatch;
}
}
}
OpenPOWER on IntegriCloud