Hi rsmith,

Clang can currently diagnose the following code:
global int *g = l;    // expected-error {{casting '__local int *' to type 
'__global int *' changes address space of pointer}}

However it does not diagnose:
global int *g = (global int*) l;    // expected-error {{casting '__local int *' 
to type '__global int *' changes address space of pointer}}

The attached patch now errors for this second piece of code. However, I had to 
add code to CheckCStyleCast, I could not figure out if it was possible to get 
it to be diagnosed by Sema::DiagnoseAssignmentResult, which handles the first 
case.

ps: note that the error message shows "__global", when I actually wrote 
"global". I'd like to fix that too at some point!

http://llvm-reviews.chandlerc.com/D2526

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

Index: lib/Sema/SemaCast.cpp
===================================================================
--- lib/Sema/SemaCast.cpp
+++ lib/Sema/SemaCast.cpp
@@ -2170,6 +2170,21 @@
 
   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: test/SemaOpenCL/address-spaces.cl
===================================================================
--- test/SemaOpenCL/address-spaces.cl
+++ test/SemaOpenCL/address-spaces.cl
@@ -11,3 +11,22 @@
   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}}
+}
Index: lib/Sema/SemaCast.cpp
===================================================================
--- lib/Sema/SemaCast.cpp
+++ lib/Sema/SemaCast.cpp
@@ -2170,6 +2170,21 @@
 
   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: test/SemaOpenCL/address-spaces.cl
===================================================================
--- test/SemaOpenCL/address-spaces.cl
+++ test/SemaOpenCL/address-spaces.cl
@@ -11,3 +11,22 @@
   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}}
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to