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.
This commit is contained in:
parent
7175fece7d
commit
440be01b07
17 changed files with 1302 additions and 56 deletions
|
@ -1634,8 +1634,8 @@ static bool c_parser_nth_token_starts_std_attributes (c_parser *,
|
|||
static tree c_parser_std_attribute_specifier_sequence (c_parser *);
|
||||
static void c_parser_external_declaration (c_parser *);
|
||||
static void c_parser_asm_definition (c_parser *);
|
||||
static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
|
||||
bool, bool, tree * = NULL,
|
||||
static tree c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
|
||||
bool, bool, bool, tree * = NULL,
|
||||
vec<c_token> * = NULL,
|
||||
bool have_attrs = false,
|
||||
tree attrs = NULL,
|
||||
|
@ -2060,7 +2060,8 @@ c_parser_external_declaration (c_parser *parser)
|
|||
an @interface or @protocol with prefix attributes). We can
|
||||
only tell which after parsing the declaration specifiers, if
|
||||
any, and the first declarator. */
|
||||
c_parser_declaration_or_fndef (parser, true, true, true, false, true);
|
||||
c_parser_declaration_or_fndef (parser, true, true, true, false, true,
|
||||
false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2145,7 +2146,13 @@ handle_assume_attribute (location_t here, tree attrs, bool nested)
|
|||
parsed in the caller (in contexts where such attributes had to be
|
||||
parsed to determine whether what follows is a declaration or a
|
||||
statement); HAVE_ATTRS says whether there were any such attributes
|
||||
(even empty).
|
||||
(even empty). If SIMPLE_OK, the construct can be a simple-declaration;
|
||||
in that case, the ';' is not consumed (left to the caller so that it
|
||||
can figure out if there was a simple-declaration or not), there must
|
||||
be an initializer, and only one object may be declared. When SIMPLE_OK
|
||||
is true we are called from c_parser_selection_header.
|
||||
|
||||
Returns the resulting declaration, if there was any with an initializer.
|
||||
|
||||
declaration:
|
||||
declaration-specifiers init-declarator-list[opt] ;
|
||||
|
@ -2167,6 +2174,10 @@ handle_assume_attribute (location_t here, tree attrs, bool nested)
|
|||
declarator simple-asm-expr[opt] gnu-attributes[opt]
|
||||
declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
|
||||
|
||||
simple-declaration:
|
||||
attribute-specifier-sequence[opt] declaration-specifiers declarator
|
||||
= initializer
|
||||
|
||||
GNU extensions:
|
||||
|
||||
nested-function-definition:
|
||||
|
@ -2213,10 +2224,11 @@ handle_assume_attribute (location_t here, tree attrs, bool nested)
|
|||
declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
|
||||
declaration-list[opt] compound-statement */
|
||||
|
||||
static void
|
||||
static tree
|
||||
c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
||||
bool static_assert_ok, bool empty_ok,
|
||||
bool nested, bool start_attr_ok,
|
||||
bool simple_ok,
|
||||
tree *objc_foreach_object_declaration
|
||||
/* = NULL */,
|
||||
vec<c_token> *omp_declare_simd_clauses
|
||||
|
@ -2232,6 +2244,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
tree all_prefix_attrs;
|
||||
bool diagnosed_no_specs = false;
|
||||
location_t here = c_parser_peek_token (parser)->location;
|
||||
tree result = NULL_TREE;
|
||||
|
||||
add_debug_begin_stmt (c_parser_peek_token (parser)->location);
|
||||
|
||||
|
@ -2239,7 +2252,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
&& c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
|
||||
{
|
||||
c_parser_static_assert_declaration (parser);
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
specs = build_null_declspecs ();
|
||||
|
||||
|
@ -2325,13 +2338,13 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
if (parser->error)
|
||||
{
|
||||
c_parser_skip_to_end_of_block_or_statement (parser);
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
if (nested && !specs->declspecs_seen_p)
|
||||
{
|
||||
c_parser_error (parser, "expected declaration specifiers");
|
||||
c_parser_skip_to_end_of_block_or_statement (parser);
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
|
||||
finish_declspecs (specs);
|
||||
|
@ -2366,6 +2379,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
|
||||
{
|
||||
bool handled_assume = false;
|
||||
|
@ -2383,7 +2397,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
c_parser_pragma (parser, pragma_external, NULL, NULL_TREE);
|
||||
}
|
||||
c_parser_consume_token (parser);
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
if (specs->typespec_kind == ctsk_none
|
||||
&& lookup_attribute ("gnu", "assume", specs->attrs))
|
||||
|
@ -2425,7 +2439,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
c_parser_consume_token (parser);
|
||||
if (oacc_routine_data)
|
||||
c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Provide better error recovery. Note that a type name here is usually
|
||||
|
@ -2438,7 +2452,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
|
||||
parser->error = false;
|
||||
shadow_tag_warned (specs, 1);
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
else if (c_dialect_objc () && !any_auto_type_p)
|
||||
{
|
||||
|
@ -2448,7 +2462,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
case CPP_PLUS:
|
||||
case CPP_MINUS:
|
||||
if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
|
||||
return;
|
||||
return result;
|
||||
if (specs->attrs)
|
||||
{
|
||||
warning_at (c_parser_peek_token (parser)->location,
|
||||
|
@ -2460,7 +2474,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
c_parser_objc_method_definition (parser);
|
||||
else
|
||||
c_parser_objc_methodproto (parser);
|
||||
return;
|
||||
return result;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -2475,15 +2489,15 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
case RID_AT_INTERFACE:
|
||||
{
|
||||
if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
|
||||
return;
|
||||
return result;
|
||||
c_parser_objc_class_definition (parser, specs->attrs);
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
case RID_AT_IMPLEMENTATION:
|
||||
{
|
||||
if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
|
||||
return;
|
||||
return result;
|
||||
if (specs->attrs)
|
||||
{
|
||||
warning_at (c_parser_peek_token (parser)->location,
|
||||
|
@ -2492,15 +2506,15 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
specs->attrs = NULL_TREE;
|
||||
}
|
||||
c_parser_objc_class_definition (parser, NULL_TREE);
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
case RID_AT_PROTOCOL:
|
||||
{
|
||||
if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
|
||||
return;
|
||||
return result;
|
||||
c_parser_objc_protocol_definition (parser, specs->attrs);
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
case RID_AT_ALIAS:
|
||||
|
@ -2532,6 +2546,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
prefix_attrs = specs->attrs;
|
||||
all_prefix_attrs = prefix_attrs;
|
||||
specs->attrs = NULL_TREE;
|
||||
bool more_than_one_decl = false;
|
||||
while (true)
|
||||
{
|
||||
struct c_declarator *declarator;
|
||||
|
@ -2554,8 +2569,10 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
omp_declare_simd_clauses);
|
||||
if (oacc_routine_data)
|
||||
c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
|
||||
c_parser_skip_to_end_of_block_or_statement (parser);
|
||||
return;
|
||||
/* This check is here purely to improve the diagnostic. */
|
||||
if (!simple_ok)
|
||||
c_parser_skip_to_end_of_block_or_statement (parser);
|
||||
return result;
|
||||
}
|
||||
if (flag_openmp || flag_openmp_simd)
|
||||
{
|
||||
|
@ -2572,7 +2589,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
"%<__auto_type%> requires a plain identifier"
|
||||
" as declarator");
|
||||
c_parser_skip_to_end_of_block_or_statement (parser);
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
if (std_auto_type_p)
|
||||
{
|
||||
|
@ -2585,7 +2602,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
"%<auto%> requires a plain identifier, possibly with"
|
||||
" attributes, as declarator");
|
||||
c_parser_skip_to_end_of_block_or_statement (parser);
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
underspec_name = d->u.id.id;
|
||||
}
|
||||
|
@ -2626,7 +2643,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
error_at (here, "attributes should be specified before the "
|
||||
"declarator in a function definition");
|
||||
c_parser_skip_to_end_of_block_or_statement (parser);
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (c_parser_next_token_is (parser, CPP_EQ))
|
||||
|
@ -2766,6 +2783,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
|
||||
finish_decl (d, init_loc, init.value,
|
||||
init.original_type, asm_name);
|
||||
result = d;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -2776,7 +2794,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
"%qs requires an initialized data declaration",
|
||||
any_auto_type_p ? auto_type_keyword : "constexpr");
|
||||
c_parser_skip_to_end_of_block_or_statement (parser);
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
|
||||
location_t lastloc = UNKNOWN_LOCATION;
|
||||
|
@ -2869,13 +2887,14 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
}
|
||||
if (c_parser_next_token_is (parser, CPP_COMMA))
|
||||
{
|
||||
more_than_one_decl = true;
|
||||
if (any_auto_type_p || specs->constexpr_p)
|
||||
{
|
||||
error_at (here,
|
||||
"%qs may only be used with a single declarator",
|
||||
any_auto_type_p ? auto_type_keyword : "constexpr");
|
||||
c_parser_skip_to_end_of_block_or_statement (parser);
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
c_parser_consume_token (parser);
|
||||
if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
|
||||
|
@ -2887,8 +2906,9 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
}
|
||||
else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
|
||||
{
|
||||
c_parser_consume_token (parser);
|
||||
return;
|
||||
if (!simple_ok)
|
||||
c_parser_consume_token (parser);
|
||||
return result;
|
||||
}
|
||||
else if (c_parser_next_token_is_keyword (parser, RID_IN))
|
||||
{
|
||||
|
@ -2897,13 +2917,20 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
Objective-C foreach statement. Do not consume the
|
||||
token, so that the caller can use it to determine
|
||||
that this indeed is a foreach context. */
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
c_parser_error (parser, "expected %<,%> or %<;%>");
|
||||
c_parser_skip_to_end_of_block_or_statement (parser);
|
||||
return;
|
||||
if (!simple_ok)
|
||||
{
|
||||
c_parser_error (parser, "expected %<,%> or %<;%>");
|
||||
c_parser_skip_to_end_of_block_or_statement (parser);
|
||||
}
|
||||
/* It's not valid to use if (int i = 2, j = 3). */
|
||||
else if (more_than_one_decl)
|
||||
error_at (here, "declaration in condition can only declare "
|
||||
"a single object");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (any_auto_type_p || specs->constexpr_p)
|
||||
|
@ -2912,14 +2939,19 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
"%qs requires an initialized data declaration",
|
||||
any_auto_type_p ? auto_type_keyword : "constexpr");
|
||||
c_parser_skip_to_end_of_block_or_statement (parser);
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
else if (!fndef_ok)
|
||||
{
|
||||
c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
|
||||
"%<asm%> or %<__attribute__%>");
|
||||
c_parser_skip_to_end_of_block_or_statement (parser);
|
||||
return;
|
||||
if (simple_ok && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
|
||||
/* Let c_parser_selection_header emit the error. */;
|
||||
else
|
||||
{
|
||||
c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
|
||||
"%<asm%> or %<__attribute__%>");
|
||||
c_parser_skip_to_end_of_block_or_statement (parser);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/* Function definition (nested or otherwise). */
|
||||
if (nested)
|
||||
|
@ -2988,7 +3020,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
while (c_parser_next_token_is_not (parser, CPP_EOF)
|
||||
&& c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
|
||||
c_parser_declaration_or_fndef (parser, false, false, false,
|
||||
true, false);
|
||||
true, false, false);
|
||||
debug_nonbind_markers_p = save_debug_nonbind_markers_p;
|
||||
store_parm_decls ();
|
||||
if (omp_declare_simd_clauses)
|
||||
|
@ -3018,7 +3050,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
pop_scope ();
|
||||
|
||||
finish_function (endloc);
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
/* If the definition was marked with __GIMPLE then parse the
|
||||
function body as GIMPLE. */
|
||||
|
@ -3059,6 +3091,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Parse an asm-definition (asm() outside a function body). This is a
|
||||
|
@ -7378,7 +7412,7 @@ c_parser_compound_statement_nostart (c_parser *parser)
|
|||
mark_valid_location_for_stdc_pragma (false);
|
||||
bool fallthru_attr_p = false;
|
||||
c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
|
||||
true, true, true, NULL,
|
||||
true, true, true, false, NULL,
|
||||
NULL, have_std_attrs, std_attrs,
|
||||
NULL, &fallthru_attr_p);
|
||||
|
||||
|
@ -7421,7 +7455,7 @@ c_parser_compound_statement_nostart (c_parser *parser)
|
|||
}
|
||||
mark_valid_location_for_stdc_pragma (false);
|
||||
c_parser_declaration_or_fndef (parser, true, true, true, true,
|
||||
true);
|
||||
true, false);
|
||||
if (in_omp_loop_block)
|
||||
omp_for_parse_state->want_nested_loop = want_nested_loop;
|
||||
/* Following the old parser, __extension__ does not
|
||||
|
@ -8075,11 +8109,12 @@ c_parser_condition (c_parser *parser)
|
|||
return cond;
|
||||
}
|
||||
|
||||
/* Parse a parenthesized condition from an if, do or while statement.
|
||||
/* Parse a parenthesized condition from a do or while statement.
|
||||
|
||||
condition:
|
||||
( expression )
|
||||
*/
|
||||
|
||||
static tree
|
||||
c_parser_paren_condition (c_parser *parser)
|
||||
{
|
||||
|
@ -8092,6 +8127,108 @@ c_parser_paren_condition (c_parser *parser)
|
|||
return cond;
|
||||
}
|
||||
|
||||
/* Parse a selection-header:
|
||||
|
||||
selection-header:
|
||||
expression
|
||||
declaration expression
|
||||
simple-declaration
|
||||
|
||||
simple-declaration:
|
||||
attribute-specifier-sequence[opt] declaration-specifiers declarator
|
||||
= initializer
|
||||
|
||||
SWITCH_P is true if we are called from c_parser_switch_statement; in
|
||||
that case, don't perform the truthvalue conversion. */
|
||||
|
||||
static c_expr
|
||||
c_parser_selection_header (c_parser *parser, bool switch_p)
|
||||
{
|
||||
location_t loc = c_parser_peek_token (parser)->location;
|
||||
c_expr expr;
|
||||
bool parse_expr = true;
|
||||
tree std_attrs;
|
||||
bool have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
|
||||
if (have_std_attrs)
|
||||
std_attrs = c_parser_std_attribute_specifier_sequence (parser);
|
||||
else
|
||||
std_attrs = NULL_TREE;
|
||||
if (c_parser_next_tokens_start_declaration (parser))
|
||||
{
|
||||
pedwarn_c23 (loc, OPT_Wpedantic,
|
||||
"ISO C does not support if declarations before C2Y");
|
||||
expr.value
|
||||
= c_parser_declaration_or_fndef (parser,
|
||||
/*fndef_ok=*/false,
|
||||
/*static_assert_ok=*/false,
|
||||
/*empty_ok=*/false,
|
||||
/*nested=*/true,
|
||||
/*start_attr_ok=*/true,
|
||||
/*simple_ok=*/true,
|
||||
/*objc_foreach_object_decl=*/nullptr,
|
||||
/*omp_declare_simd_clauses=*/nullptr,
|
||||
have_std_attrs,
|
||||
std_attrs);
|
||||
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
|
||||
c_parser_consume_token (parser);
|
||||
else
|
||||
{
|
||||
/* A simple-declaration is a declaration that can appear in
|
||||
place of the controlling expression of a selection statement.
|
||||
In that case, there shall be an initializer. */
|
||||
if (!expr.value)
|
||||
{
|
||||
error_at (loc, "declaration in the controlling expression must "
|
||||
"have an initializer");
|
||||
expr.original_type = error_mark_node;
|
||||
expr.set_error ();
|
||||
return expr;
|
||||
}
|
||||
parse_expr = false;
|
||||
}
|
||||
if (expr.value)
|
||||
{
|
||||
expr.original_type = TREE_TYPE (expr.value);
|
||||
expr = convert_lvalue_to_rvalue (loc, expr, /*convert_p=*/true,
|
||||
/*read_p=*/true);
|
||||
}
|
||||
}
|
||||
else if (have_std_attrs)
|
||||
{
|
||||
c_parser_error (parser, "expected declaration");
|
||||
expr.original_type = error_mark_node;
|
||||
expr.set_error ();
|
||||
return expr;
|
||||
}
|
||||
|
||||
if (parse_expr)
|
||||
expr = c_parser_expression_conv (parser);
|
||||
if (!switch_p)
|
||||
{
|
||||
expr.value = c_objc_common_truthvalue_conversion (loc, expr.value);
|
||||
expr.value = c_fully_fold (expr.value, false, NULL);
|
||||
if (warn_sequence_point)
|
||||
verify_sequence_points (expr.value);
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
/* Parse a selection-header enclosed in parentheses:
|
||||
|
||||
( selection-header )
|
||||
*/
|
||||
|
||||
static tree
|
||||
c_parser_paren_selection_header (c_parser *parser)
|
||||
{
|
||||
matching_parens parens;
|
||||
if (!parens.require_open (parser))
|
||||
return error_mark_node;
|
||||
tree cond = c_parser_selection_header (parser, /*switch_p=*/false).value;
|
||||
parens.skip_until_found_close (parser);
|
||||
return cond;
|
||||
}
|
||||
|
||||
/* Parse a statement which is a block in C99.
|
||||
|
||||
IF_P is used to track whether there's a (possibly labeled) if statement
|
||||
|
@ -8244,8 +8381,8 @@ c_parser_maybe_reclassify_token (c_parser *parser)
|
|||
/* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
|
||||
|
||||
if-statement:
|
||||
if ( expression ) statement
|
||||
if ( expression ) statement else statement
|
||||
if ( selection-header ) statement
|
||||
if ( selection-header ) statement else statement
|
||||
|
||||
CHAIN is a vector of if-else-if conditions.
|
||||
IF_P is used to track whether there's a (possibly labeled) if statement
|
||||
|
@ -8268,7 +8405,7 @@ c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
|
|||
c_parser_consume_token (parser);
|
||||
block = c_begin_compound_stmt (flag_isoc99);
|
||||
loc = c_parser_peek_token (parser)->location;
|
||||
cond = c_parser_paren_condition (parser);
|
||||
cond = c_parser_paren_selection_header (parser);
|
||||
in_if_block = parser->in_if_block;
|
||||
parser->in_if_block = true;
|
||||
first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
|
||||
|
@ -8355,7 +8492,10 @@ c_parser_switch_statement (c_parser *parser, bool *if_p, tree before_labels)
|
|||
if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
|
||||
&& c_token_starts_typename (c_parser_peek_2nd_token (parser)))
|
||||
explicit_cast_p = true;
|
||||
ce = c_parser_expression (parser);
|
||||
ce = c_parser_selection_header (parser, /*switch_p=*/true);
|
||||
/* The call above already performed convert_lvalue_to_rvalue, but
|
||||
if it parsed an expression, read_p was false. Make sure we mark
|
||||
the expression as read. */
|
||||
ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
|
||||
expr = ce.value;
|
||||
/* ??? expr has no valid location? */
|
||||
|
@ -8667,7 +8807,7 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
|
|||
|| c_parser_nth_token_starts_std_attributes (parser, 1))
|
||||
{
|
||||
c_parser_declaration_or_fndef (parser, true, true, true, true, true,
|
||||
&object_expression);
|
||||
false, &object_expression);
|
||||
parser->objc_could_be_foreach_context = false;
|
||||
|
||||
if (c_parser_next_token_is_keyword (parser, RID_IN))
|
||||
|
@ -8698,7 +8838,7 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
|
|||
ext = disable_extension_diagnostics ();
|
||||
c_parser_consume_token (parser);
|
||||
c_parser_declaration_or_fndef (parser, true, true, true, true,
|
||||
true, &object_expression);
|
||||
true, false, &object_expression);
|
||||
parser->objc_could_be_foreach_context = false;
|
||||
|
||||
restore_extension_diagnostics (ext);
|
||||
|
@ -14050,7 +14190,7 @@ c_parser_objc_methodprotolist (c_parser *parser)
|
|||
}
|
||||
else
|
||||
c_parser_declaration_or_fndef (parser, false, false, true,
|
||||
false, true);
|
||||
false, true, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -21170,12 +21310,12 @@ c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
|
|||
while (c_parser_next_token_is (parser, CPP_KEYWORD)
|
||||
&& c_parser_peek_token (parser)->keyword == RID_EXTENSION);
|
||||
c_parser_declaration_or_fndef (parser, true, true, true, false, true,
|
||||
NULL, NULL, false, NULL, &data);
|
||||
false, NULL, NULL, false, NULL, &data);
|
||||
restore_extension_diagnostics (ext);
|
||||
}
|
||||
else
|
||||
c_parser_declaration_or_fndef (parser, true, true, true, false, true,
|
||||
NULL, NULL, false, NULL, &data);
|
||||
false, NULL, NULL, false, NULL, &data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23136,7 +23276,8 @@ c_parser_omp_loop_nest (c_parser *parser, bool *if_p)
|
|||
/* This is a declaration, which must be added to the pre_body code. */
|
||||
tree this_pre_body = push_stmt_list ();
|
||||
c_in_omp_for = true;
|
||||
c_parser_declaration_or_fndef (parser, true, true, true, true, true);
|
||||
c_parser_declaration_or_fndef (parser, true, true, true, true, true,
|
||||
false);
|
||||
c_in_omp_for = false;
|
||||
this_pre_body = pop_stmt_list (this_pre_body);
|
||||
append_to_statement_list_force (this_pre_body,
|
||||
|
@ -25378,12 +25519,12 @@ c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
|
|||
while (c_parser_next_token_is (parser, CPP_KEYWORD)
|
||||
&& c_parser_peek_token (parser)->keyword == RID_EXTENSION);
|
||||
c_parser_declaration_or_fndef (parser, true, true, true, false, true,
|
||||
NULL, &clauses);
|
||||
false, NULL, &clauses);
|
||||
restore_extension_diagnostics (ext);
|
||||
}
|
||||
else
|
||||
c_parser_declaration_or_fndef (parser, true, true, true, false, true,
|
||||
NULL, &clauses);
|
||||
false, NULL, &clauses);
|
||||
break;
|
||||
case pragma_struct:
|
||||
case pragma_param:
|
||||
|
@ -25412,7 +25553,7 @@ c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
|
|||
|| c_parser_nth_token_starts_std_attributes (parser, 1))
|
||||
{
|
||||
c_parser_declaration_or_fndef (parser, true, true, true, true,
|
||||
true, NULL, &clauses,
|
||||
true, false, NULL, &clauses,
|
||||
have_std_attrs, std_attrs);
|
||||
restore_extension_diagnostics (ext);
|
||||
break;
|
||||
|
@ -25422,7 +25563,7 @@ c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
|
|||
else if (c_parser_next_tokens_start_declaration (parser))
|
||||
{
|
||||
c_parser_declaration_or_fndef (parser, true, true, true, true, true,
|
||||
NULL, &clauses, have_std_attrs,
|
||||
false, NULL, &clauses, have_std_attrs,
|
||||
std_attrs);
|
||||
break;
|
||||
}
|
||||
|
|
15
gcc/testsuite/gcc.dg/c23-if-decls-1.c
Normal file
15
gcc/testsuite/gcc.dg/c23-if-decls-1.c
Normal file
|
@ -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" } */
|
||||
}
|
6
gcc/testsuite/gcc.dg/c23-if-decls-2.c
Normal file
6
gcc/testsuite/gcc.dg/c23-if-decls-2.c
Normal file
|
@ -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"
|
168
gcc/testsuite/gcc.dg/c2y-if-decls-1.c
Normal file
168
gcc/testsuite/gcc.dg/c2y-if-decls-1.c
Normal file
|
@ -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 ();
|
||||
}
|
38
gcc/testsuite/gcc.dg/c2y-if-decls-10.c
Normal file
38
gcc/testsuite/gcc.dg/c2y-if-decls-10.c
Normal file
|
@ -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" } */
|
||||
}
|
199
gcc/testsuite/gcc.dg/c2y-if-decls-11.c
Normal file
199
gcc/testsuite/gcc.dg/c2y-if-decls-11.c
Normal file
|
@ -0,0 +1,199 @@
|
|||
/* N3356 - if declarations. */
|
||||
/* PR c/117019 */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-std=c2y -pedantic-errors" } */
|
||||
/* Test C2Y if declarations. Valid usages. */
|
||||
|
||||
int get () { return 42; }
|
||||
int foo (int i) { return i; }
|
||||
|
||||
enum E { X = 1, Y };
|
||||
|
||||
void
|
||||
simple ()
|
||||
{
|
||||
switch (int i = get ())
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (int i = 0)
|
||||
{
|
||||
case 0:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (auto i = get ())
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (__typeof__(get ()) i = get ())
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (auto i = 0)
|
||||
{
|
||||
case 0:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch ([[maybe_unused]] int i = get ())
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (__attribute__((unused)) int i = get ())
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (enum E e = X)
|
||||
{
|
||||
case X:
|
||||
foo (X);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (constexpr int i = 42)
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (register int i = 0);
|
||||
switch (static int i = 0);
|
||||
switch (_Atomic int i = 0);
|
||||
|
||||
double i;
|
||||
}
|
||||
|
||||
void
|
||||
expr ()
|
||||
{
|
||||
switch (int i = get (); i)
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (auto i = get (); i)
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (__typeof__(get ()) i = get (); i)
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (int (*f)(int) = foo; f (42))
|
||||
{
|
||||
case 42:
|
||||
foo (42);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch ([[maybe_unused]] int i = get (); i)
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (__attribute__((unused)) int i = get (); i)
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (enum E e = X; e)
|
||||
{
|
||||
case X:
|
||||
foo (X);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (constexpr int i = 42; i)
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (int arr[] = { 1, 2, 3}; arr[0])
|
||||
{
|
||||
case 1:
|
||||
foo (arr[0]);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (register int i = 0; i);
|
||||
switch (static int i = 0; i);
|
||||
switch (_Atomic int i = 0; i);
|
||||
|
||||
double i;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
simple ();
|
||||
expr ();
|
||||
}
|
35
gcc/testsuite/gcc.dg/c2y-if-decls-2.c
Normal file
35
gcc/testsuite/gcc.dg/c2y-if-decls-2.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* N3356 - if declarations. */
|
||||
/* PR c/117019 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=c2y" } */
|
||||
/* Test C2Y if declarations. Invalid usages. */
|
||||
|
||||
void
|
||||
g (int g)
|
||||
{
|
||||
if (;); /* { dg-error "expected" } */
|
||||
if (int); /* { dg-error "expected|initializer" } */
|
||||
if (auto); /* { dg-error "expected|initializer" } */
|
||||
if (int;); /* { dg-error "initializer" } */
|
||||
/* { dg-warning "empty" "" { target *-*-* } .-1 } */
|
||||
if (auto;); /* { dg-error "empty|initializer" } */
|
||||
if (int i); /* { dg-error "initializer" } */
|
||||
if (int i;); /* { dg-error "expected" } */
|
||||
if (int i = 0;); /* { dg-error "expected" } */
|
||||
|
||||
if (extern int i = 0); /* { dg-error "both .extern. and initializer" } */
|
||||
if (extern int i); /* { dg-error "initializer" } */
|
||||
if (thread_local int i = 0); /* { dg-error "function-scope" } */
|
||||
if (typedef int i); /* { dg-error "initializer" } */
|
||||
if (typedef int i = 0); /* { dg-error "initialized" } */
|
||||
|
||||
if (int i = 2, j = 3); /* { dg-error "only declare a single object" } */
|
||||
|
||||
if (void (*fp)(int)); /* { dg-error "initializer" } */
|
||||
if ([[maybe_unused]] g); /* { dg-error "expected" } */
|
||||
if ([[maybe_unused]] 42); /* { dg-error "expected" } */
|
||||
if ([[maybe_unused]] int); /* { dg-error "expected|initializer" } */
|
||||
if (__attribute__((unused)) g); /* { dg-error "initializer" } */
|
||||
if (__attribute__((unused)) 42); /* { dg-error "expected|initializer" } */
|
||||
if (__attribute__((unused)) int); /* { dg-error "expected|initializer" } */
|
||||
}
|
39
gcc/testsuite/gcc.dg/c2y-if-decls-3.c
Normal file
39
gcc/testsuite/gcc.dg/c2y-if-decls-3.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/* N3356 - if declarations. */
|
||||
/* PR c/117019 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=c2y" } */
|
||||
/* 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" } */
|
||||
/* { dg-warning "empty" "" { target *-*-* } .-1 } */
|
||||
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" } */
|
||||
}
|
199
gcc/testsuite/gcc.dg/c2y-if-decls-4.c
Normal file
199
gcc/testsuite/gcc.dg/c2y-if-decls-4.c
Normal file
|
@ -0,0 +1,199 @@
|
|||
/* 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 ()
|
||||
{
|
||||
switch (int i = get ()) /* { dg-warning "if declarations before C2Y" } */
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (int i = 0) /* { dg-warning "if declarations before C2Y" } */
|
||||
{
|
||||
case 0:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (auto i = get ()) /* { dg-warning "if declarations before C2Y" } */
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (__typeof__(get ()) i = get ()) /* { dg-warning "if declarations before C2Y" } */
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (auto i = 0) /* { dg-warning "if declarations before C2Y" } */
|
||||
{
|
||||
case 0:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch ([[maybe_unused]] int i = get ()) /* { dg-warning "if declarations before C2Y" } */
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (__attribute__((unused)) int i = get ()) /* { dg-warning "if declarations before C2Y" } */
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (enum E e = X) /* { dg-warning "if declarations before C2Y" } */
|
||||
{
|
||||
case X:
|
||||
foo (X);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (constexpr int i = 42) /* { dg-warning "if declarations before C2Y" } */
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (register int i = 0); /* { dg-warning "if declarations before C2Y" } */
|
||||
switch (static int i = 0); /* { dg-warning "if declarations before C2Y" } */
|
||||
switch (_Atomic int i = 0); /* { dg-warning "if declarations before C2Y" } */
|
||||
|
||||
double i;
|
||||
}
|
||||
|
||||
void
|
||||
expr ()
|
||||
{
|
||||
switch (int i = get (); i) /* { dg-warning "if declarations before C2Y" } */
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (auto i = get (); i) /* { dg-warning "if declarations before C2Y" } */
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (__typeof__(get ()) i = get (); i) /* { dg-warning "if declarations before C2Y" } */
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (int (*f)(int) = foo; f (42)) /* { dg-warning "if declarations before C2Y" } */
|
||||
{
|
||||
case 42:
|
||||
foo (42);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch ([[maybe_unused]] int i = get (); i) /* { dg-warning "if declarations before C2Y" } */
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (__attribute__((unused)) int i = get (); i) /* { dg-warning "if declarations before C2Y" } */
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (enum E e = X; e) /* { dg-warning "if declarations before C2Y" } */
|
||||
{
|
||||
case X:
|
||||
foo (X);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (constexpr int i = 42; i) /* { dg-warning "if declarations before C2Y" } */
|
||||
{
|
||||
case 42:
|
||||
foo (i);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (int arr[] = { 1, 2, 3}; arr[0]) /* { dg-warning "if declarations before C2Y" } */
|
||||
{
|
||||
case 1:
|
||||
foo (arr[0]);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
switch (register int i = 0; i); /* { dg-warning "if declarations before C2Y" } */
|
||||
switch (static int i = 0; i); /* { dg-warning "if declarations before C2Y" } */
|
||||
switch (_Atomic int i = 0; i); /* { dg-warning "if declarations before C2Y" } */
|
||||
|
||||
double i;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
simple ();
|
||||
expr ();
|
||||
}
|
35
gcc/testsuite/gcc.dg/c2y-if-decls-5.c
Normal file
35
gcc/testsuite/gcc.dg/c2y-if-decls-5.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* N3356 - if declarations. */
|
||||
/* PR c/117019 */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-std=c2y" } */
|
||||
|
||||
int g;
|
||||
int get () { ++g; return 42; }
|
||||
|
||||
struct S { int i; };
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if (auto x = get (); get (), x);
|
||||
if (g != 2)
|
||||
__builtin_abort ();
|
||||
|
||||
switch (auto x = get (); get (), x);
|
||||
if (g != 4)
|
||||
__builtin_abort ();
|
||||
|
||||
if (struct S s = { 42 }; s.i != 42)
|
||||
__builtin_abort ();
|
||||
|
||||
if (int i = 42)
|
||||
{
|
||||
i = 0;
|
||||
if (int j = 42)
|
||||
j = 0;
|
||||
else
|
||||
j = 42;
|
||||
}
|
||||
else
|
||||
i = 42;
|
||||
}
|
27
gcc/testsuite/gcc.dg/c2y-if-decls-6.c
Normal file
27
gcc/testsuite/gcc.dg/c2y-if-decls-6.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
/* N3356 - if declarations. */
|
||||
/* PR c/117019 */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-std=c2y -Wall -Wextra" } */
|
||||
/* Test VLAs. */
|
||||
|
||||
void foo (int) { }
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int i = 3;
|
||||
|
||||
if (int arr[i] = { }; !arr[0])
|
||||
foo (arr[0]);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
switch (int arr[i] = { }; arr[0])
|
||||
{
|
||||
case 0:
|
||||
foo (arr[0]);
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
}
|
||||
}
|
96
gcc/testsuite/gcc.dg/c2y-if-decls-7.c
Normal file
96
gcc/testsuite/gcc.dg/c2y-if-decls-7.c
Normal file
|
@ -0,0 +1,96 @@
|
|||
/* N3356 - if declarations. */
|
||||
/* PR c/117019 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=c2y -Wall -Wextra" } */
|
||||
/* Test VLAs. Invalid code. */
|
||||
|
||||
void foo (int) { }
|
||||
|
||||
void
|
||||
g ()
|
||||
{
|
||||
int i = 3;
|
||||
|
||||
switch (i) /* { dg-message "switch starts here" } */
|
||||
{ /* { dg-warning "statement will never be executed" } */
|
||||
int arr[i] = { };
|
||||
default: /* { dg-error "switch jumps into scope" } */
|
||||
i = arr[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
g2 (int i)
|
||||
{
|
||||
goto L1; /* { dg-error "jump into scope" } */
|
||||
if (int arr[i] = { }; arr[0])
|
||||
{
|
||||
L1:
|
||||
}
|
||||
|
||||
goto L2; /* { dg-error "jump into scope" } */
|
||||
if (int arr[i] = { }) /* { dg-warning "will always evaluate as .true." } */
|
||||
{
|
||||
L2:
|
||||
arr[0] = 42;
|
||||
}
|
||||
|
||||
goto L3; /* { dg-error "jump into scope" } */
|
||||
switch (int arr[i] = { }; arr[0])
|
||||
{
|
||||
case 0:
|
||||
L3:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
g3 (int i, int n)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
if (int arr[n] = { }) /* { dg-warning "will always evaluate as .true." } */
|
||||
{
|
||||
case 3: /* { dg-error "switch jumps into scope" } */
|
||||
arr[0] = 42;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
g4 (int i, int n)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
if (int arr[n] = { }; arr[0])
|
||||
{
|
||||
case 3: /* { dg-error "switch jumps into scope" } */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
g5 (int i, int n)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
goto L; /* { dg-error "jump into scope" } */
|
||||
switch (int arr[n] = { }; arr[0])
|
||||
{
|
||||
L:
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
168
gcc/testsuite/gcc.dg/c2y-if-decls-8.c
Normal file
168
gcc/testsuite/gcc.dg/c2y-if-decls-8.c
Normal file
|
@ -0,0 +1,168 @@
|
|||
/* N3356 - if declarations. */
|
||||
/* PR c/117019 */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-std=c2y -pedantic-errors" } */
|
||||
/* 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 ())
|
||||
foo (i);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
if (int i = 0)
|
||||
__builtin_abort ();
|
||||
else
|
||||
foo (i);
|
||||
|
||||
if (auto i = get ())
|
||||
foo (i);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
if (__typeof__(get ()) i = get ())
|
||||
foo (i);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
if (auto i = 0)
|
||||
__builtin_abort ();
|
||||
else
|
||||
foo (i);
|
||||
|
||||
if (int (*f)(int) = foo)
|
||||
f (1);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
if ([[maybe_unused]] int i = get ())
|
||||
foo (i);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
if (__attribute__((unused)) int i = get ())
|
||||
foo (i);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
if (enum E e = X)
|
||||
foo (e);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
if (constexpr int i = 42)
|
||||
foo (i);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
if (int i = 1)
|
||||
if (int j = 2)
|
||||
if (int k = 3)
|
||||
foo (i + j + k);
|
||||
|
||||
if (register int i = 0);
|
||||
if (static int i = 0);
|
||||
if (static int arr[3] = {});
|
||||
if (_Atomic int i = 0);
|
||||
|
||||
if (int arr[] = { 1 })
|
||||
foo (arr[0]);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
double i;
|
||||
}
|
||||
|
||||
void
|
||||
expr ()
|
||||
{
|
||||
if (int i = get (); i == 42)
|
||||
foo (i);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
if (int i = get (); i != 42)
|
||||
__builtin_abort ();
|
||||
else
|
||||
foo (i);
|
||||
|
||||
if (auto i = get (); i == 42)
|
||||
foo (i);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
if (__typeof__(get ()) i = get (); i == 42)
|
||||
foo (i);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
if (auto i = get (); i != 42)
|
||||
__builtin_abort ();
|
||||
else
|
||||
foo (i);
|
||||
|
||||
if (int (*f)(int) = foo; f (42))
|
||||
f (1);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
if ([[maybe_unused]] int i = get (); i == 42)
|
||||
foo (i);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
if (__attribute__((unused)) int i = get (); i == 42)
|
||||
foo (i);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
if (enum E e = X; e == X)
|
||||
foo (e);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
if (constexpr int i = 42; i == 42)
|
||||
foo (i);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
if (int i = 1; i)
|
||||
if (int j = 2; j)
|
||||
if (int k = 3; k)
|
||||
foo (i + j + k);
|
||||
|
||||
if (int i = 2, j = get (); i + j > 0)
|
||||
foo (i + j);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
if (int i; i = 1)
|
||||
foo (i);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
if (int arr[] = { 1, 2, 3}; arr[0])
|
||||
foo (arr[0]);
|
||||
else
|
||||
__builtin_abort ();
|
||||
|
||||
if (register int i = 0; i);
|
||||
if (static int i = 0; i);
|
||||
if (_Atomic int i = 0; i);
|
||||
|
||||
double i;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
simple ();
|
||||
expr ();
|
||||
}
|
35
gcc/testsuite/gcc.dg/c2y-if-decls-9.c
Normal file
35
gcc/testsuite/gcc.dg/c2y-if-decls-9.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* 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)
|
||||
{
|
||||
if (;); /* { dg-error "expected" } */
|
||||
if (int); /* { dg-error "expected|initializer" } */
|
||||
if (auto); /* { dg-error "expected|initializer" } */
|
||||
if (int;); /* { dg-error "initializer" } */
|
||||
/* { dg-error "empty" "" { target *-*-* } .-1 } */
|
||||
if (auto;); /* { dg-error "empty|initializer" } */
|
||||
if (int i); /* { dg-error "initializer" } */
|
||||
if (int i;); /* { dg-error "expected" } */
|
||||
if (int i = 0;); /* { dg-error "expected" } */
|
||||
|
||||
if (extern int i = 0); /* { dg-error "both .extern. and initializer" } */
|
||||
if (extern int i); /* { dg-error "initializer" } */
|
||||
if (thread_local int i = 0); /* { dg-error "function-scope" } */
|
||||
if (typedef int i); /* { dg-error "initializer" } */
|
||||
if (typedef int i = 0); /* { dg-error "initialized" } */
|
||||
|
||||
if (int i = 2, j = 3); /* { dg-error "only declare a single object" } */
|
||||
|
||||
if (void (*fp)(int)); /* { dg-error "initializer" } */
|
||||
if ([[maybe_unused]] g); /* { dg-error "expected" } */
|
||||
if ([[maybe_unused]] 42); /* { dg-error "expected" } */
|
||||
if ([[maybe_unused]] int); /* { dg-error "expected|initializer" } */
|
||||
if (__attribute__((unused)) g); /* { dg-error "initializer" } */
|
||||
if (__attribute__((unused)) 42); /* { dg-error "expected|initializer" } */
|
||||
if (__attribute__((unused)) int); /* { dg-error "expected|initializer" } */
|
||||
}
|
15
gcc/testsuite/gcc.dg/gnu2y-if-decls-1.c
Normal file
15
gcc/testsuite/gcc.dg/gnu2y-if-decls-1.c
Normal file
|
@ -0,0 +1,15 @@
|
|||
/* N3356 - if declarations. */
|
||||
/* PR c/117019 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=gnu2y" } */
|
||||
|
||||
void
|
||||
g ()
|
||||
{
|
||||
if (int i = 42);
|
||||
if (int i = 42; i > 10);
|
||||
if (int i, j; i = 42);
|
||||
switch (int i = 42);
|
||||
switch (int i = 42; i);
|
||||
switch (int i, j; i = 42);
|
||||
}
|
15
gcc/testsuite/gcc.dg/gnu99-if-decls-1.c
Normal file
15
gcc/testsuite/gcc.dg/gnu99-if-decls-1.c
Normal file
|
@ -0,0 +1,15 @@
|
|||
/* N3356 - if declarations. */
|
||||
/* PR c/117019 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=gnu99 -Wpedantic" } */
|
||||
|
||||
void
|
||||
g ()
|
||||
{
|
||||
if (int i = 42); /* { dg-warning "ISO C does not support if declarations before C2Y" } */
|
||||
if (int i = 42; i > 10); /* { dg-warning "ISO C does not support if declarations before C2Y" } */
|
||||
if (int i, j; i = 42); /* { dg-warning "ISO C does not support if declarations before C2Y" } */
|
||||
switch (int i = 42); /* { dg-warning "ISO C does not support if declarations before C2Y" } */
|
||||
switch (int i = 42; i); /* { dg-warning "ISO C does not support if declarations before C2Y" } */
|
||||
switch (int i, j; i = 42); /* { dg-warning "ISO C does not support if declarations before C2Y" } */
|
||||
}
|
15
gcc/testsuite/gcc.dg/gnu99-if-decls-2.c
Normal file
15
gcc/testsuite/gcc.dg/gnu99-if-decls-2.c
Normal file
|
@ -0,0 +1,15 @@
|
|||
/* N3356 - if declarations. */
|
||||
/* PR c/117019 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=gnu99" } */
|
||||
|
||||
void
|
||||
g ()
|
||||
{
|
||||
if (int i = 42);
|
||||
if (int i = 42; i > 10);
|
||||
if (int i, j; i = 42);
|
||||
switch (int i = 42);
|
||||
switch (int i = 42; i);
|
||||
switch (int i, j; i = 42);
|
||||
}
|
Loading…
Add table
Reference in a new issue