[PATCH] D47618: __c11_atomic_load's _Atomic can be const
This revision was automatically updated to reflect the committed changes. Closed by commit rL338743: __c11_atomic_loads _Atomic can be const (authored by jfb, committed by ). Herald added a subscriber: llvm-commits. Repository: rL LLVM https://reviews.llvm.org/D47618 Files: cfe/trunk/lib/Sema/SemaChecking.cpp cfe/trunk/test/Sema/atomic-ops.c cfe/trunk/test/SemaOpenCL/atomic-ops.cl Index: cfe/trunk/test/SemaOpenCL/atomic-ops.cl === --- cfe/trunk/test/SemaOpenCL/atomic-ops.cl +++ cfe/trunk/test/SemaOpenCL/atomic-ops.cl @@ -58,7 +58,8 @@ __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_work_group); __opencl_atomic_load(p, memory_order_seq_cst, memory_scope_work_group); __opencl_atomic_load(d, memory_order_seq_cst, memory_scope_work_group); - __opencl_atomic_load(ci, memory_order_seq_cst, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}} + __opencl_atomic_load(ci, memory_order_seq_cst, memory_scope_work_group); + __opencl_atomic_load(i_c, memory_order_seq_cst, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-constant _Atomic type ('__constant atomic_int *' (aka '__constant _Atomic(int) *') invalid)}} __opencl_atomic_store(i, 1, memory_order_seq_cst, memory_scope_work_group); __opencl_atomic_store(p, 1, memory_order_seq_cst, memory_scope_work_group); @@ -94,7 +95,7 @@ __opencl_atomic_init(ci, 0); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}} __opencl_atomic_store(ci, 0, memory_order_release, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}} - __opencl_atomic_load(ci, memory_order_acquire, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}} + __opencl_atomic_load(ci, memory_order_acquire, memory_scope_work_group); __opencl_atomic_init(, 456); __opencl_atomic_init(, (void*)0); // expected-warning{{incompatible pointer to integer conversion passing '__generic void *' to parameter of type 'int'}} Index: cfe/trunk/test/Sema/atomic-ops.c === --- cfe/trunk/test/Sema/atomic-ops.c +++ cfe/trunk/test/Sema/atomic-ops.c @@ -115,7 +115,7 @@ __c11_atomic_load(i, memory_order_seq_cst); __c11_atomic_load(p, memory_order_seq_cst); __c11_atomic_load(d, memory_order_seq_cst); - __c11_atomic_load(ci, memory_order_seq_cst); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}} + __c11_atomic_load(ci, memory_order_seq_cst); int load_n_1 = __atomic_load_n(I, memory_order_relaxed); int *load_n_2 = __atomic_load_n(P, memory_order_relaxed); @@ -222,7 +222,7 @@ __c11_atomic_init(ci, 0); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}} __c11_atomic_store(ci, 0, memory_order_release); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}} - __c11_atomic_load(ci, memory_order_acquire); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}} + __c11_atomic_load(ci, memory_order_acquire); // Ensure the macros behave appropriately. atomic_int n = ATOMIC_VAR_INIT(123); Index: cfe/trunk/lib/Sema/SemaChecking.cpp === --- cfe/trunk/lib/Sema/SemaChecking.cpp +++ cfe/trunk/lib/Sema/SemaChecking.cpp @@ -4347,7 +4347,7 @@ << Ptr->getType() << Ptr->getSourceRange(); return ExprError(); } -if (AtomTy.isConstQualified() || +if ((Form != Load && Form != LoadCopy && AtomTy.isConstQualified()) || AtomTy.getAddressSpace() == LangAS::opencl_constant) { Diag(DRE->getLocStart(), diag::err_atomic_op_needs_non_const_atomic) << (AtomTy.isConstQualified() ? 0 : 1) << Ptr->getType() Index: cfe/trunk/test/SemaOpenCL/atomic-ops.cl === --- cfe/trunk/test/SemaOpenCL/atomic-ops.cl +++ cfe/trunk/test/SemaOpenCL/atomic-ops.cl @@ -58,7 +58,8 @@ __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_work_group); __opencl_atomic_load(p,
[PATCH] D47618: __c11_atomic_load's _Atomic can be const
Anastasia accepted this revision. Anastasia added a comment. This revision is now accepted and ready to land. LGTM from OpenCL side! Thanks! Repository: rC Clang https://reviews.llvm.org/D47618 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47618: __c11_atomic_load's _Atomic can be const
jfb marked an inline comment as done. jfb added a comment. Give the comments, I think this is ready to commit. Repository: rC Clang https://reviews.llvm.org/D47618 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47618: __c11_atomic_load's _Atomic can be const
jfb updated this revision to Diff 157761. jfb added a comment. - Add constant AS pointer test. Repository: rC Clang https://reviews.llvm.org/D47618 Files: lib/Sema/SemaChecking.cpp test/Sema/atomic-ops.c test/SemaOpenCL/atomic-ops.cl Index: test/SemaOpenCL/atomic-ops.cl === --- test/SemaOpenCL/atomic-ops.cl +++ test/SemaOpenCL/atomic-ops.cl @@ -58,7 +58,8 @@ __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_work_group); __opencl_atomic_load(p, memory_order_seq_cst, memory_scope_work_group); __opencl_atomic_load(d, memory_order_seq_cst, memory_scope_work_group); - __opencl_atomic_load(ci, memory_order_seq_cst, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}} + __opencl_atomic_load(ci, memory_order_seq_cst, memory_scope_work_group); + __opencl_atomic_load(i_c, memory_order_seq_cst, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-constant _Atomic type ('__constant atomic_int *' (aka '__constant _Atomic(int) *') invalid)}} __opencl_atomic_store(i, 1, memory_order_seq_cst, memory_scope_work_group); __opencl_atomic_store(p, 1, memory_order_seq_cst, memory_scope_work_group); @@ -94,7 +95,7 @@ __opencl_atomic_init(ci, 0); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}} __opencl_atomic_store(ci, 0, memory_order_release, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}} - __opencl_atomic_load(ci, memory_order_acquire, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}} + __opencl_atomic_load(ci, memory_order_acquire, memory_scope_work_group); __opencl_atomic_init(, 456); __opencl_atomic_init(, (void*)0); // expected-warning{{incompatible pointer to integer conversion passing '__generic void *' to parameter of type 'int'}} Index: test/Sema/atomic-ops.c === --- test/Sema/atomic-ops.c +++ test/Sema/atomic-ops.c @@ -115,7 +115,7 @@ __c11_atomic_load(i, memory_order_seq_cst); __c11_atomic_load(p, memory_order_seq_cst); __c11_atomic_load(d, memory_order_seq_cst); - __c11_atomic_load(ci, memory_order_seq_cst); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}} + __c11_atomic_load(ci, memory_order_seq_cst); int load_n_1 = __atomic_load_n(I, memory_order_relaxed); int *load_n_2 = __atomic_load_n(P, memory_order_relaxed); @@ -222,7 +222,7 @@ __c11_atomic_init(ci, 0); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}} __c11_atomic_store(ci, 0, memory_order_release); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}} - __c11_atomic_load(ci, memory_order_acquire); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}} + __c11_atomic_load(ci, memory_order_acquire); // Ensure the macros behave appropriately. atomic_int n = ATOMIC_VAR_INIT(123); Index: lib/Sema/SemaChecking.cpp === --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -4347,7 +4347,7 @@ << Ptr->getType() << Ptr->getSourceRange(); return ExprError(); } -if (AtomTy.isConstQualified() || +if ((Form != Load && Form != LoadCopy && AtomTy.isConstQualified()) || AtomTy.getAddressSpace() == LangAS::opencl_constant) { Diag(DRE->getLocStart(), diag::err_atomic_op_needs_non_const_atomic) << (AtomTy.isConstQualified() ? 0 : 1) << Ptr->getType() Index: test/SemaOpenCL/atomic-ops.cl === --- test/SemaOpenCL/atomic-ops.cl +++ test/SemaOpenCL/atomic-ops.cl @@ -58,7 +58,8 @@ __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_work_group); __opencl_atomic_load(p, memory_order_seq_cst, memory_scope_work_group); __opencl_atomic_load(d, memory_order_seq_cst, memory_scope_work_group); - __opencl_atomic_load(ci, memory_order_seq_cst, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-const
[PATCH] D47618: __c11_atomic_load's _Atomic can be const
Anastasia added inline comments. Comment at: test/SemaOpenCL/atomic-ops.cl:61 __opencl_atomic_load(d, memory_order_seq_cst, memory_scope_work_group); - __opencl_atomic_load(ci, memory_order_seq_cst, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}} + __opencl_atomic_load(ci, memory_order_seq_cst, memory_scope_work_group); Could we add a line with constant AS pointer: __opencl_atomic_load(i_c, memory_order_seq_cst, memory_scope_work_group); Just to make sure we still give an error for this case. Repository: rC Clang https://reviews.llvm.org/D47618 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47618: __c11_atomic_load's _Atomic can be const
yaxunl added inline comments. Comment at: lib/Sema/SemaChecking.cpp:3368-3374 } else if (Form != Load && Form != LoadCopy) { if (ValType.isConstQualified()) { Diag(DRE->getLocStart(), diag::err_atomic_op_needs_non_const_pointer) << Ptr->getType() << Ptr->getSourceRange(); return ExprError(); } } jfb wrote: > rsmith wrote: > > It would be a little nicer to change this `else if` to a plain `if` and > > conditionalize the diagnostic instead. > > > > Can you track down whoever added the address space check to the C11 atomic > > path and ask them if they really meant for it to not apply to the GNU > > atomic builtins? > It was @yaxunl in https://reviews.llvm.org/D28691 > Nobody asked about GNU atomic builtins with OpenCL in that review. I'll let > @yaxunl chime in. Your change LGTM. Originally the check for constant addr space was introduced to match the check of C11 for const. OpenCL itself does not have this restriction. Repository: rC Clang https://reviews.llvm.org/D47618 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47618: __c11_atomic_load's _Atomic can be const
jfb added a subscriber: yaxunl. jfb added inline comments. Comment at: lib/Sema/SemaChecking.cpp:3361 +if ((Form != Load && Form != LoadCopy && AtomTy.isConstQualified()) || AtomTy.getAddressSpace() == LangAS::opencl_constant) { Diag(DRE->getLocStart(), diag::err_atomic_op_needs_non_const_atomic) rsmith wrote: > We also need to figure out what to do about this -- should an atomic load > from a constant address space be valid? (It seems a little pointless to use > an *atomic* load here, but not obviously wrong.) I think it's mostly harmless except when the address space is actually constant (not C++ constant) because in these cases a wide atomic might need cmpxchg to perform a read, and that will fail writing. Maybe @Anastasia can chime in for OpenCL? Comment at: lib/Sema/SemaChecking.cpp:3368-3374 } else if (Form != Load && Form != LoadCopy) { if (ValType.isConstQualified()) { Diag(DRE->getLocStart(), diag::err_atomic_op_needs_non_const_pointer) << Ptr->getType() << Ptr->getSourceRange(); return ExprError(); } } rsmith wrote: > It would be a little nicer to change this `else if` to a plain `if` and > conditionalize the diagnostic instead. > > Can you track down whoever added the address space check to the C11 atomic > path and ask them if they really meant for it to not apply to the GNU atomic > builtins? It was @yaxunl in https://reviews.llvm.org/D28691 Nobody asked about GNU atomic builtins with OpenCL in that review. I'll let @yaxunl chime in. Repository: rC Clang https://reviews.llvm.org/D47618 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47618: __c11_atomic_load's _Atomic can be const
rsmith added a comment. We need to figure out what should happen in the OpenCL case, but the rest seems fine. Comment at: lib/Sema/SemaChecking.cpp:3360 } -if (AtomTy.isConstQualified() || +if ((Form != Load && Form != LoadCopy && AtomTy.isConstQualified()) || AtomTy.getAddressSpace() == LangAS::opencl_constant) { The `LoadCopy` check is redundant; only the GNU `__atomic_load` builtin has the `LoadCopy` form. But see below, we can avoid this duplicated condition with some refactoring. Comment at: lib/Sema/SemaChecking.cpp:3361 +if ((Form != Load && Form != LoadCopy && AtomTy.isConstQualified()) || AtomTy.getAddressSpace() == LangAS::opencl_constant) { Diag(DRE->getLocStart(), diag::err_atomic_op_needs_non_const_atomic) We also need to figure out what to do about this -- should an atomic load from a constant address space be valid? (It seems a little pointless to use an *atomic* load here, but not obviously wrong.) Comment at: lib/Sema/SemaChecking.cpp:3368-3374 } else if (Form != Load && Form != LoadCopy) { if (ValType.isConstQualified()) { Diag(DRE->getLocStart(), diag::err_atomic_op_needs_non_const_pointer) << Ptr->getType() << Ptr->getSourceRange(); return ExprError(); } } It would be a little nicer to change this `else if` to a plain `if` and conditionalize the diagnostic instead. Can you track down whoever added the address space check to the C11 atomic path and ask them if they really meant for it to not apply to the GNU atomic builtins? Repository: rC Clang https://reviews.llvm.org/D47618 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47618: __c11_atomic_load's _Atomic can be const
jfb added a comment. Note that I don't touch the OpenCL __constant stuff, because the separate address space means this can be actually read-only, which means you can't cmpxchg for very wide reads. Repository: rC Clang https://reviews.llvm.org/D47618 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47618: __c11_atomic_load's _Atomic can be const
jfb created this revision. jfb added a reviewer: rsmith. Herald added a subscriber: cfe-commits. C++11 onwards specs the non-member functions atomic_load and atomic_load_explicit as taking the atomic by const (potentially volatile) pointer. C11, in its infinite wisdom, decided to drop the const, and C17 will fix this with DR459 (the current draft forgot to fix B.16, but that’s not the normative part). clang’s lib/Headers/stdatomic.h implements these as #define to the __c11_* equivalent, which are builtins with custom typecheck. Fix the typecheck. https://reviews.llvm.org/D47613 takes care of the libc++ side. Discussion: http://lists.llvm.org/pipermail/cfe-dev/2018-May/058129.html rdar://problem/27426936 Repository: rC Clang https://reviews.llvm.org/D47618 Files: lib/Sema/SemaChecking.cpp test/Sema/atomic-ops.c test/SemaOpenCL/atomic-ops.cl Index: test/SemaOpenCL/atomic-ops.cl === --- test/SemaOpenCL/atomic-ops.cl +++ test/SemaOpenCL/atomic-ops.cl @@ -58,7 +58,7 @@ __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_work_group); __opencl_atomic_load(p, memory_order_seq_cst, memory_scope_work_group); __opencl_atomic_load(d, memory_order_seq_cst, memory_scope_work_group); - __opencl_atomic_load(ci, memory_order_seq_cst, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}} + __opencl_atomic_load(ci, memory_order_seq_cst, memory_scope_work_group); __opencl_atomic_store(i, 1, memory_order_seq_cst, memory_scope_work_group); __opencl_atomic_store(p, 1, memory_order_seq_cst, memory_scope_work_group); @@ -94,7 +94,7 @@ __opencl_atomic_init(ci, 0); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}} __opencl_atomic_store(ci, 0, memory_order_release, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}} - __opencl_atomic_load(ci, memory_order_acquire, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}} + __opencl_atomic_load(ci, memory_order_acquire, memory_scope_work_group); __opencl_atomic_init(, 456); __opencl_atomic_init(, (void*)0); // expected-warning{{incompatible pointer to integer conversion passing '__generic void *' to parameter of type 'int'}} Index: test/Sema/atomic-ops.c === --- test/Sema/atomic-ops.c +++ test/Sema/atomic-ops.c @@ -115,7 +115,7 @@ __c11_atomic_load(i, memory_order_seq_cst); __c11_atomic_load(p, memory_order_seq_cst); __c11_atomic_load(d, memory_order_seq_cst); - __c11_atomic_load(ci, memory_order_seq_cst); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}} + __c11_atomic_load(ci, memory_order_seq_cst); int load_n_1 = __atomic_load_n(I, memory_order_relaxed); int *load_n_2 = __atomic_load_n(P, memory_order_relaxed); @@ -222,7 +222,7 @@ __c11_atomic_init(ci, 0); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}} __c11_atomic_store(ci, 0, memory_order_release); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}} - __c11_atomic_load(ci, memory_order_acquire); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const _Atomic(int) *' invalid)}} + __c11_atomic_load(ci, memory_order_acquire); // Ensure the macros behave appropriately. atomic_int n = ATOMIC_VAR_INIT(123); Index: lib/Sema/SemaChecking.cpp === --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -3357,7 +3357,7 @@ << Ptr->getType() << Ptr->getSourceRange(); return ExprError(); } -if (AtomTy.isConstQualified() || +if ((Form != Load && Form != LoadCopy && AtomTy.isConstQualified()) || AtomTy.getAddressSpace() == LangAS::opencl_constant) { Diag(DRE->getLocStart(), diag::err_atomic_op_needs_non_const_atomic) << (AtomTy.isConstQualified() ? 0 : 1) << Ptr->getType() Index: test/SemaOpenCL/atomic-ops.cl === --- test/SemaOpenCL/atomic-ops.cl +++ test/SemaOpenCL/atomic-ops.cl @@ -58,7 +58,7 @@