Skip to content

Commit 8e5aa53

Browse files
authored
[C2y] Add test coverage for N3298 (#112033)
This paper adds 'i' and 'j' as suffixes for forming a _Complex constant. This feature has been supported in Clang since at least Clang 3.0, so only test coverage is needed. It does remove -Wgnu-imaginary-constant in C mode (still used in C++ mode) because the feature is now a C2y feature rather than a GNU one.
1 parent 09fa2f0 commit 8e5aa53

File tree

7 files changed

+127
-18
lines changed

7 files changed

+127
-18
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,12 @@ def ext_designated_init_brace_elision : ExtWarn<
250250
// Declarations.
251251
def ext_plain_complex : ExtWarn<
252252
"plain '_Complex' requires a type specifier; assuming '_Complex double'">;
253-
def ext_imaginary_constant : Extension<
253+
def warn_c23_compat_imaginary_constant : Warning<
254+
"imaginary constants are incompatible with C standards before C2y">,
255+
DefaultIgnore, InGroup<CPre2yCompat>;
256+
def ext_c2y_imaginary_constant : Extension<
257+
"imaginary constants are a C2y extension">, InGroup<C2y>;
258+
def ext_gnu_imaginary_constant : Extension<
254259
"imaginary constants are a GNU extension">, InGroup<GNUImaginaryConstant>;
255260
def ext_integer_complex : Extension<
256261
"complex integer types are a GNU extension">, InGroup<GNUComplexInteger>;

clang/lib/Sema/SemaExpr.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4096,7 +4096,15 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
40964096
Res = new (Context) ImaginaryLiteral(Res,
40974097
Context.getComplexType(Res->getType()));
40984098

4099-
Diag(Tok.getLocation(), diag::ext_imaginary_constant);
4099+
// In C++, this is a GNU extension. In C, it's a C2y extension.
4100+
unsigned DiagId;
4101+
if (getLangOpts().CPlusPlus)
4102+
DiagId = diag::ext_gnu_imaginary_constant;
4103+
else if (getLangOpts().C2y)
4104+
DiagId = diag::warn_c23_compat_imaginary_constant;
4105+
else
4106+
DiagId = diag::ext_c2y_imaginary_constant;
4107+
Diag(Tok.getLocation(), DiagId);
41004108
}
41014109
return Res;
41024110
}

