summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/lib/Sema/SemaExpr.cpp22
-rw-r--r--clang/test/Parser/opencl-atomics-cl20.cl13
3 files changed, 37 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 6ee019d639f..a00a4db7ffa 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7297,6 +7297,8 @@ 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_assignment : Error <
+ "assigning directly to an atomic object is not allowed">;
} // end of sema category
let CategoryName = "OpenMP Issue" in {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index a793d45da4e..9b0ccc9458a 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -9747,6 +9747,19 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
return ExprError();
}
+ if (getLangOpts().OpenCL) {
+ // OpenCLC v2.0 s6.13.11.8 forbids operations on atomic types.
+ if (LHSExpr->getType()->isAtomicType() ||
+ RHSExpr->getType()->isAtomicType()) {
+ SourceRange SR(LHSExpr->getLocStart(), RHSExpr->getLocEnd());
+ if (Opc == BO_Assign)
+ Diag(OpLoc, diag::err_atomic_assignment) << SR;
+ else
+ ResultTy = InvalidOperands(OpLoc, LHS, RHS);
+ return ExprError();
+ }
+ }
+
switch (Opc) {
case BO_Assign:
ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, QualType());
@@ -10219,6 +10232,15 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
ExprValueKind VK = VK_RValue;
ExprObjectKind OK = OK_Ordinary;
QualType resultType;
+ if (getLangOpts().OpenCL) {
+ // OpenCLC v2.0 s6.13.11.8, 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:
diff --git a/clang/test/Parser/opencl-atomics-cl20.cl b/clang/test/Parser/opencl-atomics-cl20.cl
index c62142b2aa6..9118bd2a040 100644
--- a/clang/test/Parser/opencl-atomics-cl20.cl
+++ b/clang/test/Parser/opencl-atomics-cl20.cl
@@ -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 operation are not permitted on atomic types.
+ i++; // expected-error {{invalid argument type 'atomic_int' (aka '_Atomic(int)') to unary expression}}
+ i = 1; // expected-error {{assigning directly to an atomic object is not allowed}}
+ 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
OpenPOWER on IntegriCloud