]> granicus.if.org Git - clang/commitdiff
Provide, and document, a set of __c11_atomic_* intrinsics to implement C11's
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 11 Apr 2012 17:55:32 +0000 (17:55 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 11 Apr 2012 17:55:32 +0000 (17:55 +0000)
<stdatomic.h> 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
include/clang/Basic/Builtins.def
lib/AST/ExprConstant.cpp
lib/AST/StmtPrinter.cpp
lib/CodeGen/CGBuiltin.cpp
lib/Sema/SemaChecking.cpp
test/CodeGen/atomic-ops.c
test/CodeGen/atomic_init.c
test/Preprocessor/feature_tests.c
test/Sema/atomic-ops.c

index 9da30b9c0d91310883d0d1ab8cf20a006847edf4..68f0afc1ffa516d6256248749a741d9d8b7c92a8 100644 (file)
 <li><a href="#availability">Availability attribute</a></li>
 <li><a href="#checking_language_features">Checks for Standard Language Features</a>
   <ul>
-  <li><a href="#cxx_exceptions">C++ exceptions</a></li>
-  <li><a href="#cxx_rtti">C++ RTTI</a></li>
+  <li><a href="#cxx98">C++98</a>
+    <ul>
+    <li><a href="#cxx_exceptions">C++ exceptions</a></li>
+    <li><a href="#cxx_rtti">C++ RTTI</a></li>
   </ul></li>
-<li><a href="#checking_upcoming_features">Checks for Upcoming Standard Language Features</a>
-  <ul>
-  <li><a href="#cxx0x">C++11</a>
+  <li><a href="#cxx11">C++11</a>
     <ul>
-   <li><a href="#cxx_access_control_sfinae">C++11 SFINAE includes
-   access control</a></li>
+    <li><a href="#cxx_access_control_sfinae">C++11 SFINAE includes access control</a></li>
     <li><a href="#cxx_alias_templates">C++11 alias templates</a></li>
     <li><a href="#cxx_alignas">C++11 alignment specifiers</a></li>
     <li><a href="#cxx_attributes">C++11 attributes</a></li>
     <li><a href="#cxx_reference_qualified_functions">C++11 reference-qualified functions</a></li>
     <li><a href="#cxx_static_assert">C++11 <tt>static_assert()</tt></a></li>
     <li><a href="#cxx_auto_type">C++11 type inference</a></li>
-   <li><a href="#cxx_strong_enums">C++11 strongly-typed enumerations</a></li>
+    <li><a href="#cxx_strong_enums">C++11 strongly-typed enumerations</a></li>
     <li><a href="#cxx_trailing_return">C++11 trailing return type</a></li>
     <li><a href="#cxx_unicode_literals">C++11 Unicode string literals</a></li>
     <li><a href="#cxx_unrestricted_unions">C++11 unrestricted unions</a></li>
     <li><a href="#cxx_user_literals">C++11 user-defined literals</a></li>
     <li><a href="#cxx_variadic_templates">C++11 variadic templates</a></li>
-   </ul></li>
+  </ul></li>
   <li><a href="#c11">C11</a>
     <ul>
     <li><a href="#c_alignas">C11 alignment specifiers</a></li>
+    <li><a href="#c_atomic">C11 atomic operations</a></li>
     <li><a href="#c_generic_selections">C11 generic selections</a></li>
     <li><a href="#c_static_assert">C11 <tt>_Static_assert()</tt></a></li>
-    </ul></li>
-  </ul> </li>
+  </ul></li>
+</ul></li>
 <li><a href="#checking_type_traits">Checks for Type Traits</a></li>
 <li><a href="#blocks">Blocks</a></li>
 <li><a href="#objc_features">Objective-C Features</a>
@@ -91,7 +91,7 @@
     <li><a href="#objc_arc">Automatic reference counting</a></li>
     <li><a href="#objc_fixed_enum">Enumerations with a fixed underlying type</a></li>
     <li><a href="#objc_lambdas">Interoperability with C++11 lambdas</a></li>
-    <li><a href="#object-literals-subscripting">Object Literals and Subscripting</a></li>    
+    <li><a href="#object-literals-subscripting">Object Literals and Subscripting</a></li>
   </ul>
 </li>
 <li><a href="#overloading-in-c">Function Overloading in C</a></li>
@@ -707,33 +707,32 @@ linked</a>, as if the <code>weak_import</code> attribute were added to the decla
 <h2 id="checking_language_features">Checks for Standard Language Features</h2>
 <!-- ======================================================================= -->
 
-<p>The <tt>__has_feature</tt> macro can be used to query if certain standard language features are
-enabled.  Those features are listed here.</p>
+<p>The <tt>__has_feature</tt> macro can be used to query if certain standard
+language features are enabled.  The <tt>__has_extension</tt> 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.</p>
+
+<h3 id="cxx98">C++98</h3>
 
-<h3 id="cxx_exceptions">C++ exceptions</h3>
+<p>The features listed below are part of the C++98 standard. These features are
+enabled by default when compiling C++ code.</p>
+
+<h4 id="cxx_exceptions">C++ exceptions</h4>
 
 <p>Use <tt>__has_feature(cxx_exceptions)</tt> to determine if C++ exceptions have been enabled. For
-example, compiling code with <tt>-fexceptions</tt> enables C++ exceptions.</p>
+example, compiling code with <tt>-fno-exceptions</tt> disables C++ exceptions.</p>
 
-<h3 id="cxx_rtti">C++ RTTI</h3>
+<h4 id="cxx_rtti">C++ RTTI</h4>
 
 <p>Use <tt>__has_feature(cxx_rtti)</tt> to determine if C++ RTTI has been enabled. For example,
 compiling code with <tt>-fno-rtti</tt> disables the use of RTTI.</p>
 
-<!-- ======================================================================= -->
-<h2 id="checking_upcoming_features">Checks for Upcoming Standard Language Features</h2>
-<!-- ======================================================================= -->
-
-<p>The <tt>__has_feature</tt> or <tt>__has_extension</tt> 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.</p>
-
-<h3 id="cxx0x">C++11</h3>
+<h3 id="cxx11">C++11</h3>
 
-<p>The features listed below are slated for inclusion in the upcoming
-C++11 standard. As a result, all these features are enabled
-with the <tt>-std=c++11</tt> option when compiling C++ code.</p>
+<p>The features listed below are part of the C++11 standard. As a result, all
+these features are enabled with the <tt>-std=c++11</tt> or <tt>-std=gnu++11</tt>
+option when compiling C++ code.</p>
 
 <h4 id="cxx_access_control_sfinae">C++11 SFINAE includes access control</h4>
 
@@ -922,9 +921,10 @@ for variadic templates is enabled.</p>
 
 <h3 id="c11">C11</h3>
 
-<p>The features listed below are slated for inclusion in the upcoming
-C11 standard. As a result, all these features are enabled
-with the <tt>-std=c11</tt> option when compiling C code.</p>
+<p>The features listed below are part of the C11 standard. As a result, all
+these features are enabled with the <tt>-std=c11</tt> or <tt>-std=gnu11</tt>
+option when compiling C code. Additionally, because these features are all
+backward-compatible, they are available as extensions in all language modes.</p>
 
 <h4 id="c_alignas">C11 alignment specifiers</h4>
 
@@ -932,6 +932,14 @@ with the <tt>-std=c11</tt> option when compiling C code.</p>
 to determine if support for alignment specifiers using <tt>_Alignas</tt>
 is enabled.</p>
 
+<h4 id="c_atomic">C11 atomic operations</h4>
+
+<p>Use <tt>__has_feature(c_atomic)</tt> or <tt>__has_extension(c_atomic)</tt>
+to determine if support for atomic types using <tt>_Atomic</tt> is enabled.
+Clang also provides <a href="#__c11_atomic">a set of builtins</a> which can be
+used to implement the <tt>&lt;stdatomic.h&gt;</tt> operations on _Atomic
+types.</p>
+
 <h4 id="c_generic_selections">C11 generic selections</h4>
 
 <p>Use <tt>__has_feature(c_generic_selections)</tt> 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.
 </p>
 
+<!-- ======================================================================= -->
+<h3><a name="__c11_atomic">__c11_atomic builtins</a></h3>
+<!-- ======================================================================= -->
+
+<p>Clang provides a set of builtins which are intended to be used to implement
+C11's <tt>&lt;stdatomic.h&gt;</tt> header. These builtins provide the semantics
+of the <tt>_explicit</tt> form of the corresponding C11 operation, and are named
+with a <tt>__c11_</tt> prefix. The supported operations are:</p>
+
+<ul>
+  <li><tt>__c11_atomic_init</tt></li>
+  <li><tt>__c11_atomic_thread_fence</tt></li>
+  <li><tt>__c11_atomic_signal_fence</tt></li>
+  <li><tt>__c11_atomic_is_lock_free</tt></li>
+  <li><tt>__c11_atomic_store</tt></li>
+  <li><tt>__c11_atomic_load</tt></li>
+  <li><tt>__c11_atomic_exchange</tt></li>
+  <li><tt>__c11_atomic_compare_exchange_strong</tt></li>
+  <li><tt>__c11_atomic_compare_exchange_weak</tt></li>
+  <li><tt>__c11_atomic_fetch_add</tt></li>
+  <li><tt>__c11_atomic_fetch_sub</tt></li>
+  <li><tt>__c11_atomic_fetch_and</tt></li>
+  <li><tt>__c11_atomic_fetch_or</tt></li>
+  <li><tt>__c11_atomic_fetch_xor</tt></li>
+</ul>
+
 
 <!-- ======================================================================= -->
 <h2 id="targetspecific">Target-Specific Extensions</h2>
index f811316d573eb5e02d02a15deb0e8e86b3e4bc7e..82f0463d8c530c02b9d8a285b358a0b8afa6bedb 100644 (file)
@@ -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 <stdatomic.h>.
+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")
index 435d94c1d47eeb7b19d6cc885199fbca96cef359..ce41308344505014c46d54d04facd3caa94d8087 100644 (file)
@@ -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;
index ef5eefb306cdfc12cdc5c93ccbd2c33e9b5c74b1..651b88b5d32022746b8cd647116c9ec39723e7a6 100644 (file)
@@ -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;
index eb849f6e99c4aa7c7d05f4c31e138cc9d3d6c0d2..5eab5db94a5e30ce7791541d6c0b3f095ef3b01d 100644 (file)
@@ -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;
index 74832fd32edd91977625da48f29b08327a3bf989..c4ed0b0e5293befd0b4cfd1bdb03f398d2832018 100644 (file)
@@ -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<DeclRefExpr>(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;
index 2285cca723524874aaedd95685a995fd56e3afc3..c94f14023ea1f97f1bd52321a75b2b947ce457fb 100644 (file)
@@ -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*), 
 }
 
index 243eb602cb199ac9c7c2d88ab13f96d2e3fa3e54..6f773bef48cdaf88e91e523d88b9e06af1085668 100644 (file)
@@ -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
 }
index be9c62d780849afe8527713da3a74dea6ef3841b..b78a2517b18dfdba168dc86e9463156c05271c0c 100644 (file)
@@ -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
index 51b46bd5d0ea87c2f17623552cf4d068cabff859..0560a747abdb4e709e480095d9d00960312748a5 100644 (file)
@@ -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}}
 }