summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Ballman <aaron@aaronballman.com>2019-09-04 21:01:57 +0000
committerAaron Ballman <aaron@aaronballman.com>2019-09-04 21:01:57 +0000
commitc9565ca81a15f7c3a83183427ff16a912d3ff936 (patch)
tree21b1e9c156a45ac8fd8f2ecc923a72efe81e775c
parent1237b45db0016d2546eb5c78c81afb46b12ed400 (diff)
downloadclang-c9565ca81a15f7c3a83183427ff16a912d3ff936.tar.gz
Diagnose _Atomic as a C11 extension.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@370982 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Parse/ParseDecl.cpp5
-rw-r--r--test/Parser/atomic.c59
-rw-r--r--test/SemaCXX/atomic-type.cpp73
-rw-r--r--test/SemaCXX/constant-expression-cxx11.cpp14
4 files changed, 86 insertions, 65 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index d66c539056..068964cbf8 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -3924,6 +3924,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// If the _Atomic keyword is immediately followed by a left parenthesis,
// it is interpreted as a type specifier (with a type name), not as a
// type qualifier.
+ if (!getLangOpts().C11)
+ Diag(Tok, diag::ext_c11_feature) << Tok.getName();
+
if (NextToken().is(tok::l_paren)) {
ParseAtomicSpecifier(DS);
continue;
@@ -5330,6 +5333,8 @@ void Parser::ParseTypeQualifierListOpt(
case tok::kw__Atomic:
if (!AtomicAllowed)
goto DoneWithTypeQuals;
+ if (!getLangOpts().C11)
+ Diag(Tok, diag::ext_c11_feature) << Tok.getName();
isInvalid = DS.SetTypeQual(DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID,
getLangOpts());
break;
diff --git a/test/Parser/atomic.c b/test/Parser/atomic.c
index e435518d85..928a43b330 100644
--- a/test/Parser/atomic.c
+++ b/test/Parser/atomic.c
@@ -1,40 +1,47 @@
// RUN: %clang_cc1 -std=c11 %s -fsyntax-only -verify -pedantic
+// RUN: %clang_cc1 -std=c99 %s -fsyntax-only -verify=expected,ext -pedantic -Wno-typedef-redefinition
-typedef _Atomic(int) atomic_int;
-typedef _Atomic int atomic_int;
-typedef _Atomic _Atomic _Atomic(int) atomic_int; // expected-warning {{duplicate '_Atomic' declaration specifier}}
+typedef _Atomic(int) atomic_int; // ext-warning {{'_Atomic' is a C11 extension}}
+typedef _Atomic int atomic_int; // ext-warning {{'_Atomic' is a C11 extension}}
+typedef _Atomic _Atomic _Atomic(int) atomic_int; // expected-warning {{duplicate '_Atomic' declaration specifier}} \
+ // ext-warning 3 {{'_Atomic' is a C11 extension}}
typedef const int const_int;
typedef const atomic_int const_atomic_int;
-typedef _Atomic const int const_atomic_int;
-typedef const _Atomic int const_atomic_int;
-typedef const _Atomic(int) const_atomic_int;
-typedef const _Atomic(_Atomic int) const_atomic_int; // expected-error {{_Atomic cannot be applied to atomic type '_Atomic(int)'}}
-typedef _Atomic const_int const_atomic_int;
-typedef _Atomic(const_int) const_atomic_int; // expected-error {{_Atomic cannot be applied to qualified type 'const_int' (aka 'const int')}}
-
-typedef int *_Atomic atomic_int_ptr;
-typedef _Atomic(int *) atomic_int_ptr;
-typedef int (*_Atomic atomic_int_ptr);
-
-typedef int _Atomic *int_atomic_ptr;
-typedef _Atomic(int) *int_atomic_ptr;
+typedef _Atomic const int const_atomic_int; // ext-warning {{'_Atomic' is a C11 extension}}
+typedef const _Atomic int const_atomic_int; // ext-warning {{'_Atomic' is a C11 extension}}
+typedef const _Atomic(int) const_atomic_int; // ext-warning {{'_Atomic' is a C11 extension}}
+typedef const _Atomic(_Atomic int) const_atomic_int; // expected-error {{_Atomic cannot be applied to atomic type '_Atomic(int)'}} \
+ // ext-warning 2 {{'_Atomic' is a C11 extension}}
+typedef _Atomic const_int const_atomic_int; // ext-warning {{'_Atomic' is a C11 extension}}
+typedef _Atomic(const_int) const_atomic_int; // expected-error {{_Atomic cannot be applied to qualified type 'const_int' (aka 'const int')}} \
+ // ext-warning {{'_Atomic' is a C11 extension}}
+
+typedef int *_Atomic atomic_int_ptr; // ext-warning {{'_Atomic' is a C11 extension}}
+typedef _Atomic(int *) atomic_int_ptr; // ext-warning {{'_Atomic' is a C11 extension}}
+typedef int (*_Atomic atomic_int_ptr); // ext-warning {{'_Atomic' is a C11 extension}}
+
+typedef int _Atomic *int_atomic_ptr; // ext-warning {{'_Atomic' is a C11 extension}}
+typedef _Atomic(int) *int_atomic_ptr; // ext-warning {{'_Atomic' is a C11 extension}}
typedef int int_fn();
-typedef _Atomic int_fn atomic_int_fn; // expected-error {{_Atomic cannot be applied to function type 'int_fn' (aka 'int ()')}}
-typedef _Atomic int atomic_int_array[3];
-typedef _Atomic atomic_int_array atomic_int_atomic_array; // expected-error {{_Atomic cannot be applied to array type 'atomic_int_array' (aka '_Atomic(int) [3]')}}
+typedef _Atomic int_fn atomic_int_fn; // expected-error {{_Atomic cannot be applied to function type 'int_fn' (aka 'int ()')}} \
+ // ext-warning {{'_Atomic' is a C11 extension}}
+typedef _Atomic int atomic_int_array[3]; // ext-warning {{'_Atomic' is a C11 extension}}
+typedef _Atomic atomic_int_array atomic_int_atomic_array; // expected-error {{_Atomic cannot be applied to array type 'atomic_int_array' (aka '_Atomic(int) [3]')}} \
+ // ext-warning {{'_Atomic' is a C11 extension}}
-_Atomic struct S { int n; }; // expected-warning {{'_Atomic' ignored on this declaration}}
+_Atomic struct S { int n; }; // expected-warning {{'_Atomic' ignored on this declaration}} \
+ // ext-warning {{'_Atomic' is a C11 extension}}
-typedef _Atomic int __attribute__((address_space(1))) atomic_addr_space_int;
-typedef _Atomic(int) __attribute__((address_space(1))) atomic_addr_space_int;
+typedef _Atomic int __attribute__((address_space(1))) atomic_addr_space_int; // ext-warning {{'_Atomic' is a C11 extension}}
+typedef _Atomic(int) __attribute__((address_space(1))) atomic_addr_space_int; // ext-warning {{'_Atomic' is a C11 extension}}
-typedef _Atomic int __attribute__((vector_size(16))) atomic_vector_int;
-typedef _Atomic(int __attribute__((vector_size(16)))) atomic_vector_int;
+typedef _Atomic int __attribute__((vector_size(16))) atomic_vector_int; // ext-warning {{'_Atomic' is a C11 extension}}
+typedef _Atomic(int __attribute__((vector_size(16)))) atomic_vector_int; // ext-warning {{'_Atomic' is a C11 extension}}
struct S
-_Atomic atomic_s_no_missing_semicolon;
+_Atomic atomic_s_no_missing_semicolon; // ext-warning {{'_Atomic' is a C11 extension}}
-int *const _Atomic atomic_return_type();
+int *const _Atomic atomic_return_type(); // ext-warning {{'_Atomic' is a C11 extension}}
diff --git a/test/SemaCXX/atomic-type.cpp b/test/SemaCXX/atomic-type.cpp
index a2b314aacd..1ed321e47b 100644
--- a/test/SemaCXX/atomic-type.cpp
+++ b/test/SemaCXX/atomic-type.cpp
@@ -2,7 +2,7 @@
// RUN: %clang_cc1 -verify -pedantic %s -std=c++11
template<typename T> struct atomic {
- _Atomic(T) value;
+ _Atomic(T) value; // expected-warning {{'_Atomic' is a C11 extension}}
void f() _Atomic; // expected-error {{expected ';' at end of declaration list}}
};
@@ -17,16 +17,16 @@ user<int> u;
// Test overloading behavior of atomics.
struct A { };
-int &ovl1(_Atomic(int));
-int &ovl1(_Atomic int); // ok, redeclaration
-long &ovl1(_Atomic(long));
-float &ovl1(_Atomic(float));
-double &ovl1(_Atomic(A const *const *));
-double &ovl1(A const *const *_Atomic);
-short &ovl1(_Atomic(A **));
+int &ovl1(_Atomic(int)); // expected-warning {{'_Atomic' is a C11 extension}}
+int &ovl1(_Atomic int); // expected-warning {{'_Atomic' is a C11 extension}} // ok, redeclaration
+long &ovl1(_Atomic(long)); // expected-warning {{'_Atomic' is a C11 extension}}
+float &ovl1(_Atomic(float)); // expected-warning {{'_Atomic' is a C11 extension}}
+double &ovl1(_Atomic(A const *const *)); // expected-warning {{'_Atomic' is a C11 extension}}
+double &ovl1(A const *const *_Atomic); // expected-warning {{'_Atomic' is a C11 extension}}
+short &ovl1(_Atomic(A **)); // expected-warning {{'_Atomic' is a C11 extension}}
-void test_overloading(int i, float f, _Atomic(int) ai, _Atomic(float) af,
- long l, _Atomic(long) al, A const *const *acc,
+void test_overloading(int i, float f, _Atomic(int) ai, _Atomic(float) af, // expected-warning 2 {{'_Atomic' is a C11 extension}}
+ long l, _Atomic(long) al, A const *const *acc, // expected-warning {{'_Atomic' is a C11 extension}}
A const ** ac, A **a) {
int& ir1 = ovl1(i);
int& ir2 = ovl1(ai);
@@ -39,23 +39,28 @@ void test_overloading(int i, float f, _Atomic(int) ai, _Atomic(float) af,
short &sr1 = ovl1(a);
}
-typedef int (A::*fp)() _Atomic; // expected-error {{expected ';' after top level declarator}} expected-warning {{does not declare anything}}
+typedef int (A::*fp)() _Atomic; // expected-error {{expected ';' after top level declarator}} expected-warning {{does not declare anything}} \
+ // expected-warning {{'_Atomic' is a C11 extension}}
-typedef _Atomic(int(A::*)) atomic_mem_ptr_to_int;
-typedef int(A::*_Atomic atomic_mem_ptr_to_int);
+typedef _Atomic(int(A::*)) atomic_mem_ptr_to_int; // expected-warning {{'_Atomic' is a C11 extension}}
+typedef int(A::*_Atomic atomic_mem_ptr_to_int); // expected-warning {{'_Atomic' is a C11 extension}}
-typedef _Atomic(int)(A::*mem_ptr_to_atomic_int);
-typedef _Atomic int(A::*mem_ptr_to_atomic_int);
+typedef _Atomic(int)(A::*mem_ptr_to_atomic_int); // expected-warning {{'_Atomic' is a C11 extension}}
+typedef _Atomic int(A::*mem_ptr_to_atomic_int); // expected-warning {{'_Atomic' is a C11 extension}}
-typedef _Atomic(int)&atomic_int_ref;
-typedef _Atomic int &atomic_int_ref;
-typedef _Atomic atomic_int_ref atomic_int_ref; // expected-warning {{'_Atomic' qualifier on reference type 'atomic_int_ref' (aka '_Atomic(int) &') has no effect}}
+typedef _Atomic(int)&atomic_int_ref; // expected-warning {{'_Atomic' is a C11 extension}}
+typedef _Atomic int &atomic_int_ref; // expected-warning {{'_Atomic' is a C11 extension}}
+typedef _Atomic atomic_int_ref atomic_int_ref; // expected-warning {{'_Atomic' qualifier on reference type 'atomic_int_ref' (aka '_Atomic(int) &') has no effect}} \
+ // expected-warning {{'_Atomic' is a C11 extension}}
-typedef int &_Atomic atomic_reference_to_int; // expected-error {{'_Atomic' qualifier may not be applied to a reference}}
-typedef _Atomic(int &) atomic_reference_to_int; // expected-error {{_Atomic cannot be applied to reference type 'int &'}}
+typedef int &_Atomic atomic_reference_to_int; // expected-error {{'_Atomic' qualifier may not be applied to a reference}} \
+ // expected-warning {{'_Atomic' is a C11 extension}}
+typedef _Atomic(int &) atomic_reference_to_int; // expected-error {{_Atomic cannot be applied to reference type 'int &'}} \
+ // expected-warning {{'_Atomic' is a C11 extension}}
struct S {
- _Atomic union { int n; }; // expected-warning {{anonymous union cannot be '_Atomic'}}
+ _Atomic union { int n; }; // expected-warning {{anonymous union cannot be '_Atomic'}} \
+ // expected-warning {{'_Atomic' is a C11 extension}}
};
namespace copy_init {
@@ -63,21 +68,24 @@ namespace copy_init {
X(int);
int n;
};
- _Atomic(X) y = X(0);
- _Atomic(X) z(X(0));
+ _Atomic(X) y = X(0); // expected-warning {{'_Atomic' is a C11 extension}}
+ _Atomic(X) z(X(0)); // expected-warning {{'_Atomic' is a C11 extension}}
void f() { y = X(0); }
- _Atomic(X) e1(0); // expected-error {{cannot initialize}}
+ _Atomic(X) e1(0); // expected-error {{cannot initialize}} \
+ // expected-warning {{'_Atomic' is a C11 extension}}
#if __cplusplus >= 201103L
- _Atomic(X) e2{0}; // expected-error {{illegal initializer}}
- _Atomic(X) a{X(0)};
+ _Atomic(X) e2{0}; // expected-error {{illegal initializer}} \
+ // expected-warning {{'_Atomic' is a C11 extension}}
+ _Atomic(X) a{X(0)}; // expected-warning {{'_Atomic' is a C11 extension}}
// FIXME: This does not seem like the right answer.
- _Atomic(int) e3{0}; // expected-error {{illegal initializer}}
+ _Atomic(int) e3{0}; // expected-error {{illegal initializer}} \
+ // expected-warning {{'_Atomic' is a C11 extension}}
#endif
struct Y {
- _Atomic(X) a;
- _Atomic(int) b;
+ _Atomic(X) a; // expected-warning {{'_Atomic' is a C11 extension}}
+ _Atomic(int) b; // expected-warning {{'_Atomic' is a C11 extension}}
};
Y y1 = { X(0), 4 };
Y y2 = { 0, 4 }; // expected-error {{cannot initialize}}
@@ -87,10 +95,11 @@ namespace copy_init {
// same answer in all these cases:
Y y3 = { X(0), { 4 } }; // expected-error {{illegal initializer type}}
Y y4 = { { X(0) }, 4 };
- _Atomic(int) ai = { 4 }; // expected-error {{illegal initializer type}}
- _Atomic(X) ax = { X(0) };
+ _Atomic(int) ai = { 4 }; // expected-error {{illegal initializer type}} \
+ // expected-warning {{'_Atomic' is a C11 extension}}
+ _Atomic(X) ax = { X(0) }; // expected-warning {{'_Atomic' is a C11 extension}}
}
-bool PR21836(_Atomic(int) *x) {
+bool PR21836(_Atomic(int) *x) { // expected-warning {{'_Atomic' is a C11 extension}}
return *x;
}
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp
index eaac64d21e..bcfb3ac5e9 100644
--- a/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1322,21 +1322,21 @@ namespace ComplexConstexpr {
// _Atomic(T) is exactly like T for the purposes of constant expression
// evaluation..
namespace Atomic {
- constexpr _Atomic int n = 3;
+ constexpr _Atomic int n = 3; // expected-warning {{'_Atomic' is a C11 extension}}
- struct S { _Atomic(double) d; };
+ struct S { _Atomic(double) d; }; // expected-warning {{'_Atomic' is a C11 extension}}
constexpr S s = { 0.5 };
constexpr double d1 = s.d;
constexpr double d2 = n;
- constexpr _Atomic double d3 = n;
+ constexpr _Atomic double d3 = n; // expected-warning {{'_Atomic' is a C11 extension}}
- constexpr _Atomic(int) n2 = d3;
+ constexpr _Atomic(int) n2 = d3; // expected-warning {{'_Atomic' is a C11 extension}}
static_assert(d1 == 0.5, "");
static_assert(d3 == 3.0, "");
namespace PR16056 {
struct TestVar {
- _Atomic(int) value;
+ _Atomic(int) value; // expected-warning {{'_Atomic' is a C11 extension}}
constexpr TestVar(int value) : value(value) {}
};
constexpr TestVar testVar{-1};
@@ -1345,11 +1345,11 @@ namespace Atomic {
namespace PR32034 {
struct A {};
- struct B { _Atomic(A) a; };
+ struct B { _Atomic(A) a; }; // expected-warning {{'_Atomic' is a C11 extension}}
constexpr int n = (B(), B(), 0);
struct C { constexpr C() {} void *self = this; };
- constexpr _Atomic(C) c = C();
+ constexpr _Atomic(C) c = C(); // expected-warning {{'_Atomic' is a C11 extension}}
}
}