-
-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
c: Implement C2y N3356, if declarations [PR117019]
This patch implements C2y N3356, if declarations as described at <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3356.htm>. This feature is cognate with C++17 Selection statements with initializer <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0305r1.html>, but they are not the same yet. For example, C++17 allows if (lock (); int i = getval ()) whereas C2y does not. The proposal adds new grammar productions. selection-header is handled in c_parser_selection_header which is the gist of the patch. simple-declaration is handled by c_parser_declaration_or_fndef, which gets a new parameter. PR c/117019 gcc/c/ChangeLog: * c-parser.cc (c_parser_declaration_or_fndef): Adjust declaration. (c_parser_external_declaration): Adjust a call to c_parser_declaration_or_fndef. (c_parser_declaration_or_fndef): New bool parameter. Return a tree instead of void. Adjust for N3356. Adjust a call to c_parser_declaration_or_fndef. (c_parser_compound_statement_nostart): Adjust calls to c_parser_declaration_or_fndef. (c_parser_selection_header): New. (c_parser_paren_selection_header): New. (c_parser_if_statement): Call c_parser_paren_selection_header instead of c_parser_paren_condition. (c_parser_switch_statement): Call c_parser_selection_header instead of c_parser_expression. (c_parser_for_statement): Adjust calls to c_parser_declaration_or_fndef. (c_parser_objc_methodprotolist): Likewise. (c_parser_oacc_routine): Likewise. (c_parser_omp_loop_nest): Likewise. (c_parser_omp_declare_simd): Likewise. gcc/testsuite/ChangeLog: * gcc.dg/c23-if-decls-1.c: New test. * gcc.dg/c23-if-decls-2.c: New test. * gcc.dg/c2y-if-decls-1.c: New test. * gcc.dg/c2y-if-decls-2.c: New test. * gcc.dg/c2y-if-decls-3.c: New test. * gcc.dg/c2y-if-decls-4.c: New test. * gcc.dg/c2y-if-decls-5.c: New test. * gcc.dg/c2y-if-decls-6.c: New test. * gcc.dg/c2y-if-decls-7.c: New test. * gcc.dg/c2y-if-decls-8.c: New test. * gcc.dg/c2y-if-decls-9.c: New test. * gcc.dg/c2y-if-decls-10.c: New test. * gcc.dg/c2y-if-decls-11.c: New test. * gcc.dg/gnu2y-if-decls-1.c: New test. * gcc.dg/gnu99-if-decls-1.c: New test. * gcc.dg/gnu99-if-decls-2.c: New test.
- Loading branch information
Showing
17 changed files
with
1,302 additions
and
56 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* N3356 - if declarations. */ | ||
/* PR c/117019 */ | ||
/* { dg-do compile } */ | ||
/* { dg-options "-std=c23 -pedantic-errors" } */ | ||
|
||
void | ||
g () | ||
{ | ||
if (int i = 42); /* { dg-error "ISO C does not support if declarations before C2Y" } */ | ||
if (int i = 42; i > 10); /* { dg-error "ISO C does not support if declarations before C2Y" } */ | ||
if (int i, j; i = 42); /* { dg-error "ISO C does not support if declarations before C2Y" } */ | ||
switch (int i = 42); /* { dg-error "ISO C does not support if declarations before C2Y" } */ | ||
switch (int i = 42; i); /* { dg-error "ISO C does not support if declarations before C2Y" } */ | ||
switch (int i, j; i = 42); /* { dg-error "ISO C does not support if declarations before C2Y" } */ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/* N3356 - if declarations. */ | ||
/* PR c/117019 */ | ||
/* { dg-do compile } */ | ||
/* { dg-options "-std=c23 -pedantic-errors -Wno-c23-c2y-compat" } */ | ||
|
||
#include "c23-if-decls-1.c" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
/* N3356 - if declarations. */ | ||
/* PR c/117019 */ | ||
/* { dg-do run } */ | ||
/* { dg-options "-std=c2y -Wc23-c2y-compat" } */ | ||
/* Test C2Y if declarations. Valid usages. */ | ||
|
||
int get () { return 42; } | ||
int foo (int i) { return i; } | ||
|
||
enum E { X = 1, Y }; | ||
|
||
void | ||
simple () | ||
{ | ||
if (int i = get ()) /* { dg-warning "if declarations before C2Y" } */ | ||
foo (i); | ||
else | ||
__builtin_abort (); | ||
|
||
if (int i = 0) /* { dg-warning "if declarations before C2Y" } */ | ||
__builtin_abort (); | ||
else | ||
foo (i); | ||
|
||
if (auto i = get ()) /* { dg-warning "if declarations before C2Y" } */ | ||
foo (i); | ||
else | ||
__builtin_abort (); | ||
|
||
if (__typeof__(get ()) i = get ()) /* { dg-warning "if declarations before C2Y" } */ | ||
foo (i); | ||
else | ||
__builtin_abort (); | ||
|
||
if (auto i = 0) /* { dg-warning "if declarations before C2Y" } */ | ||
__builtin_abort (); | ||
else | ||
foo (i); | ||
|
||
if (int (*f)(int) = foo) /* { dg-warning "if declarations before C2Y" } */ | ||
f (1); | ||
else | ||
__builtin_abort (); | ||
|
||
if ([[maybe_unused]] int i = get ()) /* { dg-warning "if declarations before C2Y" } */ | ||
foo (i); | ||
else | ||
__builtin_abort (); | ||
|
||
if (__attribute__((unused)) int i = get ()) /* { dg-warning "if declarations before C2Y" } */ | ||
foo (i); | ||
else | ||
__builtin_abort (); | ||
|
||
if (enum E e = X) /* { dg-warning "if declarations before C2Y" } */ | ||
foo (e); | ||
else | ||
__builtin_abort (); | ||
|
||
if (constexpr int i = 42) /* { dg-warning "if declarations before C2Y" } */ | ||
foo (i); | ||
else | ||
__builtin_abort (); | ||
|
||
if (int i = 1) /* { dg-warning "if declarations before C2Y" } */ | ||
if (int j = 2) /* { dg-warning "if declarations before C2Y" } */ | ||
if (int k = 3) /* { dg-warning "if declarations before C2Y" } */ | ||
foo (i + j + k); | ||
|
||
if (register int i = 0); /* { dg-warning "if declarations before C2Y" } */ | ||
if (static int i = 0); /* { dg-warning "if declarations before C2Y" } */ | ||
if (static int arr[3] = {}); /* { dg-warning "if declarations before C2Y" } */ | ||
if (_Atomic int i = 0); /* { dg-warning "if declarations before C2Y" } */ | ||
|
||
if (int arr[] = { 1 }) /* { dg-warning "if declarations before C2Y" } */ | ||
foo (arr[0]); | ||
else | ||
__builtin_abort (); | ||
|
||
double i; | ||
} | ||
|
||
void | ||
expr () | ||
{ | ||
if (int i = get (); i == 42) /* { dg-warning "if declarations before C2Y" } */ | ||
foo (i); | ||
else | ||
__builtin_abort (); | ||
|
||
if (int i = get (); i != 42) /* { dg-warning "if declarations before C2Y" } */ | ||
__builtin_abort (); | ||
else | ||
foo (i); | ||
|
||
if (auto i = get (); i == 42) /* { dg-warning "if declarations before C2Y" } */ | ||
foo (i); | ||
else | ||
__builtin_abort (); | ||
|
||
if (__typeof__(get ()) i = get (); i == 42) /* { dg-warning "if declarations before C2Y" } */ | ||
foo (i); | ||
else | ||
__builtin_abort (); | ||
|
||
if (auto i = get (); i != 42) /* { dg-warning "if declarations before C2Y" } */ | ||
__builtin_abort (); | ||
else | ||
foo (i); | ||
|
||
if (int (*f)(int) = foo; f (42)) /* { dg-warning "if declarations before C2Y" } */ | ||
f (1); | ||
else | ||
__builtin_abort (); | ||
|
||
if ([[maybe_unused]] int i = get (); i == 42) /* { dg-warning "if declarations before C2Y" } */ | ||
foo (i); | ||
else | ||
__builtin_abort (); | ||
|
||
if (__attribute__((unused)) int i = get (); i == 42) /* { dg-warning "if declarations before C2Y" } */ | ||
foo (i); | ||
else | ||
__builtin_abort (); | ||
|
||
if (enum E e = X; e == X) /* { dg-warning "if declarations before C2Y" } */ | ||
foo (e); | ||
else | ||
__builtin_abort (); | ||
|
||
if (constexpr int i = 42; i == 42) /* { dg-warning "if declarations before C2Y" } */ | ||
foo (i); | ||
else | ||
__builtin_abort (); | ||
|
||
if (int i = 1; i) /* { dg-warning "if declarations before C2Y" } */ | ||
if (int j = 2; j) /* { dg-warning "if declarations before C2Y" } */ | ||
if (int k = 3; k) /* { dg-warning "if declarations before C2Y" } */ | ||
foo (i + j + k); | ||
|
||
if (int i = 2, j = get (); i + j > 0) /* { dg-warning "if declarations before C2Y" } */ | ||
foo (i + j); | ||
else | ||
__builtin_abort (); | ||
|
||
if (int i; i = 1) /* { dg-warning "if declarations before C2Y" } */ | ||
foo (i); | ||
else | ||
__builtin_abort (); | ||
|
||
if (int arr[] = { 1, 2, 3}; arr[0]) /* { dg-warning "if declarations before C2Y" } */ | ||
foo (arr[0]); | ||
else | ||
__builtin_abort (); | ||
|
||
if (register int i = 0; i); /* { dg-warning "if declarations before C2Y" } */ | ||
if (static int i = 0; i); /* { dg-warning "if declarations before C2Y" } */ | ||
if (_Atomic int i = 0; i); /* { dg-warning "if declarations before C2Y" } */ | ||
|
||
double i; | ||
} | ||
|
||
int | ||
main () | ||
{ | ||
simple (); | ||
expr (); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* N3356 - if declarations. */ | ||
/* PR c/117019 */ | ||
/* { dg-do compile } */ | ||
/* { dg-options "-std=c2y -pedantic-errors" } */ | ||
/* Test C2Y if declarations. Invalid usages. */ | ||
|
||
void | ||
g (int g) | ||
{ | ||
switch (;); /* { dg-error "expected" } */ | ||
switch (int); /* { dg-error "expected identifier" } */ | ||
/* { dg-error "declaration" "" { target *-*-* } .-1 } */ | ||
switch (auto); /* { dg-error "expected identifier" } */ | ||
/* { dg-error "declaration" "" { target *-*-* } .-1 } */ | ||
switch (int;); /* { dg-error "declaration" } */ | ||
switch (auto;); /* { dg-error "empty|initializer" } */ | ||
switch (int i); /* { dg-error "initializer" } */ | ||
switch (int i;); /* { dg-error "expected" } */ | ||
switch (int i = 0;); /* { dg-error "expected" } */ | ||
|
||
switch (extern int i = 0); /* { dg-error "both .extern. and initializer" } */ | ||
switch (extern int i); /* { dg-error "initializer" } */ | ||
switch (thread_local int i = 0); /* { dg-error "function-scope" } */ | ||
switch (typedef int i); /* { dg-error "initializer" } */ | ||
switch (typedef int i = 0); /* { dg-error "initialized" } */ | ||
|
||
switch (int i = 2, j = 3); /* { dg-error "only declare a single object" } */ | ||
|
||
switch (void (*fp)(int)); /* { dg-error "initializer" } */ | ||
switch ([[maybe_unused]] g); /* { dg-error "expected" } */ | ||
switch ([[maybe_unused]] 42); /* { dg-error "expected" } */ | ||
switch ([[maybe_unused]] int); /* { dg-error "expected|initializer" } */ | ||
switch (__attribute__((unused)) g); /* { dg-error "initializer" } */ | ||
switch (__attribute__((unused)) 42); /* { dg-error "expected|initializer" } */ | ||
switch (__attribute__((unused)) int); /* { dg-error "expected|initializer" } */ | ||
|
||
switch (int arr[] = { 1 }); /* { dg-error "switch quantity not an integer" } */ | ||
} |
Oops, something went wrong.