From 41c69f0bb0f301c3a409c5585881f0241495aa6f Mon Sep 17 00:00:00 2001 From: Anastasia Stulova Date: Wed, 11 Mar 2015 16:23:10 +0000 Subject: [PATCH] OpenCL: CL2.0 atomic type diagnostics Added restictions for atomic type usage from OpenCL C Spec Section 6.13.11.8 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@231935 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ lib/Sema/SemaExpr.cpp | 22 ++++++++++++++++++++++ test/Parser/opencl-atomics-cl20.cl | 13 +++++++++++++ 3 files changed, 37 insertions(+) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 6ee019d639..a00a4db7ff 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/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/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index a793d45da4..9b0ccc9458 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/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/test/Parser/opencl-atomics-cl20.cl b/test/Parser/opencl-atomics-cl20.cl index c62142b2aa..9118bd2a04 100644 --- a/test/Parser/opencl-atomics-cl20.cl +++ b/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 -- 2.40.0