]> granicus.if.org Git - clang/commitdiff
[OpenCL] Disallow casts between address spaces.
authorJoey Gouly <joey.gouly@gmail.com>
Tue, 14 Jan 2014 12:47:29 +0000 (12:47 +0000)
committerJoey Gouly <joey.gouly@gmail.com>
Tue, 14 Jan 2014 12:47:29 +0000 (12:47 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@199208 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaCast.cpp
test/SemaOpenCL/address-spaces.cl

index 86621255609a6d0baa45c698f43725d980f7c216..ef229cf838be145e0a68de62b4901c353654a7aa 100644 (file)
@@ -2170,6 +2170,21 @@ void CastOperation::CheckCStyleCast() {
 
   assert(!SrcType->isPlaceholderType());
 
+  // OpenCL v1 s6.5: Casting a pointer to address space A to a pointer to
+  // address space B is illegal.
+  if (Self.getLangOpts().OpenCL && DestType->isPointerType() &&
+      SrcType->isPointerType()) {
+    if (DestType->getPointeeType().getAddressSpace() !=
+        SrcType->getPointeeType().getAddressSpace()) {
+      Self.Diag(OpRange.getBegin(),
+                diag::err_typecheck_incompatible_address_space)
+          << SrcType << DestType << Sema::AA_Casting
+          << SrcExpr.get()->getSourceRange();
+      SrcExpr = ExprError();
+      return;
+    }
+  }
+
   if (Self.RequireCompleteType(OpRange.getBegin(), DestType,
                                diag::err_typecheck_cast_to_incomplete)) {
     SrcExpr = ExprError();
index 6ab10b3507f746e4e69ac02986504c8ebb9a08fa..b188ea4576f1f3e08af6fe635360b532237c34b8 100644 (file)
@@ -11,3 +11,29 @@ __kernel void foo(__global int *gip) {
   ip = &li; // expected-error {{assigning '__local int *' to 'int *' changes address space of pointer}}
   ip = &ci; // expected-error {{assigning '__constant int *' to 'int *' changes address space of pointer}}
 }
+
+void explicit_cast(global int* g, local int* l, constant int* c, private int* p)
+{
+  g = (global int*) l;    // expected-error {{casting '__local int *' to type '__global int *' changes address space of pointer}}
+  g = (global int*) c;    // expected-error {{casting '__constant int *' to type '__global int *' changes address space of pointer}}
+  g = (global int*) p;    // expected-error {{casting 'int *' to type '__global int *' changes address space of pointer}}
+
+  l = (local int*) g;     // expected-error {{casting '__global int *' to type '__local int *' changes address space of pointer}}
+  l = (local int*) c;     // expected-error {{casting '__constant int *' to type '__local int *' changes address space of pointer}}
+  l = (local int*) p;     // expected-error {{casting 'int *' to type '__local int *' changes address space of pointer}}
+
+  c = (constant int*) g;  // expected-error {{casting '__global int *' to type '__constant int *' changes address space of pointer}}
+  c = (constant int*) l;  // expected-error {{casting '__local int *' to type '__constant int *' changes address space of pointer}}
+  c = (constant int*) p;  // expected-error {{casting 'int *' to type '__constant int *' changes address space of pointer}}
+
+  p = (private int*) g;   // expected-error {{casting '__global int *' to type 'int *' changes address space of pointer}}
+  p = (private int*) l;   // expected-error {{casting '__local int *' to type 'int *' changes address space of pointer}}
+  p = (private int*) c;   // expected-error {{casting '__constant int *' to type 'int *' changes address space of pointer}}
+}
+
+void ok_explicit_casts(global int *g, global int* g2, local int* l, local int* l2, private int* p, private int* p2)
+{
+  g = (global int*) g2;
+  l = (local int*) l2;
+  p = (private int*) p2;
+}