Anastasia created this revision.
Anastasia added reviewers: pekka.jaaskelainen, yaxunl.
Anastasia added a subscriber: cfe-commits.

Programs scope pointers should point to objects in constant AS or for OpenCL 
2.0 in global AS.

http://reviews.llvm.org/D17343

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaDecl.cpp
  test/CodeGenOpenCL/address-spaces.cl
  test/SemaOpenCL/storageclass-cl20.cl
  test/SemaOpenCL/storageclass.cl

Index: test/SemaOpenCL/storageclass.cl
===================================================================
--- test/SemaOpenCL/storageclass.cl
+++ test/SemaOpenCL/storageclass.cl
@@ -5,6 +5,13 @@
 int G3 = 0;        // expected-error{{program scope variable must reside in constant address space}}
 global int G4 = 0; // expected-error{{program scope variable must reside in constant address space}}
 
+int *constant GP1 = 0;           // expected-error{{program scope pointer must point to constant address space}}
+int *constant *constant GP2 = 0; // expected-error{{program scope pointer must point to constant address space}}
+int **constant GP3 = 0;          // expected-error{{program scope pointer must point to constant address space}}
+constant int **constant GP4 = 0; // expected-error{{program scope pointer must point to constant address space}}
+global int *constant GP5 = 0;    // expected-error{{program scope pointer must point to constant address space}}
+constant int *constant GP6 = 0;
+
 void kernel foo() {
   // static is not allowed at local scope before CL2.0
   static int S1 = 5;          // expected-error{{variables in function scope cannot be declared static}}
Index: test/SemaOpenCL/storageclass-cl20.cl
===================================================================
--- test/SemaOpenCL/storageclass-cl20.cl
+++ test/SemaOpenCL/storageclass-cl20.cl
@@ -3,12 +3,16 @@
 static constant int G1 = 0;
 int G2 = 0;
 global int G3 = 0;
-local int G4 = 0;// expected-error{{program scope variable must reside in global or constant address space}}
+local int G4 = 0;              // expected-error{{program scope variable must reside in global or constant address space}}
+global int **constant GP5 = 0; // expected-error{{program scope pointer must point to global or constant address space}}
+global int *global GP6 = 0;
 
 void kernel foo() {
   static int S1 = 5;
   static global int S2 = 5;
-  static private int S3 = 5;// expected-error{{program scope variable must reside in global or constant address space}}
+  static private int S3 = 5;   // expected-error{{program scope variable must reside in global or constant address space}}
+  static local int *global S4; // expected-error{{program scope pointer must point to global or constant address space}}
+  static constant int *global S5;
 
   constant int L1 = 0;
   local int L2;
Index: test/CodeGenOpenCL/address-spaces.cl
===================================================================
--- test/CodeGenOpenCL/address-spaces.cl
+++ test/CodeGenOpenCL/address-spaces.cl
@@ -28,8 +28,8 @@
 #ifdef CL20
 int i;
 // CL20-DAG: @i = common addrspace(1) global i32 0
-int *ptr;
-// CL20-DAG: @ptr = common addrspace(1) global i32 addrspace(4)* null
+global int *ptr;
+// CL20-DAG: @ptr = common addrspace(1) global i32 addrspace(1)* null
 #endif
 
 // CHECK: i32* %arg
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -6600,37 +6600,34 @@
     // OpenCL v2.0 s6.5.1 - Variables defined at program scope and static
     // variables inside a function can also be declared in the global
     // address space.
-    if (NewVD->isFileVarDecl()) {
-      if (!T->isSamplerT() &&
-          !(T.getAddressSpace() == LangAS::opencl_constant ||
-            (T.getAddressSpace() == LangAS::opencl_global &&
-             getLangOpts().OpenCLVersion == 200))) {
-        if (getLangOpts().OpenCLVersion == 200)
-          Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space)
-              << "global or constant";
-        else
-          Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space)
-              << "constant";
-        NewVD->setInvalidDecl();
-        return;
-      }
+    if (NewVD->isFileVarDecl() || NewVD->isStaticLocal()) {
+      // Program scope pointers can only point to data at the constant or global
+       // address space.
+      const PointerType *PT = nullptr;
+      bool IsPointerDecl = false;
+      do {
+        if (!T->isSamplerT() &&
+            !(T.getAddressSpace() == LangAS::opencl_constant ||
+              (T.getAddressSpace() == LangAS::opencl_global &&
+               getLangOpts().OpenCLVersion == 200))) {
+          if (getLangOpts().OpenCLVersion == 200)
+            Diag(NewVD->getLocation(),
+                 diag::err_opencl_global_invalid_addr_space)
+                << IsPointerDecl << "global or constant";
+          else
+            Diag(NewVD->getLocation(),
+                 diag::err_opencl_global_invalid_addr_space)
+                << IsPointerDecl << "constant";
+          NewVD->setInvalidDecl();
+          return;
+        }
+        PT = dyn_cast<const PointerType>(T.getTypePtr());
+        if (PT) {
+          T = PT->getPointeeType();
+          IsPointerDecl = true;
+        }
+      } while (PT);
     } else {
-      // OpenCL v2.0 s6.5.1 - Variables defined at program scope and static
-      // variables inside a function can also be declared in the global
-      // address space.
-      if (NewVD->isStaticLocal() &&
-          !(T.getAddressSpace() == LangAS::opencl_constant ||
-            (T.getAddressSpace() == LangAS::opencl_global &&
-             getLangOpts().OpenCLVersion == 200))) {
-        if (getLangOpts().OpenCLVersion == 200)
-          Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space)
-              << "global or constant";
-        else
-          Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space)
-              << "constant";
-        NewVD->setInvalidDecl();
-        return;
-      }
       // OpenCL v1.1 s6.5.2 and s6.5.3 no local or constant variables
       // in functions.
       if (T.getAddressSpace() == LangAS::opencl_constant ||
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -7678,7 +7678,7 @@
 def err_wrong_sampler_addressspace: Error<
   "sampler type cannot be used with the __local and __global address space qualifiers">;
 def err_opencl_global_invalid_addr_space : Error<
-  "program scope variable must reside in %0 address space">;
+  "program scope %select{variable|pointer}0 must %select{reside in|point to}0 %1 address space">;
 def err_missing_actual_pipe_type : Error<
   "missing actual type specifier for pipe">;
 def err_reference_pipe_type : Error <
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to