From: Alex Lorenz Date: Wed, 23 Nov 2016 16:57:03 +0000 (+0000) Subject: [Sema][Atomics] Treat expected pointer in compare exchange atomics as _Nonnull X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=017ae22a5cb136fd1668e5586bfef535d0e51e2f;p=clang [Sema][Atomics] Treat expected pointer in compare exchange atomics as _Nonnull This commit teaches clang that is has to emit a warning when NULL is passed as the 'expected' pointer parameter into an atomic compare exchange call. rdar://18926650 Differential Revision: https://reviews.llvm.org/D26978 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@287776 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 843ff43bdb..4fe30536fd 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -2868,6 +2868,9 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult, Ty = Context.getPointerDiffType(); else { Expr *ValArg = TheCall->getArg(i); + // Treat this argument as _Nonnull as we want to show a warning if + // NULL is passed into it. + CheckNonNullArgument(*this, ValArg, DRE->getLocStart()); unsigned AS = 0; // Keep address space of non-atomic pointer type. if (const PointerType *PtrTy = diff --git a/test/Sema/atomic-ops.c b/test/Sema/atomic-ops.c index 0583621424..8ebf3eaed4 100644 --- a/test/Sema/atomic-ops.c +++ b/test/Sema/atomic-ops.c @@ -174,14 +174,14 @@ void f(_Atomic(int) *i, const _Atomic(int) *ci, __atomic_fetch_or(D, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer}} __atomic_fetch_and(s1, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer}} - _Bool cmpexch_1 = __c11_atomic_compare_exchange_strong(i, 0, 1, memory_order_seq_cst, memory_order_seq_cst); - _Bool cmpexch_2 = __c11_atomic_compare_exchange_strong(p, 0, (int*)1, memory_order_seq_cst, memory_order_seq_cst); - _Bool cmpexch_3 = __c11_atomic_compare_exchange_strong(d, (int*)0, 1, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{incompatible pointer types}} + _Bool cmpexch_1 = __c11_atomic_compare_exchange_strong(i, I, 1, memory_order_seq_cst, memory_order_seq_cst); + _Bool cmpexch_2 = __c11_atomic_compare_exchange_strong(p, P, (int*)1, memory_order_seq_cst, memory_order_seq_cst); + _Bool cmpexch_3 = __c11_atomic_compare_exchange_strong(d, I, 1, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{incompatible pointer types}} (void)__c11_atomic_compare_exchange_strong(i, CI, 1, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{passing 'const int *' to parameter of type 'int *' discards qualifiers}} - _Bool cmpexchw_1 = __c11_atomic_compare_exchange_weak(i, 0, 1, memory_order_seq_cst, memory_order_seq_cst); - _Bool cmpexchw_2 = __c11_atomic_compare_exchange_weak(p, 0, (int*)1, memory_order_seq_cst, memory_order_seq_cst); - _Bool cmpexchw_3 = __c11_atomic_compare_exchange_weak(d, (int*)0, 1, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{incompatible pointer types}} + _Bool cmpexchw_1 = __c11_atomic_compare_exchange_weak(i, I, 1, memory_order_seq_cst, memory_order_seq_cst); + _Bool cmpexchw_2 = __c11_atomic_compare_exchange_weak(p, P, (int*)1, memory_order_seq_cst, memory_order_seq_cst); + _Bool cmpexchw_3 = __c11_atomic_compare_exchange_weak(d, I, 1, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{incompatible pointer types}} (void)__c11_atomic_compare_exchange_weak(i, CI, 1, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{passing 'const int *' to parameter of type 'int *' discards qualifiers}} _Bool cmpexch_4 = __atomic_compare_exchange_n(I, I, 5, 1, memory_order_seq_cst, memory_order_seq_cst); @@ -503,4 +503,9 @@ void memory_checks(_Atomic(int) *Ap, int *p, int val) { (void)__atomic_compare_exchange_n(p, p, val, 0, memory_order_seq_cst, memory_order_relaxed); } - +void nullPointerWarning(_Atomic(int) *Ap, int *p, int val) { + // The 'expected' pointer shouldn't be NULL. + (void)__c11_atomic_compare_exchange_strong(Ap, NULL, val, memory_order_relaxed, memory_order_relaxed); // expected-warning {{null passed to a callee that requires a non-null argument}} + (void)atomic_compare_exchange_weak(Ap, ((void*)0), val); // expected-warning {{null passed to a callee that requires a non-null argument}} + (void)__atomic_compare_exchange_n(p, NULL, val, 0, memory_order_relaxed, memory_order_relaxed); // expected-warning {{null passed to a callee that requires a non-null argument}} +}