Skip to content

Commit b4b1f59

Browse files
committed
__c11_atomic_load's _Atomic can be const
Summary: C++11 onwards specs the non-member functions atomic_load and atomic_load_explicit as taking the atomic<T> 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. D47613 takes care of the libc++ side. Discussion: http://lists.llvm.org/pipermail/cfe-dev/2018-May/058129.html <rdar://problem/27426936> Reviewers: rsmith Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D47618 llvm-svn: 338743
1 parent ae67218 commit b4b1f59

File tree

3 files changed

+6
-5
lines changed

3 files changed

+6
-5
lines changed

clang/lib/Sema/SemaChecking.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4347,7 +4347,7 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,
43474347
<< Ptr->getType() << Ptr->getSourceRange();
43484348
return ExprError();
43494349
}
4350-
if (AtomTy.isConstQualified() ||
4350+
if ((Form != Load && Form != LoadCopy && AtomTy.isConstQualified()) ||
43514351
AtomTy.getAddressSpace() == LangAS::opencl_constant) {
43524352
Diag(DRE->getLocStart(), diag::err_atomic_op_needs_non_const_atomic)
43534353
<< (AtomTy.isConstQualified() ? 0 : 1) << Ptr->getType()

clang/test/Sema/atomic-ops.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ void f(_Atomic(int) *i, const _Atomic(int) *ci,
115115
__c11_atomic_load(i, memory_order_seq_cst);
116116
__c11_atomic_load(p, memory_order_seq_cst);
117117
__c11_atomic_load(d, memory_order_seq_cst);
118-
__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)}}
118+
__c11_atomic_load(ci, memory_order_seq_cst);
119119

120120
int load_n_1 = __atomic_load_n(I, memory_order_relaxed);
121121
int *load_n_2 = __atomic_load_n(P, memory_order_relaxed);
@@ -222,7 +222,7 @@ void f(_Atomic(int) *i, const _Atomic(int) *ci,
222222

223223
__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)}}
224224
__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)}}
225-
__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)}}
225+
__c11_atomic_load(ci, memory_order_acquire);
226226

227227
// Ensure the <stdatomic.h> macros behave appropriately.
228228
atomic_int n = ATOMIC_VAR_INIT(123);

clang/test/SemaOpenCL/atomic-ops.cl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ void f(atomic_int *i, const atomic_int *ci,
5858
__opencl_atomic_load(i, memory_order_seq_cst, memory_scope_work_group);
5959
__opencl_atomic_load(p, memory_order_seq_cst, memory_scope_work_group);
6060
__opencl_atomic_load(d, memory_order_seq_cst, memory_scope_work_group);
61-
__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)}}
61+
__opencl_atomic_load(ci, memory_order_seq_cst, memory_scope_work_group);
62+
__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)}}
6263

6364
__opencl_atomic_store(i, 1, memory_order_seq_cst, memory_scope_work_group);
6465
__opencl_atomic_store(p, 1, memory_order_seq_cst, memory_scope_work_group);
@@ -94,7 +95,7 @@ void f(atomic_int *i, const atomic_int *ci,
9495

9596
__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)}}
9697
__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)}}
97-
__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)}}
98+
__opencl_atomic_load(ci, memory_order_acquire, memory_scope_work_group);
9899

99100
__opencl_atomic_init(&gn, 456);
100101
__opencl_atomic_init(&gn, (void*)0); // expected-warning{{incompatible pointer to integer conversion passing '__generic void *' to parameter of type 'int'}}

0 commit comments

Comments
 (0)