]> granicus.if.org Git - clang/commitdiff
[OpenCL 2.0] This change adds extra diagnostics to atomic types
authorAnastasia Stulova <anastasia.stulova@arm.com>
Wed, 30 Sep 2015 13:18:52 +0000 (13:18 +0000)
committerAnastasia Stulova <anastasia.stulova@arm.com>
Wed, 30 Sep 2015 13:18:52 +0000 (13:18 +0000)
Applied restrictions from OpenCL v2.0 s6.13.11.8
that mainly disallow operations on atomic types (except for taking their address - &).

The patch is taken from SPIR2.0 provisional branch, contributed by Guy Benyei!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@248896 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExpr.cpp
test/Parser/opencl-atomics-cl20.cl

index 22bb622f1557d36dca9b90eb8a6480d26ae2955f..455cdfa7f29e7824909bc58fa4aaedcde0a70ca2 100644 (file)
@@ -7480,6 +7480,9 @@ def err_opencl_return_value_with_address_space : Error<
   "return value cannot be qualified with address space">;
 def err_opencl_constant_no_init : Error<
   "variable in constant address space must be initialized">;
+def err_atomic_init_constant : Error<
+  "atomic variable can only be assigned to a compile time constant"
+  " 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">;
 } // end of sema category
index 90f3c7c16a599b85fdd4c8406028987b8ec3a076..c2b3f29332b24ab6ce01cbe2730f95c80944e1b7 100644 (file)
@@ -10276,6 +10276,20 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
       return ExprError();
   }
 
+  if (getLangOpts().OpenCL) {
+    // OpenCLC v2.0 s6.13.11.1 allows atomic variables to be initialized by
+    // the ATOMIC_VAR_INIT macro.
+    if (LHSExpr->getType()->isAtomicType() ||
+        RHSExpr->getType()->isAtomicType()) {
+      SourceRange SR(LHSExpr->getLocStart(), RHSExpr->getLocEnd());
+      if (BO_Assign == Opc)
+        Diag(OpLoc, diag::err_atomic_init_constant) << SR;
+      else
+        ResultTy = InvalidOperands(OpLoc, LHS, RHS);
+      return ExprError();
+    }
+  }
+
   switch (Opc) {
   case BO_Assign:
     ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, QualType());
@@ -10748,6 +10762,14 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
   ExprValueKind VK = VK_RValue;
   ExprObjectKind OK = OK_Ordinary;
   QualType resultType;
+  if (getLangOpts().OpenCL) {
+    // The only legal unary operation for atomics is '&'.
+    if (Opc != UO_AddrOf && InputExpr->getType()->isAtomicType()) {
+      return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
+                       << InputExpr->getType()
+                       << Input.get()->getSourceRange());
+    }
+  }
   switch (Opc) {
   case UO_PreInc:
   case UO_PreDec:
index c62142b2aa6b099d51ca97866f28eee1dec77cba..cb2f59721acc0c33ac8da6aedccb86f79e4d3fb2 100644 (file)
@@ -54,3 +54,16 @@ void atomic_types_test() {
 // expected-error-re@-31 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
 // expected-error-re@-32 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
 #endif
+
+#ifdef CL20
+void foo(atomic_int * ptr) {}
+void atomic_ops_test() {
+  atomic_int i;
+  foo(&i);
+// OpenCL v2.0 s6.13.11.8, arithemtic operations are not permitted on atomic types.
+  i++; // expected-error {{invalid argument type 'atomic_int' (aka '_Atomic(int)') to unary expression}}
+  i = 1; // expected-error {{atomic variable can only be assigned to a compile time constant in the declaration statement in the program scope}}
+  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')}}
+}
+#endif