Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,12 @@ def ext_designated_init_brace_elision : ExtWarn<
// Declarations.
def ext_plain_complex : ExtWarn<
"plain '_Complex' requires a type specifier; assuming '_Complex double'">;
def ext_imaginary_constant : Extension<
def warn_c23_compat_imaginary_constant : Warning<
"imaginary constants are incompatible with C standards before C2y">,
DefaultIgnore, InGroup<CPre2yCompat>;
def ext_c2y_imaginary_constant : Extension<
"imaginary constants are a C2y extension">, InGroup<C2y>;
def ext_gnu_imaginary_constant : Extension<
"imaginary constants are a GNU extension">, InGroup<GNUImaginaryConstant>;
def ext_integer_complex : Extension<
"complex integer types are a GNU extension">, InGroup<GNUComplexInteger>;
Expand Down
10 changes: 9 additions & 1 deletion clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4096,7 +4096,15 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
Res = new (Context) ImaginaryLiteral(Res,
Context.getComplexType(Res->getType()));

Diag(Tok.getLocation(), diag::ext_imaginary_constant);
// In C++, this is a GNU extension. In C, it's a C2y extension.
unsigned DiagId;
if (getLangOpts().CPlusPlus)
DiagId = diag::ext_gnu_imaginary_constant;
else if (getLangOpts().C2y)
DiagId = diag::warn_c23_compat_imaginary_constant;
else
DiagId = diag::ext_c2y_imaginary_constant;
Diag(Tok.getLocation(), DiagId);
}
return Res;
}
Expand Down
104 changes: 104 additions & 0 deletions clang/test/C/C2y/n3298.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// RUN: %clang_cc1 -verify=ped -std=c23 -Wall -pedantic %s
// RUN: %clang_cc1 -verify=yay -std=c2y -Wall -pedantic %s
// RUN: %clang_cc1 -verify=pre -std=c2y -Wpre-c2y-compat -Wall -pedantic %s
// RUN: %clang_cc1 -verify=gnu -Wall -Wgnu -x c++ %s
// RUN: %clang_cc1 -verify=yay -Wall -Wgnu -Wno-gnu-imaginary-constant -x c++ %s


/* WG14 N3298: Yes
* Introduce complex literals v. 2
*
* This introduces two suffixes for making complex literals: i and j (and I and
* J), which can be combined in any order with the other floating literal
* suffixes.
*
* We support these suffixes in older language modes as a conforming extension.
* It used to be a GNU extension, but now it's a C2y extension.
*/

// yay-no-diagnostics

static_assert(_Generic(12.0i, _Complex double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0fi, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0li, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0if, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0il, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/

static_assert(_Generic(12.0I, _Complex double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0fI, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0lI, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0If, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0Il, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/

static_assert(_Generic(12.0j, _Complex double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0fj, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0lj, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0jf, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0jl, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/

static_assert(_Generic(12.0J, _Complex double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0fJ, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0lJ, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0Jf, _Complex float : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/
static_assert(_Generic(12.0Jl, _Complex long double : 1, default : 0)); /* gnu-warning {{imaginary constants are a GNU extension}}
ped-warning {{imaginary constants are a C2y extension}}
pre-warning {{imaginary constants are incompatible with C standards before C2y}}
*/

12 changes: 2 additions & 10 deletions clang/test/Lexer/gnu-flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -DALL -Wgnu
// RUN: %clang_cc1 -fsyntax-only -verify %s -DALL \
// RUN: -Wgnu-zero-variadic-macro-arguments \
// RUN: -Wgnu-imaginary-constant -Wgnu-zero-line-directive
// RUN: -Wgnu-zero-line-directive
// RUN: %clang_cc1 -fsyntax-only -verify %s -DNONE -Wgnu \
// RUN: -Wno-gnu-zero-variadic-macro-arguments \
// RUN: -Wno-gnu-imaginary-constant -Wno-gnu-zero-line-directive
// RUN: -Wno-gnu-zero-line-directive
// Additional disabled tests:
// %clang_cc1 -fsyntax-only -verify %s -DZEROARGS -Wgnu-zero-variadic-macro-arguments
// %clang_cc1 -fsyntax-only -verify %s -DIMAGINARYCONST -Wgnu-imaginary-constant
// %clang_cc1 -fsyntax-only -verify %s -DLINE0 -Wgnu-zero-line-directive

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


#if ALL || IMAGINARYCONST
// expected-warning@+3 {{imaginary constants are a GNU extension}}
#endif

float _Complex c = 1.if;


// This case is handled differently because lit has a bug whereby #line 0 is reported to be on line 4294967295
// http://llvm.org/bugs/show_bug.cgi?id=16952
#if ALL || LINE0
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Sema/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ void test9(short v) {

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

// PR7600: Pointers are implicitly casted to integers and back.
void *old_ptr = __sync_val_compare_and_swap((void**)0, 0, 0);
Expand Down
8 changes: 4 additions & 4 deletions clang/test/Sema/exprs.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ _Complex double test1(void) {
}

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

void test3(void) {
Expand All @@ -57,7 +57,7 @@ void test4(void) {

var =+5; // no warning when the subexpr of the unary op has no space before it.
var =-5;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handful of WS changes in this file, though not sure I care enough to have you change this.


#define FIVE 5
var=-FIVE; // no warning with macros.
var=-FIVE;
Expand Down Expand Up @@ -152,7 +152,7 @@ void test17(int x) {
x = x % 0; // expected-warning {{remainder by zero is undefined}}
x /= 0; // expected-warning {{division by zero is undefined}}
x %= 0; // expected-warning {{remainder by zero is undefined}}

x = sizeof(x/0); // no warning.
}

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

return x && sizeof(int) == 4; // no warning, RHS is logical op.

// no warning, this is an idiom for "true" in old C style.
return x && (signed char)1;

Expand Down
2 changes: 1 addition & 1 deletion clang/www/c_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ <h2 id="c2y">C2y implementation status</h2>
<tr>
<td>Introduce complex literals v. 2</td>
<td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3298.htm">N3298</a></td>
<td class="unknown" align="center">Unknown</td>
<td class="full" align="center">Yes</td>
</tr>
<tr>
<td>Allow zero length operations on null pointers</td>
Expand Down
Loading