mirror of git://gcc.gnu.org/git/gcc.git
Implement P0305R1, Selection statements with initializer.
* cp-array-notation.c (create_an_loop): Call finish_init_stmt instead of finish_for_init_stmt. * cp-tree.h (finish_for_init_stmt): Rename to finish_init_stmt. * decl.c (poplevel): Adjust a comment. * init.c (build_vec_init): Call finish_init_stmt instead of finish_for_init_stmt. * name-lookup.c (pushdecl_maybe_friend_1): Adjust a comment. * name-lookup.h (enum scope_kind): Likewise. * parser.c (cp_parser_statement): Update commentary. (cp_parser_init_statement_p): New function. (cp_parser_selection_statement): Parse the optional init-statement. (cp_parser_for): Call finish_init_stmt instead of finish_for_init_stmt. (cp_parser_c_for): Likewise. (cp_convert_range_for): Call finish_init_stmt instead of finish_for_init_stmt. (cp_parser_range_for_member_function): Update commentary. (cp_parser_iteration_statement): (cp_parser_for_init_statement): Rename to cp_parser_init_statement. * pt.c (tsubst_omp_for_iterator): Update commentary. (tsubst_expr): Call finish_init_stmt instead of finish_for_init_stmt. * semantics.c (finish_for_init_stmt): Rename to finish_init_stmt. Update commentary. * g++.dg/cpp1z/init-statement1.C: New test. * g++.dg/cpp1z/init-statement2.C: New test. * g++.dg/cpp1z/init-statement3.C: New test. * g++.dg/cpp1z/init-statement4.C: New test. * g++.dg/cpp1z/init-statement5.C: New test. * g++.dg/cpp1z/init-statement6.C: New test. * g++.dg/cpp1z/init-statement7.C: New test. * g++.dg/cpp1z/init-statement8.C: New test. From-SVN: r240798
This commit is contained in:
parent
6e48e779ab
commit
17a9e3802a
|
|
@ -1,3 +1,28 @@
|
||||||
|
2016-10-05 Marek Polacek <polacek@redhat.com>
|
||||||
|
|
||||||
|
Implement P0305R1, Selection statements with initializer.
|
||||||
|
* cp-array-notation.c (create_an_loop): Call finish_init_stmt
|
||||||
|
instead of finish_for_init_stmt.
|
||||||
|
* cp-tree.h (finish_for_init_stmt): Rename to finish_init_stmt.
|
||||||
|
* decl.c (poplevel): Adjust a comment.
|
||||||
|
* init.c (build_vec_init): Call finish_init_stmt instead of
|
||||||
|
finish_for_init_stmt.
|
||||||
|
* name-lookup.c (pushdecl_maybe_friend_1): Adjust a comment.
|
||||||
|
* name-lookup.h (enum scope_kind): Likewise.
|
||||||
|
* parser.c (cp_parser_statement): Update commentary.
|
||||||
|
(cp_parser_init_statement_p): New function.
|
||||||
|
(cp_parser_selection_statement): Parse the optional init-statement.
|
||||||
|
(cp_parser_for): Call finish_init_stmt instead of finish_for_init_stmt.
|
||||||
|
(cp_parser_c_for): Likewise.
|
||||||
|
(cp_convert_range_for): Call finish_init_stmt instead of finish_for_init_stmt.
|
||||||
|
(cp_parser_range_for_member_function): Update commentary.
|
||||||
|
(cp_parser_iteration_statement):
|
||||||
|
(cp_parser_for_init_statement): Rename to cp_parser_init_statement.
|
||||||
|
* pt.c (tsubst_omp_for_iterator): Update commentary.
|
||||||
|
(tsubst_expr): Call finish_init_stmt instead of finish_for_init_stmt.
|
||||||
|
* semantics.c (finish_for_init_stmt): Rename to finish_init_stmt.
|
||||||
|
Update commentary.
|
||||||
|
|
||||||
2016-10-04 Jason Merrill <jason@redhat.com>
|
2016-10-04 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
PR c++/77852
|
PR c++/77852
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ create_an_loop (tree init, tree cond, tree incr, tree body)
|
||||||
|
|
||||||
finish_expr_stmt (init);
|
finish_expr_stmt (init);
|
||||||
for_stmt = begin_for_stmt (NULL_TREE, NULL_TREE);
|
for_stmt = begin_for_stmt (NULL_TREE, NULL_TREE);
|
||||||
finish_for_init_stmt (for_stmt);
|
finish_init_stmt (for_stmt);
|
||||||
finish_for_cond (cond, for_stmt, false);
|
finish_for_cond (cond, for_stmt, false);
|
||||||
finish_for_expr (incr, for_stmt);
|
finish_for_expr (incr, for_stmt);
|
||||||
finish_expr_stmt (body);
|
finish_expr_stmt (body);
|
||||||
|
|
|
||||||
|
|
@ -6297,7 +6297,7 @@ extern void finish_do_stmt (tree, tree, bool);
|
||||||
extern tree finish_return_stmt (tree);
|
extern tree finish_return_stmt (tree);
|
||||||
extern tree begin_for_scope (tree *);
|
extern tree begin_for_scope (tree *);
|
||||||
extern tree begin_for_stmt (tree, tree);
|
extern tree begin_for_stmt (tree, tree);
|
||||||
extern void finish_for_init_stmt (tree);
|
extern void finish_init_stmt (tree);
|
||||||
extern void finish_for_cond (tree, tree, bool);
|
extern void finish_for_cond (tree, tree, bool);
|
||||||
extern void finish_for_expr (tree, tree);
|
extern void finish_for_expr (tree, tree);
|
||||||
extern void finish_for_stmt (tree);
|
extern void finish_for_stmt (tree);
|
||||||
|
|
|
||||||
|
|
@ -639,9 +639,8 @@ poplevel (int keep, int reverse, int functionbody)
|
||||||
BLOCK_SUPERCONTEXT (link) = block;
|
BLOCK_SUPERCONTEXT (link) = block;
|
||||||
|
|
||||||
/* We still support the old for-scope rules, whereby the variables
|
/* We still support the old for-scope rules, whereby the variables
|
||||||
in a for-init statement were in scope after the for-statement
|
in a init statement were in scope after the for-statement ended.
|
||||||
ended. We only use the new rules if flag_new_for_scope is
|
We only use the new rules if flag_new_for_scope is nonzero. */
|
||||||
nonzero. */
|
|
||||||
leaving_for_scope
|
leaving_for_scope
|
||||||
= current_binding_level->kind == sk_for && flag_new_for_scope == 1;
|
= current_binding_level->kind == sk_for && flag_new_for_scope == 1;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4052,7 +4052,7 @@ build_vec_init (tree base, tree maxindex, tree init,
|
||||||
tree to;
|
tree to;
|
||||||
|
|
||||||
for_stmt = begin_for_stmt (NULL_TREE, NULL_TREE);
|
for_stmt = begin_for_stmt (NULL_TREE, NULL_TREE);
|
||||||
finish_for_init_stmt (for_stmt);
|
finish_init_stmt (for_stmt);
|
||||||
finish_for_cond (build2 (GT_EXPR, boolean_type_node, iterator,
|
finish_for_cond (build2 (GT_EXPR, boolean_type_node, iterator,
|
||||||
build_int_cst (TREE_TYPE (iterator), -1)),
|
build_int_cst (TREE_TYPE (iterator), -1)),
|
||||||
for_stmt, false);
|
for_stmt, false);
|
||||||
|
|
|
||||||
|
|
@ -1156,7 +1156,7 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Error if redeclaring a local declared in a
|
/* Error if redeclaring a local declared in a
|
||||||
for-init-statement or in the condition of an if or
|
init-statement or in the condition of an if or
|
||||||
switch statement when the new declaration is in the
|
switch statement when the new declaration is in the
|
||||||
outermost block of the controlled statement.
|
outermost block of the controlled statement.
|
||||||
Redeclaring a variable from a for or while condition is
|
Redeclaring a variable from a for or while condition is
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ enum scope_kind {
|
||||||
sk_try, /* A try-block. */
|
sk_try, /* A try-block. */
|
||||||
sk_catch, /* A catch-block. */
|
sk_catch, /* A catch-block. */
|
||||||
sk_for, /* The scope of the variable declared in a
|
sk_for, /* The scope of the variable declared in a
|
||||||
for-init-statement. */
|
init-statement. */
|
||||||
sk_cond, /* The scope of the variable declared in the condition
|
sk_cond, /* The scope of the variable declared in the condition
|
||||||
of an if or switch statement. */
|
of an if or switch statement. */
|
||||||
sk_function_parms, /* The scope containing function parameters. */
|
sk_function_parms, /* The scope containing function parameters. */
|
||||||
|
|
|
||||||
|
|
@ -2117,7 +2117,7 @@ static tree cp_parser_condition
|
||||||
(cp_parser *);
|
(cp_parser *);
|
||||||
static tree cp_parser_iteration_statement
|
static tree cp_parser_iteration_statement
|
||||||
(cp_parser *, bool *, bool);
|
(cp_parser *, bool *, bool);
|
||||||
static bool cp_parser_for_init_statement
|
static bool cp_parser_init_statement
|
||||||
(cp_parser *, tree *decl);
|
(cp_parser *, tree *decl);
|
||||||
static tree cp_parser_for
|
static tree cp_parser_for
|
||||||
(cp_parser *, bool);
|
(cp_parser *, bool);
|
||||||
|
|
@ -2642,6 +2642,8 @@ static bool cp_parser_compound_literal_p
|
||||||
(cp_parser *);
|
(cp_parser *);
|
||||||
static bool cp_parser_array_designator_p
|
static bool cp_parser_array_designator_p
|
||||||
(cp_parser *);
|
(cp_parser *);
|
||||||
|
static bool cp_parser_init_statement_p
|
||||||
|
(cp_parser *);
|
||||||
static bool cp_parser_skip_to_closing_square_bracket
|
static bool cp_parser_skip_to_closing_square_bracket
|
||||||
(cp_parser *);
|
(cp_parser *);
|
||||||
|
|
||||||
|
|
@ -10396,6 +10398,10 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
|
||||||
declaration-statement
|
declaration-statement
|
||||||
attribute-specifier-seq (opt) try-block
|
attribute-specifier-seq (opt) try-block
|
||||||
|
|
||||||
|
init-statement:
|
||||||
|
expression-statement
|
||||||
|
simple-declaration
|
||||||
|
|
||||||
TM Extension:
|
TM Extension:
|
||||||
|
|
||||||
statement:
|
statement:
|
||||||
|
|
@ -10936,12 +10942,32 @@ cp_parser_statement_seq_opt (cp_parser* parser, tree in_statement_expr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return true if we're looking at (init; cond), false otherwise. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cp_parser_init_statement_p (cp_parser *parser)
|
||||||
|
{
|
||||||
|
/* Save tokens so that we can put them back. */
|
||||||
|
cp_lexer_save_tokens (parser->lexer);
|
||||||
|
|
||||||
|
/* Look for ';' that is not nested in () or {}. */
|
||||||
|
int ret = cp_parser_skip_to_closing_parenthesis_1 (parser,
|
||||||
|
/*recovering=*/false,
|
||||||
|
CPP_SEMICOLON,
|
||||||
|
/*consume_paren=*/false);
|
||||||
|
|
||||||
|
/* Roll back the tokens we skipped. */
|
||||||
|
cp_lexer_rollback_tokens (parser->lexer);
|
||||||
|
|
||||||
|
return ret == -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse a selection-statement.
|
/* Parse a selection-statement.
|
||||||
|
|
||||||
selection-statement:
|
selection-statement:
|
||||||
if ( condition ) statement
|
if ( init-statement [opt] condition ) statement
|
||||||
if ( condition ) statement else statement
|
if ( init-statement [opt] condition ) statement else statement
|
||||||
switch ( condition ) statement
|
switch ( init-statement [opt] condition ) statement
|
||||||
|
|
||||||
Returns the new IF_STMT or SWITCH_STMT.
|
Returns the new IF_STMT or SWITCH_STMT.
|
||||||
|
|
||||||
|
|
@ -11006,6 +11032,17 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p,
|
||||||
else
|
else
|
||||||
statement = begin_switch_stmt ();
|
statement = begin_switch_stmt ();
|
||||||
|
|
||||||
|
/* Parse the optional init-statement. */
|
||||||
|
if (cp_parser_init_statement_p (parser))
|
||||||
|
{
|
||||||
|
tree decl;
|
||||||
|
if (cxx_dialect < cxx1z)
|
||||||
|
pedwarn (cp_lexer_peek_token (parser->lexer)->location, 0,
|
||||||
|
"init-statement in selection statements only available "
|
||||||
|
"with -std=c++1z or -std=gnu++1z");
|
||||||
|
cp_parser_init_statement (parser, &decl);
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse the condition. */
|
/* Parse the condition. */
|
||||||
condition = cp_parser_condition (parser);
|
condition = cp_parser_condition (parser);
|
||||||
/* Look for the `)'. */
|
/* Look for the `)'. */
|
||||||
|
|
@ -11306,7 +11343,7 @@ cp_parser_for (cp_parser *parser, bool ivdep)
|
||||||
scope = begin_for_scope (&init);
|
scope = begin_for_scope (&init);
|
||||||
|
|
||||||
/* Parse the initialization. */
|
/* Parse the initialization. */
|
||||||
is_range_for = cp_parser_for_init_statement (parser, &decl);
|
is_range_for = cp_parser_init_statement (parser, &decl);
|
||||||
|
|
||||||
if (is_range_for)
|
if (is_range_for)
|
||||||
return cp_parser_range_for (parser, scope, init, decl, ivdep);
|
return cp_parser_range_for (parser, scope, init, decl, ivdep);
|
||||||
|
|
@ -11323,9 +11360,9 @@ cp_parser_c_for (cp_parser *parser, tree scope, tree init, bool ivdep)
|
||||||
tree stmt;
|
tree stmt;
|
||||||
|
|
||||||
stmt = begin_for_stmt (scope, init);
|
stmt = begin_for_stmt (scope, init);
|
||||||
/* The for-init-statement has already been parsed in
|
/* The init-statement has already been parsed in
|
||||||
cp_parser_for_init_statement, so no work is needed here. */
|
cp_parser_init_statement, so no work is needed here. */
|
||||||
finish_for_init_stmt (stmt);
|
finish_init_stmt (stmt);
|
||||||
|
|
||||||
/* If there's a condition, process it. */
|
/* If there's a condition, process it. */
|
||||||
if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
|
if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
|
||||||
|
|
@ -11354,7 +11391,7 @@ cp_parser_c_for (cp_parser *parser, tree scope, tree init, bool ivdep)
|
||||||
decl-specifier-seq declarator : expression
|
decl-specifier-seq declarator : expression
|
||||||
|
|
||||||
The decl-specifier-seq declarator and the `:' are already parsed by
|
The decl-specifier-seq declarator and the `:' are already parsed by
|
||||||
cp_parser_for_init_statement. If processing_template_decl it returns a
|
cp_parser_init_statement. If processing_template_decl it returns a
|
||||||
newly created RANGE_FOR_STMT; if not, it is converted to a
|
newly created RANGE_FOR_STMT; if not, it is converted to a
|
||||||
regular FOR_STMT. */
|
regular FOR_STMT. */
|
||||||
|
|
||||||
|
|
@ -11552,7 +11589,7 @@ cp_convert_range_for (tree statement, tree range_decl, tree range_expr,
|
||||||
/*is_constant_init*/false, NULL_TREE,
|
/*is_constant_init*/false, NULL_TREE,
|
||||||
LOOKUP_ONLYCONVERTING);
|
LOOKUP_ONLYCONVERTING);
|
||||||
|
|
||||||
finish_for_init_stmt (statement);
|
finish_init_stmt (statement);
|
||||||
|
|
||||||
/* The new for condition. */
|
/* The new for condition. */
|
||||||
condition = build_x_binary_op (input_location, NE_EXPR,
|
condition = build_x_binary_op (input_location, NE_EXPR,
|
||||||
|
|
@ -11726,7 +11763,7 @@ cp_parser_range_for_member_function (tree range, tree identifier)
|
||||||
iteration-statement:
|
iteration-statement:
|
||||||
while ( condition ) statement
|
while ( condition ) statement
|
||||||
do statement while ( expression ) ;
|
do statement while ( expression ) ;
|
||||||
for ( for-init-statement condition [opt] ; expression [opt] )
|
for ( init-statement condition [opt] ; expression [opt] )
|
||||||
statement
|
statement
|
||||||
|
|
||||||
Returns the new WHILE_STMT, DO_STMT, FOR_STMT or RANGE_FOR_STMT. */
|
Returns the new WHILE_STMT, DO_STMT, FOR_STMT or RANGE_FOR_STMT. */
|
||||||
|
|
@ -11832,15 +11869,15 @@ cp_parser_iteration_statement (cp_parser* parser, bool *if_p, bool ivdep)
|
||||||
return statement;
|
return statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse a for-init-statement or the declarator of a range-based-for.
|
/* Parse a init-statement or the declarator of a range-based-for.
|
||||||
Returns true if a range-based-for declaration is seen.
|
Returns true if a range-based-for declaration is seen.
|
||||||
|
|
||||||
for-init-statement:
|
init-statement:
|
||||||
expression-statement
|
expression-statement
|
||||||
simple-declaration */
|
simple-declaration */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
cp_parser_for_init_statement (cp_parser* parser, tree *decl)
|
cp_parser_init_statement (cp_parser* parser, tree *decl)
|
||||||
{
|
{
|
||||||
/* If the next token is a `;', then we have an empty
|
/* If the next token is a `;', then we have an empty
|
||||||
expression-statement. Grammatically, this is also a
|
expression-statement. Grammatically, this is also a
|
||||||
|
|
|
||||||
|
|
@ -14974,7 +14974,7 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree orig_declv,
|
||||||
if (init && TREE_CODE (init) == DECL_EXPR)
|
if (init && TREE_CODE (init) == DECL_EXPR)
|
||||||
{
|
{
|
||||||
/* We need to jump through some hoops to handle declarations in the
|
/* We need to jump through some hoops to handle declarations in the
|
||||||
for-init-statement, since we might need to handle auto deduction,
|
init-statement, since we might need to handle auto deduction,
|
||||||
but we need to keep control of initialization. */
|
but we need to keep control of initialization. */
|
||||||
decl_expr = init;
|
decl_expr = init;
|
||||||
init = DECL_INITIAL (DECL_EXPR_DECL (init));
|
init = DECL_INITIAL (DECL_EXPR_DECL (init));
|
||||||
|
|
@ -15359,7 +15359,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
|
||||||
case FOR_STMT:
|
case FOR_STMT:
|
||||||
stmt = begin_for_stmt (NULL_TREE, NULL_TREE);
|
stmt = begin_for_stmt (NULL_TREE, NULL_TREE);
|
||||||
RECUR (FOR_INIT_STMT (t));
|
RECUR (FOR_INIT_STMT (t));
|
||||||
finish_for_init_stmt (stmt);
|
finish_init_stmt (stmt);
|
||||||
tmp = RECUR (FOR_COND (t));
|
tmp = RECUR (FOR_COND (t));
|
||||||
finish_for_cond (tmp, stmt, false);
|
finish_for_cond (tmp, stmt, false);
|
||||||
tmp = RECUR (FOR_EXPR (t));
|
tmp = RECUR (FOR_EXPR (t));
|
||||||
|
|
|
||||||
|
|
@ -953,11 +953,11 @@ begin_for_stmt (tree scope, tree init)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finish the for-init-statement of a for-statement, which may be
|
/* Finish the init-statement of a for-statement, which may be
|
||||||
given by FOR_STMT. */
|
given by FOR_STMT. */
|
||||||
|
|
||||||
void
|
void
|
||||||
finish_for_init_stmt (tree for_stmt)
|
finish_init_stmt (tree for_stmt)
|
||||||
{
|
{
|
||||||
if (processing_template_decl)
|
if (processing_template_decl)
|
||||||
FOR_INIT_STMT (for_stmt) = pop_stmt_list (FOR_INIT_STMT (for_stmt));
|
FOR_INIT_STMT (for_stmt) = pop_stmt_list (FOR_INIT_STMT (for_stmt));
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,14 @@
|
||||||
|
2016-10-05 Marek Polacek <polacek@redhat.com>
|
||||||
|
|
||||||
|
* g++.dg/cpp1z/init-statement1.C: New test.
|
||||||
|
* g++.dg/cpp1z/init-statement2.C: New test.
|
||||||
|
* g++.dg/cpp1z/init-statement3.C: New test.
|
||||||
|
* g++.dg/cpp1z/init-statement4.C: New test.
|
||||||
|
* g++.dg/cpp1z/init-statement5.C: New test.
|
||||||
|
* g++.dg/cpp1z/init-statement6.C: New test.
|
||||||
|
* g++.dg/cpp1z/init-statement7.C: New test.
|
||||||
|
* g++.dg/cpp1z/init-statement8.C: New test.
|
||||||
|
|
||||||
2016-10-05 Louis Krupp <louis.krupp@zoho.com>
|
2016-10-05 Louis Krupp <louis.krupp@zoho.com>
|
||||||
|
|
||||||
PR fortran/67524
|
PR fortran/67524
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
// { dg-do compile { target c++11 } }
|
||||||
|
// { dg-options "" }
|
||||||
|
|
||||||
|
extern int foo (void);
|
||||||
|
extern void bar (int);
|
||||||
|
|
||||||
|
void
|
||||||
|
f (void)
|
||||||
|
{
|
||||||
|
if (auto p = foo (); p > 10) // { dg-warning "init-statement" "" { target c++14_down } }
|
||||||
|
bar (p);
|
||||||
|
else
|
||||||
|
bar (-p);
|
||||||
|
}
|
||||||
|
// { dg-do compile { target c++11 } }
|
||||||
|
// { dg-options "" }
|
||||||
|
|
||||||
|
extern int foo (void);
|
||||||
|
extern void bar (int);
|
||||||
|
|
||||||
|
void
|
||||||
|
f (void)
|
||||||
|
{
|
||||||
|
if (auto p = foo (); p > 10) // { dg-warning "init-statement" "" { target c++14_down } }
|
||||||
|
bar (p);
|
||||||
|
else
|
||||||
|
bar (-p);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,124 @@
|
||||||
|
// { dg-options -std=c++1z }
|
||||||
|
// Test C++17 selection statements with initializer, basic use.
|
||||||
|
|
||||||
|
extern int foo (void);
|
||||||
|
extern void bar (int);
|
||||||
|
extern int g;
|
||||||
|
|
||||||
|
void
|
||||||
|
f (void)
|
||||||
|
{
|
||||||
|
if (auto p = foo (); p > 10)
|
||||||
|
bar (p);
|
||||||
|
else
|
||||||
|
bar (-p);
|
||||||
|
|
||||||
|
if ((g += 2); g > 6)
|
||||||
|
bar (1);
|
||||||
|
|
||||||
|
if (auto a = 9, b = foo (); a + b > 10)
|
||||||
|
bar (a + b);
|
||||||
|
else
|
||||||
|
bar (a - b);
|
||||||
|
|
||||||
|
if (({ int a; 1;}))
|
||||||
|
bar (0);
|
||||||
|
|
||||||
|
if (auto i = foo (); i > 6)
|
||||||
|
bar (0);
|
||||||
|
else if (i++; i > 8)
|
||||||
|
bar (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void lock (void);
|
||||||
|
|
||||||
|
void
|
||||||
|
f2 (int i)
|
||||||
|
{
|
||||||
|
if (lock (); i > 10)
|
||||||
|
++i;
|
||||||
|
else
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f3 (int i)
|
||||||
|
{
|
||||||
|
switch (i *= 2; auto idx = i)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
bar (3);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f4 (void)
|
||||||
|
{
|
||||||
|
if constexpr (constexpr auto s = sizeof (int); s > 10)
|
||||||
|
foo ();
|
||||||
|
}
|
||||||
|
// { dg-options -std=c++1z }
|
||||||
|
// Test C++17 selection statements with initializer, basic use.
|
||||||
|
|
||||||
|
extern int foo (void);
|
||||||
|
extern void bar (int);
|
||||||
|
extern int g;
|
||||||
|
|
||||||
|
void
|
||||||
|
f (void)
|
||||||
|
{
|
||||||
|
if (auto p = foo (); p > 10)
|
||||||
|
bar (p);
|
||||||
|
else
|
||||||
|
bar (-p);
|
||||||
|
|
||||||
|
if ((g += 2); g > 6)
|
||||||
|
bar (1);
|
||||||
|
|
||||||
|
if (auto a = 9, b = foo (); a + b > 10)
|
||||||
|
bar (a + b);
|
||||||
|
else
|
||||||
|
bar (a - b);
|
||||||
|
|
||||||
|
if (({ int a; 1;}))
|
||||||
|
bar (0);
|
||||||
|
|
||||||
|
if (auto i = foo (); i > 6)
|
||||||
|
bar (0);
|
||||||
|
else if (i++; i > 8)
|
||||||
|
bar (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void lock (void);
|
||||||
|
|
||||||
|
void
|
||||||
|
f2 (int i)
|
||||||
|
{
|
||||||
|
if (lock (); i > 10)
|
||||||
|
++i;
|
||||||
|
else
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f3 (int i)
|
||||||
|
{
|
||||||
|
switch (i *= 2; auto idx = i)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
bar (3);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f4 (void)
|
||||||
|
{
|
||||||
|
if constexpr (constexpr auto s = sizeof (int); s > 10)
|
||||||
|
foo ();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
// { dg-do run }
|
||||||
|
// { dg-options -std=c++1z }
|
||||||
|
// Test C++17 selection statements with initializer, side-effects.
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
int g = 0;
|
||||||
|
|
||||||
|
if (g++; g > 1)
|
||||||
|
__builtin_abort ();
|
||||||
|
if (++g; g > 2)
|
||||||
|
__builtin_abort ();
|
||||||
|
if (g != 2)
|
||||||
|
__builtin_abort ();
|
||||||
|
}
|
||||||
|
// { dg-do run }
|
||||||
|
// { dg-options -std=c++1z }
|
||||||
|
// Test C++17 selection statements with initializer, side-effects.
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
int g = 0;
|
||||||
|
|
||||||
|
if (g++; g > 1)
|
||||||
|
__builtin_abort ();
|
||||||
|
if (++g; g > 2)
|
||||||
|
__builtin_abort ();
|
||||||
|
if (g != 2)
|
||||||
|
__builtin_abort ();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,118 @@
|
||||||
|
// { dg-options -std=c++1z }
|
||||||
|
|
||||||
|
extern int foo (void);
|
||||||
|
extern void bar (int), die (void);
|
||||||
|
|
||||||
|
void
|
||||||
|
f (void)
|
||||||
|
{
|
||||||
|
if (auto i = foo (); i != -1)
|
||||||
|
bar (1);
|
||||||
|
else
|
||||||
|
die ();
|
||||||
|
|
||||||
|
i = 10; // { dg-error "not declared" }
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f2 (void)
|
||||||
|
{
|
||||||
|
switch (auto i = foo (); i)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
bar (i + 1);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
bar (i + 10);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 10; // { dg-error "not declared" }
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f3 (void)
|
||||||
|
{
|
||||||
|
if constexpr (constexpr auto i = sizeof (long); i < 2)
|
||||||
|
die ();
|
||||||
|
i = 4; // { dg-error "not declared" }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
f4 (void)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
if (auto i = foo (); i > -1)
|
||||||
|
{
|
||||||
|
if (i > 5)
|
||||||
|
bar (i);
|
||||||
|
if (auto j = foo (); true)
|
||||||
|
j++;
|
||||||
|
j--; // { dg-error "not declared" }
|
||||||
|
}
|
||||||
|
i = 10; // { dg-error "not declared" }
|
||||||
|
}
|
||||||
|
i = 10; // { dg-error "not declared" }
|
||||||
|
}
|
||||||
|
// { dg-options -std=c++1z }
|
||||||
|
|
||||||
|
extern int foo (void);
|
||||||
|
extern void bar (int), die (void);
|
||||||
|
|
||||||
|
void
|
||||||
|
f (void)
|
||||||
|
{
|
||||||
|
if (auto i = foo (); i != -1)
|
||||||
|
bar (1);
|
||||||
|
else
|
||||||
|
die ();
|
||||||
|
|
||||||
|
i = 10; // { dg-error "not declared" }
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f2 (void)
|
||||||
|
{
|
||||||
|
switch (auto i = foo (); i)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
bar (i + 1);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
bar (i + 10);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 10; // { dg-error "not declared" }
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f3 (void)
|
||||||
|
{
|
||||||
|
if constexpr (constexpr auto i = sizeof (long); i < 2)
|
||||||
|
die ();
|
||||||
|
i = 4; // { dg-error "not declared" }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
f4 (void)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
if (auto i = foo (); i > -1)
|
||||||
|
{
|
||||||
|
if (i > 5)
|
||||||
|
bar (i);
|
||||||
|
if (auto j = foo (); true)
|
||||||
|
j++;
|
||||||
|
j--; // { dg-error "not declared" }
|
||||||
|
}
|
||||||
|
i = 10; // { dg-error "not declared" }
|
||||||
|
}
|
||||||
|
i = 10; // { dg-error "not declared" }
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Testcase from P0305R1
|
||||||
|
// { dg-options -std=c++1z }
|
||||||
|
|
||||||
|
enum class status_code { SUCCESS };
|
||||||
|
extern int get_value ();
|
||||||
|
status_code bar (int);
|
||||||
|
status_code do_more_stuff (void);
|
||||||
|
|
||||||
|
status_code
|
||||||
|
foo ()
|
||||||
|
{
|
||||||
|
int n = get_value ();
|
||||||
|
if (status_code c = bar (n); c != status_code::SUCCESS) { return c; }
|
||||||
|
if (status_code c = do_more_stuff (); c != status_code::SUCCESS) { return c; }
|
||||||
|
return status_code::SUCCESS;
|
||||||
|
}
|
||||||
|
// Testcase from P0305R1
|
||||||
|
// { dg-options -std=c++1z }
|
||||||
|
|
||||||
|
enum class status_code { SUCCESS };
|
||||||
|
extern int get_value ();
|
||||||
|
status_code bar (int);
|
||||||
|
status_code do_more_stuff (void);
|
||||||
|
|
||||||
|
status_code
|
||||||
|
foo ()
|
||||||
|
{
|
||||||
|
int n = get_value ();
|
||||||
|
if (status_code c = bar (n); c != status_code::SUCCESS) { return c; }
|
||||||
|
if (status_code c = do_more_stuff (); c != status_code::SUCCESS) { return c; }
|
||||||
|
return status_code::SUCCESS;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
// Testcase from P0305R1
|
||||||
|
// { dg-options -std=c++1z }
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
std::map<int, std::string> m;
|
||||||
|
extern int xread (int *);
|
||||||
|
extern void publish (int), raise (int);
|
||||||
|
|
||||||
|
void
|
||||||
|
foo ()
|
||||||
|
{
|
||||||
|
if (auto it = m.find (10); it != m.end ()) { std::string s = it->second; }
|
||||||
|
if (char buf[10]; std::fgets(buf, 10, stdin)) { m[0] += buf; }
|
||||||
|
if (int s; int count = xread (&s)) { publish(count); raise(s); }
|
||||||
|
|
||||||
|
const char *s;
|
||||||
|
if (auto keywords = {"if", "for", "while"};
|
||||||
|
std::any_of(keywords.begin(), keywords.end(), [&s](const char* kw) { return s == kw; }))
|
||||||
|
{
|
||||||
|
// whatever
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Testcase from P0305R1
|
||||||
|
// { dg-options -std=c++1z }
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
std::map<int, std::string> m;
|
||||||
|
extern int xread (int *);
|
||||||
|
extern void publish (int), raise (int);
|
||||||
|
|
||||||
|
void
|
||||||
|
foo ()
|
||||||
|
{
|
||||||
|
if (auto it = m.find (10); it != m.end ()) { std::string s = it->second; }
|
||||||
|
if (char buf[10]; std::fgets(buf, 10, stdin)) { m[0] += buf; }
|
||||||
|
if (int s; int count = xread (&s)) { publish(count); raise(s); }
|
||||||
|
|
||||||
|
const char *s;
|
||||||
|
if (auto keywords = {"if", "for", "while"};
|
||||||
|
std::any_of(keywords.begin(), keywords.end(), [&s](const char* kw) { return s == kw; }))
|
||||||
|
{
|
||||||
|
// whatever
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
// { dg-do run }
|
||||||
|
// { dg-options -std=c++1z }
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
if (int i = 10, &ir = i; [=]{ return ir; }() != 10)
|
||||||
|
__builtin_abort ();
|
||||||
|
}
|
||||||
|
// { dg-do run }
|
||||||
|
// { dg-options -std=c++1z }
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
if (int i = 10, &ir = i; [=]{ return ir; }() != 10)
|
||||||
|
__builtin_abort ();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
// { dg-options -std=c++1z }
|
||||||
|
|
||||||
|
int
|
||||||
|
f ()
|
||||||
|
{
|
||||||
|
if (int c = 5;
|
||||||
|
int c = 5) // { dg-error "redeclaration" }
|
||||||
|
return 5;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// { dg-options -std=c++1z }
|
||||||
|
|
||||||
|
int
|
||||||
|
f ()
|
||||||
|
{
|
||||||
|
if (int c = 5;
|
||||||
|
int c = 5) // { dg-error "redeclaration" }
|
||||||
|
return 5;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue