From: Egor Churaev Date: Wed, 5 Apr 2017 12:47:10 +0000 (+0000) Subject: [OpenCL] Extended diagnostics for atomic initialization X-Git-Tag: llvmorg-5.0.0-rc1~8457 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3bccec5da7e553e4291ed5f1ad069fe68cb20a43;p=platform%2Fupstream%2Fllvm.git [OpenCL] Extended diagnostics for atomic initialization Summary: I saw the same changes in the following review: https://reviews.llvm.org/D17438 I don't know in that way I could determine that atomic variable was initialized by macro ATOMIC_VAR_INIT. Anyway I added check that atomic variables can be initialize only in global scope. I think that we can discuss this change. Reviewers: Anastasia, cfe-commits Reviewed By: Anastasia Subscribers: bader, yaxunl Differential Revision: https://reviews.llvm.org/D30643 llvm-svn: 299537 --- diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index cdf0d4680d6f..e593ab9419ad 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -8286,9 +8286,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_atomic_init: Error< + "atomic variable can be %select{assigned|initialized}0 to a variable only " + "in global address space">; def err_opencl_implicit_vector_conversion : Error< "implicit conversions between vector types (%0 and %1) are not permitted">; def err_opencl_invalid_type_array : Error< diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 454bc32d8858..01a7e29e3f00 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -11121,7 +11121,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, if (LHSTy->isAtomicType() || RHSTy->isAtomicType()) { SourceRange SR(LHSExpr->getLocStart(), RHSExpr->getLocEnd()); if (BO_Assign == Opc) - Diag(OpLoc, diag::err_atomic_init_constant) << SR; + Diag(OpLoc, diag::err_opencl_atomic_init) << 0 << SR; else ResultTy = InvalidOperands(OpLoc, LHS, RHS); return ExprError(); diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index a50244e51c0b..b11769bf4289 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -6502,6 +6502,20 @@ InitializationSequence::Perform(Sema &S, << Init->getSourceRange(); } + // OpenCL v2.0 s6.13.11.1. atomic variables can be initialized in global scope + QualType ETy = Entity.getType(); + Qualifiers TyQualifiers = ETy.getQualifiers(); + bool HasGlobalAS = TyQualifiers.hasAddressSpace() && + TyQualifiers.getAddressSpace() == LangAS::opencl_global; + + if (S.getLangOpts().OpenCLVersion >= 200 && + ETy->isAtomicType() && !HasGlobalAS && + Entity.getKind() == InitializedEntity::EK_Variable && Args.size() > 0) { + S.Diag(Args[0]->getLocStart(), diag::err_opencl_atomic_init) << 1 << + SourceRange(Entity.getDecl()->getLocStart(), Args[0]->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() && diff --git a/clang/test/Parser/opencl-atomics-cl20.cl b/clang/test/Parser/opencl-atomics-cl20.cl index 65fb9d9b42a8..ad67db0bab8a 100644 --- a/clang/test/Parser/opencl-atomics-cl20.cl +++ b/clang/test/Parser/opencl-atomics-cl20.cl @@ -67,7 +67,7 @@ void atomic_ops_test() { 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 {{atomic variable can be assigned to a variable only in global address space}} 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')}} } diff --git a/clang/test/SemaOpenCL/atomic-init.cl b/clang/test/SemaOpenCL/atomic-init.cl new file mode 100644 index 000000000000..8208a85c3dab --- /dev/null +++ b/clang/test/SemaOpenCL/atomic-init.cl @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s + +global atomic_int a1 = 0; + +kernel void test_atomic_initialization() { + a1 = 1; // expected-error {{atomic variable can be assigned to a variable only in global address space}} + atomic_int a2 = 0; // expected-error {{atomic variable can be initialized to a variable only in global address space}} + private atomic_int a3 = 0; // expected-error {{atomic variable can be initialized to a variable only in global address space}} + local atomic_int a4 = 0; // expected-error {{'__local' variable cannot have an initializer}} + global atomic_int a5 = 0; // expected-error {{function scope variable cannot be declared in global address space}} + static global atomic_int a6 = 0; +}