clang/test/C/C2y/n3298.c

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// RUN: %clang_cc1 -verify=ped -std=c23 -Wall -pedantic %s
2+
// RUN: %clang_cc1 -verify=yay -std=c2y -Wall -pedantic %s
3+
// RUN: %clang_cc1 -verify=pre -std=c2y -Wpre-c2y-compat -Wall -pedantic %s
4+
// RUN: %clang_cc1 -verify=gnu -Wall -Wgnu -x c++ %s
5+
// RUN: %clang_cc1 -verify=yay -Wall -Wgnu -Wno-gnu-imaginary-constant -x c++ %s
6+
7+
8+
/* WG14 N3298: Yes
9+
* Introduce complex literals v. 2
10+
*
11+
* This introduces two suffixes for making complex literals: i and j (and I and
12+
* J), which can be combined in any order with the other floating literal
13+
* suffixes.
14+
*
15+
* We support these suffixes in older language modes as a conforming extension.
16+
* It used to be a GNU extension, but now it's a C2y extension.
17+
*/
18+
19+
// yay-no-diagnostics
20+
21+
static_assert(_Generic(12.0i, _Complex double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
22+
ped-warning {{imaginary constants are a C2y extension}}
23+
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
24+
*/
25+
static_assert(_Generic(12.0fi, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
26+
ped-warning {{imaginary constants are a C2y extension}}
27+
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
28+
*/
29+
static_assert(_Generic(12.0li, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
30+
ped-warning {{imaginary constants are a C2y extension}}
31+
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
32+
*/
33+
static_assert(_Generic(12.0if, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
34+
ped-warning {{imaginary constants are a C2y extension}}
35+
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
36+
*/
37+
static_assert(_Generic(12.0il, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
38+
ped-warning {{imaginary constants are a C2y extension}}
39+
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
40+
*/
41+
42+
static_assert(_Generic(12.0I, _Complex double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
43+
ped-warning {{imaginary constants are a C2y extension}}
44+
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
45+
*/
46+
static_assert(_Generic(12.0fI, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
47+
ped-warning {{imaginary constants are a C2y extension}}
48+
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
49+
*/
50+
static_assert(_Generic(12.0lI, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
51+
ped-warning {{imaginary constants are a C2y extension}}
52+
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
53+
*/
54+
static_assert(_Generic(12.0If, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
55+
ped-warning {{imaginary constants are a C2y extension}}
56+
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
57+
*/
58+
static_assert(_Generic(12.0Il, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
59+
ped-warning {{imaginary constants are a C2y extension}}
60+
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
61+
*/
62+
63+
static_assert(_Generic(12.0j, _Complex double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
64+
ped-warning {{imaginary constants are a C2y extension}}
65+
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
66+
*/
67+
static_assert(_Generic(12.0fj, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
68+
ped-warning {{imaginary constants are a C2y extension}}
69+
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
70+
*/
71+
static_assert(_Generic(12.0lj, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
72+
ped-warning {{imaginary constants are a C2y extension}}
73+
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
74+
*/
75+
static_assert(_Generic(12.0jf, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
76+
ped-warning {{imaginary constants are a C2y extension}}
77+
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
78+
*/
79+
static_assert(_Generic(12.0jl, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
80+
ped-warning {{imaginary constants are a C2y extension}}
81+
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
82+
*/
83+
84+
static_assert(_Generic(12.0J, _Complex double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
85+
ped-warning {{imaginary constants are a C2y extension}}
86+
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
87+
*/
88+
static_assert(_Generic(12.0fJ, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
89+
ped-warning {{imaginary constants are a C2y extension}}
90+
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
91+
*/
92+
static_assert(_Generic(12.0lJ, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
93+
ped-warning {{imaginary constants are a C2y extension}}
94+
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
95+
*/
96+
static_assert(_Generic(12.0Jf, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
97+
ped-warning {{imaginary constants are a C2y extension}}
98+
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
99+
*/
100+
static_assert(_Generic(12.0Jl, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
101+
ped-warning {{imaginary constants are a C2y extension}}
102+
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
103+
*/
104+

clang/test/Lexer/gnu-flags.c

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@
22
// RUN: %clang_cc1 -fsyntax-only -verify %s -DALL -Wgnu
33
// RUN: %clang_cc1 -fsyntax-only -verify %s -DALL \
44
// RUN: -Wgnu-zero-variadic-macro-arguments \
5-
// RUN: -Wgnu-imaginary-constant -Wgnu-zero-line-directive
5+
// RUN: -Wgnu-zero-line-directive
66
// RUN: %clang_cc1 -fsyntax-only -verify %s -DNONE -Wgnu \
77
// RUN: -Wno-gnu-zero-variadic-macro-arguments \
8-
// RUN: -Wno-gnu-imaginary-constant -Wno-gnu-zero-line-directive
8+
// RUN: -Wno-gnu-zero-line-directive
99
// Additional disabled tests:
1010
// %clang_cc1 -fsyntax-only -verify %s -DZEROARGS -Wgnu-zero-variadic-macro-arguments
11-
// %clang_cc1 -fsyntax-only -verify %s -DIMAGINARYCONST -Wgnu-imaginary-constant
1211
// %clang_cc1 -fsyntax-only -verify %s -DLINE0 -Wgnu-zero-line-directive
1312

1413
#if NONE
@@ -28,13 +27,6 @@ void foo( const char* c )
2827
}
2928

3029

31-
#if ALL || IMAGINARYCONST
32-
// expected-warning@+3 {{imaginary constants are a GNU extension}}
33-
#endif
34-
35-
float _Complex c = 1.if;
36-
37-
3830
// This case is handled differently because lit has a bug whereby #line 0 is reported to be on line 4294967295
3931
// http://llvm.org/bugs/show_bug.cgi?id=16952
4032
#if ALL || LINE0

clang/test/Sema/builtins.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ void test9(short v) {
4040

4141
old = __sync_fetch_and_add(); // expected-error {{too few arguments to function call}}
4242
old = __sync_fetch_and_add(&old); // expected-error {{too few arguments to function call}}
43-
old = __sync_fetch_and_add((unsigned*)0, 42i); // expected-warning {{imaginary constants are a GNU extension}}
43+
old = __sync_fetch_and_add((unsigned*)0, 42i); // expected-warning {{imaginary constants are a C2y extension}}
4444

4545
// PR7600: Pointers are implicitly casted to integers and back.
4646
void *old_ptr = __sync_val_compare_and_swap((void**)0, 0, 0);

clang/test/Sema/exprs.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ _Complex double test1(void) {
4040
}
4141

4242
_Complex double test2(void) {
43-
return 1.0if; // expected-warning {{imaginary constants are a GNU extension}}
43+
return 1.0if; // expected-warning {{imaginary constants are a C2y extension}}
4444
}
4545

4646
void test3(void) {
@@ -57,7 +57,7 @@ void test4(void) {
5757

5858
var =+5; // no warning when the subexpr of the unary op has no space before it.
5959
var =-5;
60-
60+
6161
#define FIVE 5
6262
var=-FIVE; // no warning with macros.
6363
var=-FIVE;
@@ -152,7 +152,7 @@ void test17(int x) {
152152
x = x % 0; // expected-warning {{remainder by zero is undefined}}
153153
x /= 0; // expected-warning {{division by zero is undefined}}
154154
x %= 0; // expected-warning {{remainder by zero is undefined}}
155-
155+
156156
x = sizeof(x/0); // no warning.
157157
}
158158

@@ -205,7 +205,7 @@ int test20(int x) {
205205
// expected-note {{remove constant to silence this warning}}
206206

207207
return x && sizeof(int) == 4; // no warning, RHS is logical op.
208-
208+
209209
// no warning, this is an idiom for "true" in old C style.
210210
return x && (signed char)1;
211211

clang/www/c_status.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ <h2 id="c2y">C2y implementation status</h2>
216216
<tr>
217217
<td>Introduce complex literals v. 2</td>
218218
<td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3298.htm">N3298</a></td>
219-
<td class="unknown" align="center">Unknown</td>
219+
<td class="full" align="center">Yes</td>
220220
</tr>
221221
<tr>
222222
<td>Allow zero length operations on null pointers</td>

0 commit comments

Comments
 (0)