[clang] e95ee30 - [SYCL] Prohibit arithmetic operations for incompatible pointers
Alexey Bader via cfe-commits
cfe-commits at lists.llvm.org
Fri May 22 03:43:37 PDT 2020
Author: Alexey Bader
Date: 2020-05-22T13:43:24+03:00
New Revision: e95ee300c0530158d86430fd82ffabd36262e862
URL: https://github.com/llvm/llvm-project/commit/e95ee300c0530158d86430fd82ffabd36262e862
DIFF: https://github.com/llvm/llvm-project/commit/e95ee300c0530158d86430fd82ffabd36262e862.diff
LOG: [SYCL] Prohibit arithmetic operations for incompatible pointers
Summary:
This change enables OpenCL diagnostics for the pointers annotated with
address space attribute SYCL mode.
Move `isAddressSpaceOverlapping` method from PointerType to QualType.
Reviewers: Anastasia, rjmccall
Reviewed By: rjmccall
Subscribers: rjmccall, jeroen.dobbelaere, Fznamznon, yaxunl, ebevhan, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D80317
Added:
clang/test/SemaCXX/address-space-arithmetic.cpp
Modified:
clang/include/clang/AST/Type.h
clang/lib/Sema/SemaCast.cpp
clang/lib/Sema/SemaExpr.cpp
clang/test/Sema/address_spaces.c
Removed:
################################################################################
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 21b14de997cb..ed31dea925f3 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1064,6 +1064,21 @@ class QualType {
/// Return the address space of this type.
inline LangAS getAddressSpace() const;
+ /// Returns true if address space qualifiers overlap with T address space
+ /// qualifiers.
+ /// OpenCL C defines conversion rules for pointers to
diff erent address spaces
+ /// and notion of overlapping address spaces.
+ /// CL1.1 or CL1.2:
+ /// address spaces overlap iff they are they same.
+ /// OpenCL C v2.0 s6.5.5 adds:
+ /// __generic overlaps with any address space except for __constant.
+ bool isAddressSpaceOverlapping(QualType T) const {
+ Qualifiers Q = getQualifiers();
+ Qualifiers TQ = T.getQualifiers();
+ // Address spaces overlap if at least one of them is a superset of another
+ return Q.isAddressSpaceSupersetOf(TQ) || TQ.isAddressSpaceSupersetOf(Q);
+ }
+
/// Returns gc attribute of this type.
inline Qualifiers::GC getObjCGCAttr() const;
@@ -2631,22 +2646,6 @@ class PointerType : public Type, public llvm::FoldingSetNode {
public:
QualType getPointeeType() const { return PointeeType; }
- /// Returns true if address spaces of pointers overlap.
- /// OpenCL v2.0 defines conversion rules for pointers to
diff erent
- /// address spaces (OpenCLC v2.0 s6.5.5) and notion of overlapping
- /// address spaces.
- /// CL1.1 or CL1.2:
- /// address spaces overlap iff they are they same.
- /// CL2.0 adds:
- /// __generic overlaps with any address space except for __constant.
- bool isAddressSpaceOverlapping(const PointerType &other) const {
- Qualifiers thisQuals = PointeeType.getQualifiers();
- Qualifiers otherQuals = other.getPointeeType().getQualifiers();
- // Address spaces overlap if at least one of them is a superset of another
- return thisQuals.isAddressSpaceSupersetOf(otherQuals) ||
- otherQuals.isAddressSpaceSupersetOf(thisQuals);
- }
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index a4fe90f79eb9..fe4fcdd01301 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -2391,7 +2391,7 @@ static TryCastResult TryAddressSpaceCast(Sema &Self, ExprResult &SrcExpr,
return TC_NotApplicable;
auto SrcPointeeType = SrcPtrType->getPointeeType();
auto DestPointeeType = DestPtrType->getPointeeType();
- if (!DestPtrType->isAddressSpaceOverlapping(*SrcPtrType)) {
+ if (!DestPointeeType.isAddressSpaceOverlapping(SrcPointeeType)) {
msg = diag::err_bad_cxx_cast_addr_space_mismatch;
return TC_Failed;
}
@@ -2434,9 +2434,9 @@ void CastOperation::checkAddressSpaceCast(QualType SrcType, QualType DestType) {
const PointerType *SrcPPtr = cast<PointerType>(SrcPtr);
QualType DestPPointee = DestPPtr->getPointeeType();
QualType SrcPPointee = SrcPPtr->getPointeeType();
- if (Nested ? DestPPointee.getAddressSpace() !=
- SrcPPointee.getAddressSpace()
- : !DestPPtr->isAddressSpaceOverlapping(*SrcPPtr)) {
+ if (Nested
+ ? DestPPointee.getAddressSpace() != SrcPPointee.getAddressSpace()
+ : !DestPPointee.isAddressSpaceOverlapping(SrcPPointee)) {
Self.Diag(OpRange.getBegin(), DiagID)
<< SrcType << DestType << Sema::AA_Casting
<< SrcExpr.get()->getSourceRange();
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 93e67ad2940c..261e69b44052 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -10087,10 +10087,8 @@ static bool checkArithmeticBinOpPointerOperands(Sema &S, SourceLocation Loc,
if (isRHSPointer) RHSPointeeTy = RHSExpr->getType()->getPointeeType();
// if both are pointers check if operation is valid wrt address spaces
- if (S.getLangOpts().OpenCL && isLHSPointer && isRHSPointer) {
- const PointerType *lhsPtr = LHSExpr->getType()->castAs<PointerType>();
- const PointerType *rhsPtr = RHSExpr->getType()->castAs<PointerType>();
- if (!lhsPtr->isAddressSpaceOverlapping(*rhsPtr)) {
+ if (isLHSPointer && isRHSPointer) {
+ if (!LHSPointeeTy.isAddressSpaceOverlapping(RHSPointeeTy)) {
S.Diag(Loc,
diag::err_typecheck_op_on_nonoverlapping_address_space_pointers)
<< LHSExpr->getType() << RHSExpr->getType() << 1 /*arithmetic op*/
@@ -11444,8 +11442,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
if (LCanPointeeTy != RCanPointeeTy) {
// Treat NULL constant as a special case in OpenCL.
if (getLangOpts().OpenCL && !LHSIsNull && !RHSIsNull) {
- const PointerType *LHSPtr = LHSType->castAs<PointerType>();
- if (!LHSPtr->isAddressSpaceOverlapping(*RHSType->castAs<PointerType>())) {
+ if (!LCanPointeeTy.isAddressSpaceOverlapping(RCanPointeeTy)) {
Diag(Loc,
diag::err_typecheck_op_on_nonoverlapping_address_space_pointers)
<< LHSType << RHSType << 0 /* comparison */
diff --git a/clang/test/Sema/address_spaces.c b/clang/test/Sema/address_spaces.c
index 5425ef75b64e..6eb93f1625c7 100644
--- a/clang/test/Sema/address_spaces.c
+++ b/clang/test/Sema/address_spaces.c
@@ -74,6 +74,10 @@ char* cmp(_AS1 char *x, _AS2 char *y) {
return x < y ? x : y; // expected-error{{conditional operator with the second and third operands of type ('_AS1 char *' and '_AS2 char *') which are pointers to non-overlapping address spaces}}
}
+char *sub(_AS1 char *x, _AS2 char *y) {
+ return x - y; // expected-error {{arithmetic operation with operands of type ('_AS1 char *' and '_AS2 char *') which are pointers to non-overlapping address spaces}}
+}
+
struct SomeStruct {
int a;
long b;
diff --git a/clang/test/SemaCXX/address-space-arithmetic.cpp b/clang/test/SemaCXX/address-space-arithmetic.cpp
new file mode 100644
index 000000000000..af72bc7624b3
--- /dev/null
+++ b/clang/test/SemaCXX/address-space-arithmetic.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int *foo(__attribute__((opencl_private)) int *p,
+ __attribute__((opencl_local)) int *l) {
+ return p - l; // expected-error {{arithmetic operation with operands of type ('__private int *' and '__local int *') which are pointers to non-overlapping address spaces}}
+}
More information about the cfe-commits
mailing list