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

Add Sema checks for atomics and implicit declaration
This patch is partitioned from http://reviews.llvm.org/D16047

http://reviews.llvm.org/D17438

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaInit.cpp
  test/Parser/opencl-atomics-cl20.cl
  test/SemaOpenCL/invalid-decl.cl

Index: test/SemaOpenCL/invalid-decl.cl
===================================================================
--- /dev/null
+++ test/SemaOpenCL/invalid-decl.cl
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -verify -cl-std=CL2.0 %s
+int; // expected-error {{declaration does not declare anything}}
+
+void test1(){
+  myfun(); // expected-error {{implicit declaration of function 'myfun' is invalid in OpenCL}}
+}
Index: test/Parser/opencl-atomics-cl20.cl
===================================================================
--- test/Parser/opencl-atomics-cl20.cl
+++ test/Parser/opencl-atomics-cl20.cl
@@ -56,6 +56,7 @@
 #endif
 
 #ifdef CL20
+#define ATOMIC_VAR_INIT
 void foo(atomic_int * ptr) {}
 void atomic_ops_test() {
   atomic_int i;
@@ -66,4 +67,7 @@
   i += 1; // expected-error {{invalid operands to binary expression ('atomic_int' (aka '_Atomic(int)') and 'int')}}
   i = i + i; // expected-error {{invalid operands to binary expression ('atomic_int' (aka '_Atomic(int)') and 'atomic_int')}}
 }
+void atomic_init_test() {
+    atomic_int guide = ATOMIC_VAR_INIT(42); // expected-error {{initialization of atomic variables is restricted to variables in global address space in opencl}}
+}
 #endif
Index: lib/Sema/SemaInit.cpp
===================================================================
--- lib/Sema/SemaInit.cpp
+++ lib/Sema/SemaInit.cpp
@@ -6136,6 +6136,32 @@
       << Init->getSourceRange();
   }
 
+  // OpenCL v2.0 s6.13.11.1 - The ATOMIC_VAR_INIT macro expands to a token
+  // sequence suitable for initializing an atomic object of a type that is
+  // initialization-compatible with value. An atomic object with automatic
+  // storage duration that is not explicitly initialized using ATOMIC_VAR_INIT
+  // is initially in an indeterminate state; however, the default (zero)
+  // initialization for objects with static storage duration is guaranteed to
+  // produce a valid state.
+  // #define ATOMIC_VAR_INIT(C value)
+  // This macro can only be used to initialize atomic objects that are declared
+  // in program scope in the global address space.
+  // Examples:
+  // global atomic_int guide = ATOMIC_VAR_INIT(42);
+  if (S.getLangOpts().OpenCL && S.getLangOpts().OpenCLVersion >= 200 &&
+      Entity.getType()->isAtomicType()) {
+    Qualifiers TyQualifiers = Entity.getType().getQualifiers();
+    bool HasGlobalAS = TyQualifiers.hasAddressSpace() &&
+                       TyQualifiers.getAddressSpace() == LangAS::opencl_global;
+    if (!HasGlobalAS && Entity.getKind() == InitializedEntity::EK_Variable &&
+        Args.size() > 0) {
+      Expr *Init = Args[0];
+      S.Diag(Init->getLocStart(), diag::err_opencl_atomic_init_addressspace)
+          << SourceRange(Entity.getDecl()->getLocStart(), Init->getLocEnd());
+      return ExprError();
+    }
+  }
+
   // Diagnose cases where we initialize a pointer to an array temporary, and the
   // pointer obviously outlives the temporary.
   if (Args.size() == 1 && Args[0]->getType()->isArrayType() &&
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -3897,6 +3897,12 @@
   //   names into the program, or shall redeclare a name introduced by a
   //   previous declaration.
   if (!DeclaresAnything) {
+    // OpenCL C doesn't support bit-field, so declaration with no declarator
+    // has no use.
+    if (getLangOpts().OpenCL) {
+      Diag(DS.getLocStart(), diag::err_no_declarators) << DS.getSourceRange();
+      return 0;
+    }
     // In C, we allow this as a (popular) extension / bug. Don't bother
     // producing further diagnostics for redundant qualifiers after this.
     Diag(DS.getLocStart(), diag::ext_no_declarators) << DS.getSourceRange();
@@ -7274,8 +7280,13 @@
     QualType PointeeType = PT->getPointeeType();
     if (PointeeType->isPointerType())
       return PtrPtrKernelParam;
-    return PointeeType.getAddressSpace() == 0 ? PrivatePtrKernelParam
-                                              : PtrKernelParam;
+    // Now generice address space is added, we need to handle like this
+    unsigned addrSpace = PointeeType.getAddressSpace();
+    return (addrSpace != LangAS::opencl_global &&
+            addrSpace != LangAS::opencl_constant &&
+            addrSpace != LangAS::opencl_local)
+               ? PrivatePtrKernelParam
+               : PtrKernelParam;
   }
 
   // TODO: Forbid the other integer types (size_t, ptrdiff_t...) when they can
@@ -7293,6 +7304,9 @@
   if (PT->isHalfType())
     return InvalidKernelParam;
 
+  if (PT->isReserveIDT())
+    return InvalidKernelParam;
+
   if (PT->isRecordType())
     return RecordKernelParam;
 
@@ -11486,6 +11500,10 @@
   unsigned diag_id;
   if (II.getName().startswith("__builtin_"))
     diag_id = diag::warn_builtin_unknown;
+  else if (getLangOpts().OpenCL)
+    // OpenCL function need to be called with prototype, so we don't allow
+    // implicit function declarations in OpenCL
+    diag_id = diag::err_opencl_implicit_function_decl;
   else if (getLangOpts().C99)
     diag_id = diag::ext_implicit_function_decl;
   else
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -602,6 +602,7 @@
 /// parser diagnostics
 def ext_no_declarators : ExtWarn<"declaration does not declare anything">,
   InGroup<MissingDeclarations>;
+def err_no_declarators : Error<"declaration does not declare anything">;
 def ext_typedef_without_a_name : ExtWarn<"typedef requires a name">,
   InGroup<MissingDeclarations>;
 def err_typedef_not_identifier : Error<"typedef name must be an identifier">;
@@ -7713,12 +7714,16 @@
   " in the declaration statement in the program scope">;
 def err_opencl_implicit_vector_conversion : Error<
   "implicit conversions between vector types (%0 and %1) are not permitted">;
+def err_opencl_implicit_function_decl : Error<
+  "implicit declaration of function %0 is invalid in OpenCL">;
 def err_opencl_dereferencing : Error<
   "dereferencing pointer of type %0 is not allowed in OpenCL">;
 def err_opencl_pointer_to_image : Error<
   "pointer to image is invalid in OpenCL">;
 def err_opencl_type_can_only_be_used_as_function_parameter : Error <
   "%0 can only be used as a function parameter">;
+def err_opencl_atomic_init_addressspace : Error<
+  "initialization of atomic variables is restricted to variables in global address space in opencl">;
 def err_opencl_block_proto_variadic : Error<
   "invalid block prototype, variadic arguments are not allowed in opencl">;
 def err_opencl_invalid_block_array : Error<
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to