From fafbf06732746f3ceca21d452d77b144ba8652ae Mon Sep 17 00:00:00 2001
From: Richard Smith
Date: Wed, 11 Apr 2012 17:55:32 +0000
Subject: [PATCH] Provide, and document, a set of __c11_atomic_* intrinsics to
implement C11's header.
In passing, fix LanguageExtensions to note that C11 and C++11 are no longer
"upcoming standards" but are now actually standardized.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154513 91177308-0d34-0410-b5e6-96231b3b80d8
---
docs/LanguageExtensions.html | 100 ++++++++++++++++++++----------
include/clang/Basic/Builtins.def | 17 +++++
lib/AST/ExprConstant.cpp | 3 +-
lib/AST/StmtPrinter.cpp | 22 +++----
lib/CodeGen/CGBuiltin.cpp | 7 ++-
lib/Sema/SemaChecking.cpp | 21 +++++--
test/CodeGen/atomic-ops.c | 36 +++++------
test/CodeGen/atomic_init.c | 4 +-
test/Preprocessor/feature_tests.c | 1 +
test/Sema/atomic-ops.c | 52 ++++++++--------
10 files changed, 165 insertions(+), 98 deletions(-)
diff --git a/docs/LanguageExtensions.html b/docs/LanguageExtensions.html
index 9da30b9c0d..68f0afc1ff 100644
--- a/docs/LanguageExtensions.html
+++ b/docs/LanguageExtensions.html
@@ -34,15 +34,14 @@
Availability attribute
Checks for Standard Language Features
+
+
Checks for Type Traits
Blocks
Objective-C Features
@@ -91,7 +91,7 @@
Automatic reference counting
Enumerations with a fixed underlying type
Interoperability with C++11 lambdas
- Object Literals and Subscripting
+ Object Literals and Subscripting
Function Overloading in C
@@ -707,33 +707,32 @@ linked, as if the weak_import
attribute were added to the decla
Checks for Standard Language Features
-The __has_feature macro can be used to query if certain standard language features are
-enabled. Those features are listed here.
+The __has_feature macro can be used to query if certain standard
+language features are enabled. The __has_extension macro can be used
+to query if language features are available as an extension when compiling for
+a standard which does not provide them. The features which can be tested are
+listed here.
+
+C++98
-C++ exceptions
+The features listed below are part of the C++98 standard. These features are
+enabled by default when compiling C++ code.
+
+C++ exceptions
Use __has_feature(cxx_exceptions) to determine if C++ exceptions have been enabled. For
-example, compiling code with -fexceptions enables C++ exceptions.
+example, compiling code with -fno-exceptions disables C++ exceptions.
-C++ RTTI
+C++ RTTI
Use __has_feature(cxx_rtti) to determine if C++ RTTI has been enabled. For example,
compiling code with -fno-rtti disables the use of RTTI.
-
-Checks for Upcoming Standard Language Features
-
-
-The __has_feature or __has_extension macros can be used
-to query if certain upcoming standard language features are enabled. Those
-features are listed here. Features that are not yet implemented will be
-noted.
-
-C++11
+C++11
-The features listed below are slated for inclusion in the upcoming
-C++11 standard. As a result, all these features are enabled
-with the -std=c++11 option when compiling C++ code.
+The features listed below are part of the C++11 standard. As a result, all
+these features are enabled with the -std=c++11 or -std=gnu++11
+option when compiling C++ code.
C++11 SFINAE includes access control
@@ -922,9 +921,10 @@ for variadic templates is enabled.
C11
-The features listed below are slated for inclusion in the upcoming
-C11 standard. As a result, all these features are enabled
-with the -std=c11 option when compiling C code.
+The features listed below are part of the C11 standard. As a result, all
+these features are enabled with the -std=c11 or -std=gnu11
+option when compiling C code. Additionally, because these features are all
+backward-compatible, they are available as extensions in all language modes.
C11 alignment specifiers
@@ -932,6 +932,14 @@ with the -std=c11 option when compiling C code.
to determine if support for alignment specifiers using _Alignas
is enabled.
+C11 atomic operations
+
+Use __has_feature(c_atomic) or __has_extension(c_atomic)
+to determine if support for atomic types using _Atomic is enabled.
+Clang also provides a set of builtins which can be
+used to implement the <stdatomic.h> operations on _Atomic
+types.
+
C11 generic selections
Use __has_feature(c_generic_selections) or
@@ -1455,6 +1463,32 @@ relying on the platform specific implementation details of
__sync_lock_test_and_set(). The __sync_swap() builtin is a full barrier.
+
+
+
+
+Clang provides a set of builtins which are intended to be used to implement
+C11's <stdatomic.h> header. These builtins provide the semantics
+of the _explicit form of the corresponding C11 operation, and are named
+with a __c11_ prefix. The supported operations are:
+
+
+ - __c11_atomic_init
+ - __c11_atomic_thread_fence
+ - __c11_atomic_signal_fence
+ - __c11_atomic_is_lock_free
+ - __c11_atomic_store
+ - __c11_atomic_load
+ - __c11_atomic_exchange
+ - __c11_atomic_compare_exchange_strong
+ - __c11_atomic_compare_exchange_weak
+ - __c11_atomic_fetch_add
+ - __c11_atomic_fetch_sub
+ - __c11_atomic_fetch_and
+ - __c11_atomic_fetch_or
+ - __c11_atomic_fetch_xor
+
+
Target-Specific Extensions
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index f811316d57..82f0463d8c 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -594,6 +594,23 @@ BUILTIN(__sync_swap_4, "iiD*i.", "tn")
BUILTIN(__sync_swap_8, "LLiLLiD*LLi.", "tn")
BUILTIN(__sync_swap_16, "LLLiLLLiD*LLLi.", "tn")
+// C11 _Atomic operations for .
+BUILTIN(__c11_atomic_load, "v.", "t")
+BUILTIN(__c11_atomic_store, "v.", "t")
+BUILTIN(__c11_atomic_exchange, "v.", "t")
+BUILTIN(__c11_atomic_compare_exchange_strong, "v.", "t")
+BUILTIN(__c11_atomic_compare_exchange_weak, "v.", "t")
+BUILTIN(__c11_atomic_fetch_add, "v.", "t")
+BUILTIN(__c11_atomic_fetch_sub, "v.", "t")
+BUILTIN(__c11_atomic_fetch_and, "v.", "t")
+BUILTIN(__c11_atomic_fetch_or, "v.", "t")
+BUILTIN(__c11_atomic_fetch_xor, "v.", "t")
+BUILTIN(__c11_atomic_thread_fence, "vi", "n")
+BUILTIN(__c11_atomic_signal_fence, "vi", "n")
+BUILTIN(__c11_atomic_init, "v.", "t")
+BUILTIN(__c11_atomic_is_lock_free, "iz", "n")
+
+// FIXME: Convert these to implementing GNU atomic builtins.
BUILTIN(__atomic_load, "v.", "t")
BUILTIN(__atomic_store, "v.", "t")
BUILTIN(__atomic_exchange, "v.", "t")
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 435d94c1d4..ce41308344 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -4365,7 +4365,8 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
return Error(E);
- case Builtin::BI__atomic_is_lock_free: {
+ case Builtin::BI__atomic_is_lock_free:
+ case Builtin::BI__c11_atomic_is_lock_free: {
APSInt SizeVal;
if (!EvaluateInteger(E->getArg(0), SizeVal, Info))
return false;
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index ef5eefb306..651b88b5d3 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -1109,37 +1109,37 @@ void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
const char *Name = 0;
switch (Node->getOp()) {
case AtomicExpr::Init:
- Name = "__atomic_init(";
+ Name = "__c11_atomic_init(";
break;
case AtomicExpr::Load:
- Name = "__atomic_load(";
+ Name = "__c11_atomic_load(";
break;
case AtomicExpr::Store:
- Name = "__atomic_store(";
+ Name = "__c11_atomic_store(";
break;
case AtomicExpr::CmpXchgStrong:
- Name = "__atomic_compare_exchange_strong(";
+ Name = "__c11_atomic_compare_exchange_strong(";
break;
case AtomicExpr::CmpXchgWeak:
- Name = "__atomic_compare_exchange_weak(";
+ Name = "__c11_atomic_compare_exchange_weak(";
break;
case AtomicExpr::Xchg:
- Name = "__atomic_exchange(";
+ Name = "__c11_atomic_exchange(";
break;
case AtomicExpr::Add:
- Name = "__atomic_fetch_add(";
+ Name = "__c11_atomic_fetch_add(";
break;
case AtomicExpr::Sub:
- Name = "__atomic_fetch_sub(";
+ Name = "__c11_atomic_fetch_sub(";
break;
case AtomicExpr::And:
- Name = "__atomic_fetch_and(";
+ Name = "__c11_atomic_fetch_and(";
break;
case AtomicExpr::Or:
- Name = "__atomic_fetch_or(";
+ Name = "__c11_atomic_fetch_or(";
break;
case AtomicExpr::Xor:
- Name = "__atomic_fetch_xor(";
+ Name = "__c11_atomic_fetch_xor(";
break;
}
OS << Name;
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index eb849f6e99..5eab5db94a 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -967,9 +967,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
}
case Builtin::BI__atomic_thread_fence:
- case Builtin::BI__atomic_signal_fence: {
+ case Builtin::BI__atomic_signal_fence:
+ case Builtin::BI__c11_atomic_thread_fence:
+ case Builtin::BI__c11_atomic_signal_fence: {
llvm::SynchronizationScope Scope;
- if (BuiltinID == Builtin::BI__atomic_signal_fence)
+ if (BuiltinID == Builtin::BI__atomic_signal_fence ||
+ BuiltinID == Builtin::BI__c11_atomic_signal_fence)
Scope = llvm::SingleThread;
else
Scope = llvm::CrossThread;
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 74832fd32e..c4ed0b0e52 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -251,28 +251,39 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
case Builtin::BI__sync_swap_16:
return SemaBuiltinAtomicOverloaded(move(TheCallResult));
case Builtin::BI__atomic_load:
+ case Builtin::BI__c11_atomic_load:
return SemaAtomicOpsOverloaded(move(TheCallResult), AtomicExpr::Load);
case Builtin::BI__atomic_store:
+ case Builtin::BI__c11_atomic_store:
return SemaAtomicOpsOverloaded(move(TheCallResult), AtomicExpr::Store);
case Builtin::BI__atomic_init:
+ case Builtin::BI__c11_atomic_init:
return SemaAtomicOpsOverloaded(move(TheCallResult), AtomicExpr::Init);
case Builtin::BI__atomic_exchange:
+ case Builtin::BI__c11_atomic_exchange:
return SemaAtomicOpsOverloaded(move(TheCallResult), AtomicExpr::Xchg);
case Builtin::BI__atomic_compare_exchange_strong:
+ case Builtin::BI__c11_atomic_compare_exchange_strong:
return SemaAtomicOpsOverloaded(move(TheCallResult),
AtomicExpr::CmpXchgStrong);
case Builtin::BI__atomic_compare_exchange_weak:
+ case Builtin::BI__c11_atomic_compare_exchange_weak:
return SemaAtomicOpsOverloaded(move(TheCallResult),
AtomicExpr::CmpXchgWeak);
case Builtin::BI__atomic_fetch_add:
+ case Builtin::BI__c11_atomic_fetch_add:
return SemaAtomicOpsOverloaded(move(TheCallResult), AtomicExpr::Add);
case Builtin::BI__atomic_fetch_sub:
+ case Builtin::BI__c11_atomic_fetch_sub:
return SemaAtomicOpsOverloaded(move(TheCallResult), AtomicExpr::Sub);
case Builtin::BI__atomic_fetch_and:
+ case Builtin::BI__c11_atomic_fetch_and:
return SemaAtomicOpsOverloaded(move(TheCallResult), AtomicExpr::And);
case Builtin::BI__atomic_fetch_or:
+ case Builtin::BI__c11_atomic_fetch_or:
return SemaAtomicOpsOverloaded(move(TheCallResult), AtomicExpr::Or);
case Builtin::BI__atomic_fetch_xor:
+ case Builtin::BI__c11_atomic_fetch_xor:
return SemaAtomicOpsOverloaded(move(TheCallResult), AtomicExpr::Xor);
case Builtin::BI__builtin_annotation:
if (CheckBuiltinAnnotationString(*this, TheCall->getArg(1)))
@@ -510,11 +521,11 @@ Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult, AtomicExpr::AtomicOp Op)
DeclRefExpr *DRE =cast(TheCall->getCallee()->IgnoreParenCasts());
// All these operations take one of the following four forms:
- // T __atomic_load(_Atomic(T)*, int) (loads)
- // T* __atomic_add(_Atomic(T*)*, ptrdiff_t, int) (pointer add/sub)
- // int __atomic_compare_exchange_strong(_Atomic(T)*, T*, T, int, int)
- // (cmpxchg)
- // T __atomic_exchange(_Atomic(T)*, T, int) (everything else)
+ // T __c11_atomic_load(_Atomic(T)*, int) (loads)
+ // T* __c11_atomic_add(_Atomic(T*)*, ptrdiff_t, int) (pointer add/sub)
+ // int __c11_atomic_compare_exchange_strong(_Atomic(T)*, T*, T, int, int)
+ // (cmpxchg)
+ // T __c11_atomic_exchange(_Atomic(T)*, T, int) (everything else)
// where T is an appropriate type, and the int paremeterss are for orderings.
unsigned NumVals = 1;
unsigned NumOrders = 1;
diff --git a/test/CodeGen/atomic-ops.c b/test/CodeGen/atomic-ops.c
index 2285cca723..c94f14023e 100644
--- a/test/CodeGen/atomic-ops.c
+++ b/test/CodeGen/atomic-ops.c
@@ -7,9 +7,9 @@
#ifndef ALREADY_INCLUDED
#define ALREADY_INCLUDED
-// Basic IRGen tests for __atomic_*
+// Basic IRGen tests for __c11_atomic_*
-// FIXME: Need to implement __atomic_is_lock_free
+// FIXME: Need to implement __c11_atomic_is_lock_free
typedef enum memory_order {
memory_order_relaxed, memory_order_consume, memory_order_acquire,
@@ -19,74 +19,74 @@ typedef enum memory_order {
int fi1(_Atomic(int) *i) {
// CHECK: @fi1
// CHECK: load atomic i32* {{.*}} seq_cst
- return __atomic_load(i, memory_order_seq_cst);
+ return __c11_atomic_load(i, memory_order_seq_cst);
}
void fi2(_Atomic(int) *i) {
// CHECK: @fi2
// CHECK: store atomic i32 {{.*}} seq_cst
- __atomic_store(i, 1, memory_order_seq_cst);
+ __c11_atomic_store(i, 1, memory_order_seq_cst);
}
void fi3(_Atomic(int) *i) {
// CHECK: @fi3
// CHECK: atomicrmw and
- __atomic_fetch_and(i, 1, memory_order_seq_cst);
+ __c11_atomic_fetch_and(i, 1, memory_order_seq_cst);
}
void fi4(_Atomic(int) *i) {
// CHECK: @fi4
// CHECK: cmpxchg i32*
int cmp = 0;
- __atomic_compare_exchange_strong(i, &cmp, 1, memory_order_acquire, memory_order_acquire);
+ __c11_atomic_compare_exchange_strong(i, &cmp, 1, memory_order_acquire, memory_order_acquire);
}
float ff1(_Atomic(float) *d) {
// CHECK: @ff1
// CHECK: load atomic i32* {{.*}} monotonic
- return __atomic_load(d, memory_order_relaxed);
+ return __c11_atomic_load(d, memory_order_relaxed);
}
void ff2(_Atomic(float) *d) {
// CHECK: @ff2
// CHECK: store atomic i32 {{.*}} release
- __atomic_store(d, 1, memory_order_release);
+ __c11_atomic_store(d, 1, memory_order_release);
}
float ff3(_Atomic(float) *d) {
- return __atomic_exchange(d, 2, memory_order_seq_cst);
+ return __c11_atomic_exchange(d, 2, memory_order_seq_cst);
}
int* fp1(_Atomic(int*) *p) {
// CHECK: @fp1
// CHECK: load atomic i32* {{.*}} seq_cst
- return __atomic_load(p, memory_order_seq_cst);
+ return __c11_atomic_load(p, memory_order_seq_cst);
}
int* fp2(_Atomic(int*) *p) {
// CHECK: @fp2
// CHECK: store i32 4
// CHECK: atomicrmw add {{.*}} monotonic
- return __atomic_fetch_add(p, 1, memory_order_relaxed);
+ return __c11_atomic_fetch_add(p, 1, memory_order_relaxed);
}
_Complex float fc(_Atomic(_Complex float) *c) {
// CHECK: @fc
// CHECK: atomicrmw xchg i64*
- return __atomic_exchange(c, 2, memory_order_seq_cst);
+ return __c11_atomic_exchange(c, 2, memory_order_seq_cst);
}
typedef struct X { int x; } X;
X fs(_Atomic(X) *c) {
// CHECK: @fs
// CHECK: atomicrmw xchg i32*
- return __atomic_exchange(c, (X){2}, memory_order_seq_cst);
+ return __c11_atomic_exchange(c, (X){2}, memory_order_seq_cst);
}
int lock_free() {
// CHECK: @lock_free
// CHECK: ret i32 1
- return __atomic_is_lock_free(sizeof(_Atomic(int)));
+ return __c11_atomic_is_lock_free(sizeof(_Atomic(int)));
}
// Tests for atomic operations on big values. These should call the functions
@@ -102,18 +102,18 @@ _Atomic(struct foo) bigAtomic;
void structAtomicStore() {
// CHECK: @structAtomicStore
struct foo f = {0};
- __atomic_store(&bigAtomic, f, 5);
+ __c11_atomic_store(&bigAtomic, f, 5);
// CHECK: call void @__atomic_store(i32 512, i8* bitcast (%struct.foo* @bigAtomic to i8*),
}
void structAtomicLoad() {
// CHECK: @structAtomicLoad
- struct foo f = __atomic_load(&bigAtomic, 5);
+ struct foo f = __c11_atomic_load(&bigAtomic, 5);
// CHECK: call void @__atomic_load(i32 512, i8* bitcast (%struct.foo* @bigAtomic to i8*),
}
struct foo structAtomicExchange() {
// CHECK: @structAtomicExchange
struct foo f = {0};
- return __atomic_exchange(&bigAtomic, f, 5);
+ return __c11_atomic_exchange(&bigAtomic, f, 5);
// CHECK: call void @__atomic_exchange(i32 512, i8* bitcast (%struct.foo* @bigAtomic to i8*),
}
int structAtomicCmpExchange() {
@@ -121,7 +121,7 @@ int structAtomicCmpExchange() {
struct foo f = {0};
struct foo g = {0};
g.big[12] = 12;
- return __atomic_compare_exchange_strong(&bigAtomic, &f, g, 5, 5);
+ return __c11_atomic_compare_exchange_strong(&bigAtomic, &f, g, 5, 5);
// CHECK: call zeroext i1 @__atomic_compare_exchange(i32 512, i8* bitcast (%struct.foo* @bigAtomic to i8*),
}
diff --git a/test/CodeGen/atomic_init.c b/test/CodeGen/atomic_init.c
index 243eb602cb..6f773bef48 100644
--- a/test/CodeGen/atomic_init.c
+++ b/test/CodeGen/atomic_init.c
@@ -9,6 +9,6 @@ void foo()
{
_Atomic(int) j = 12; // CHECK: store
// CHECK-NOT: atomic
- __atomic_init(&j, 42); // CHECK: store
- // CHECK-NOT: atomic
+ __c11_atomic_init(&j, 42); // CHECK: store
+ // CHECK-NOT: atomic
}
diff --git a/test/Preprocessor/feature_tests.c b/test/Preprocessor/feature_tests.c
index be9c62d780..b78a2517b1 100644
--- a/test/Preprocessor/feature_tests.c
+++ b/test/Preprocessor/feature_tests.c
@@ -12,6 +12,7 @@
#if !__has_builtin(__builtin_huge_val) || \
!__has_builtin(__builtin_shufflevector) || \
!__has_builtin(__builtin_trap) || \
+ !__has_builtin(__c11_atomic_init) || \
!__has_feature(attribute_analyzer_noreturn) || \
!__has_feature(attribute_overloadable)
#error Clang should have these
diff --git a/test/Sema/atomic-ops.c b/test/Sema/atomic-ops.c
index 51b46bd5d0..0560a747ab 100644
--- a/test/Sema/atomic-ops.c
+++ b/test/Sema/atomic-ops.c
@@ -1,8 +1,8 @@
// RUN: %clang_cc1 %s -verify -fsyntax-only
-// Basic parsing/Sema tests for __atomic_*
+// Basic parsing/Sema tests for __c11_atomic_*
-// FIXME: Need to implement __atomic_is_lock_free
+// FIXME: Need to implement __c11_atomic_is_lock_free
typedef enum memory_order {
memory_order_relaxed, memory_order_consume, memory_order_acquire,
@@ -10,28 +10,28 @@ typedef enum memory_order {
} memory_order;
void f(_Atomic(int) *i, _Atomic(int*) *p, _Atomic(float) *d) {
- __atomic_load(0); // expected-error {{too few arguments to function}}
- __atomic_load(0,0,0); // expected-error {{too many arguments to function}}
- __atomic_store(0,0,0); // expected-error {{first argument to atomic operation}}
- __atomic_store((int*)0,0,0); // expected-error {{first argument to atomic operation}}
-
- __atomic_load(i, memory_order_seq_cst);
- __atomic_load(p, memory_order_seq_cst);
- __atomic_load(d, memory_order_seq_cst);
-
- __atomic_store(i, 1, memory_order_seq_cst);
- __atomic_store(p, 1, memory_order_seq_cst); // expected-warning {{incompatible integer to pointer conversion}}
- (int)__atomic_store(d, 1, memory_order_seq_cst); // expected-error {{operand of type 'void'}}
-
- __atomic_fetch_add(i, 1, memory_order_seq_cst);
- __atomic_fetch_add(p, 1, memory_order_seq_cst);
- __atomic_fetch_add(d, 1, memory_order_seq_cst); // expected-error {{must be a pointer to atomic integer or pointer}}
-
- __atomic_fetch_and(i, 1, memory_order_seq_cst);
- __atomic_fetch_and(p, 1, memory_order_seq_cst); // expected-error {{must be a pointer to atomic integer}}
- __atomic_fetch_and(d, 1, memory_order_seq_cst); // expected-error {{must be a pointer to atomic integer}}
-
- __atomic_compare_exchange_strong(i, 0, 1, memory_order_seq_cst, memory_order_seq_cst);
- __atomic_compare_exchange_strong(p, 0, (int*)1, memory_order_seq_cst, memory_order_seq_cst);
- __atomic_compare_exchange_strong(d, (int*)0, 1, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{incompatible pointer types}}
+ __c11_atomic_load(0); // expected-error {{too few arguments to function}}
+ __c11_atomic_load(0,0,0); // expected-error {{too many arguments to function}}
+ __c11_atomic_store(0,0,0); // expected-error {{first argument to atomic operation}}
+ __c11_atomic_store((int*)0,0,0); // expected-error {{first argument to atomic operation}}
+
+ __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_store(i, 1, memory_order_seq_cst);
+ __c11_atomic_store(p, 1, memory_order_seq_cst); // expected-warning {{incompatible integer to pointer conversion}}
+ (int)__c11_atomic_store(d, 1, memory_order_seq_cst); // expected-error {{operand of type 'void'}}
+
+ __c11_atomic_fetch_add(i, 1, memory_order_seq_cst);
+ __c11_atomic_fetch_add(p, 1, memory_order_seq_cst);
+ __c11_atomic_fetch_add(d, 1, memory_order_seq_cst); // expected-error {{must be a pointer to atomic integer or pointer}}
+
+ __c11_atomic_fetch_and(i, 1, memory_order_seq_cst);
+ __c11_atomic_fetch_and(p, 1, memory_order_seq_cst); // expected-error {{must be a pointer to atomic integer}}
+ __c11_atomic_fetch_and(d, 1, memory_order_seq_cst); // expected-error {{must be a pointer to atomic integer}}
+
+ __c11_atomic_compare_exchange_strong(i, 0, 1, memory_order_seq_cst, memory_order_seq_cst);
+ __c11_atomic_compare_exchange_strong(p, 0, (int*)1, memory_order_seq_cst, memory_order_seq_cst);
+ __c11_atomic_compare_exchange_strong(d, (int*)0, 1, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{incompatible pointer types}}
}
--
2.40.0