diff options
author | Anastasia Stulova <anastasia.stulova@arm.com> | 2014-11-26 15:36:41 +0000 |
---|---|---|
committer | Anastasia Stulova <anastasia.stulova@arm.com> | 2014-11-26 15:36:41 +0000 |
commit | 77ebcbe8edcf3f5190a27a778c8aecaeb68b209e (patch) | |
tree | 702a70444dff7c499b2ecbabb8e24a88eb6814f9 /lib/Sema/SemaExpr.cpp | |
parent | 7893925065a7e6e9478f878e882c2dd1e8093e20 (diff) |
[OpenCL] Implemented restrictions for pointer conversions specified in OpenCL v2.0.
OpenCL v2.0 s6.5.5 restricts conversion of pointers to different address spaces:
- the named address spaces (__global, __local, and __private) => __generic - implicitly converted;
- __generic => named - with an explicit cast;
- named <=> named - disallowed;
- __constant <=> any other - disallowed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@222834 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index ae299c3c98..76e3612327 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -6256,7 +6256,7 @@ checkPointerTypesForAssignment(Sema &S, QualType LHSType, QualType RHSType) { if (!lhq.compatiblyIncludes(rhq)) { // Treat address-space mismatches as fatal. TODO: address subspaces - if (lhq.getAddressSpace() != rhq.getAddressSpace()) + if (!lhq.isAddressSpaceSupersetOf(rhq)) ConvTy = Sema::IncompatiblePointerDiscardsQualifiers; // It's okay to add or remove GC or lifetime qualifiers when converting to @@ -6541,7 +6541,9 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, if (const PointerType *LHSPointer = dyn_cast<PointerType>(LHSType)) { // U* -> T* if (isa<PointerType>(RHSType)) { - Kind = CK_BitCast; + unsigned AddrSpaceL = LHSPointer->getPointeeType().getAddressSpace(); + unsigned AddrSpaceR = RHSType->getPointeeType().getAddressSpace(); + Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion : CK_BitCast; return checkPointerTypesForAssignment(*this, LHSType, RHSType); } @@ -7224,6 +7226,19 @@ static bool checkArithmeticBinOpPointerOperands(Sema &S, SourceLocation Loc, if (isLHSPointer) LHSPointeeTy = LHSExpr->getType()->getPointeeType(); if (isRHSPointer) RHSPointeeTy = RHSExpr->getType()->getPointeeType(); + // if both are pointers check if operation is valid wrt address spaces + if (isLHSPointer && isRHSPointer) { + const PointerType *lhsPtr = LHSExpr->getType()->getAs<PointerType>(); + const PointerType *rhsPtr = RHSExpr->getType()->getAs<PointerType>(); + if (!lhsPtr->isAddressSpaceOverlapping(*rhsPtr)) { + S.Diag(Loc, + diag::err_typecheck_op_on_nonoverlapping_address_space_pointers) + << LHSExpr->getType() << RHSExpr->getType() << 1 /*arithmetic op*/ + << LHSExpr->getSourceRange() << RHSExpr->getSourceRange(); + return false; + } + } + // Check for arithmetic on pointers to incomplete types. bool isLHSVoidPtr = isLHSPointer && LHSPointeeTy->isVoidType(); bool isRHSVoidPtr = isRHSPointer && RHSPointeeTy->isVoidType(); @@ -8152,6 +8167,13 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, diagnoseDistinctPointerComparison(*this, Loc, LHS, RHS, /*isError*/false); } if (LCanPointeeTy != RCanPointeeTy) { + const PointerType *lhsPtr = LHSType->getAs<PointerType>(); + if (!lhsPtr->isAddressSpaceOverlapping(*RHSType->getAs<PointerType>())) { + Diag(Loc, + diag::err_typecheck_op_on_nonoverlapping_address_space_pointers) + << LHSType << RHSType << 0 /* comparison */ + << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); + } unsigned AddrSpaceL = LCanPointeeTy.getAddressSpace(); unsigned AddrSpaceR = RCanPointeeTy.getAddressSpace(); CastKind Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion |