From 17a9e3802a32f39707a2ac260f8f97b665a44c87 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 5 Oct 2016 18:02:06 +0000 Subject: 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 --- gcc/cp/ChangeLog | 25 ++++++ gcc/cp/cp-array-notation.c | 2 +- gcc/cp/cp-tree.h | 2 +- gcc/cp/decl.c | 5 +- gcc/cp/init.c | 2 +- gcc/cp/name-lookup.c | 2 +- gcc/cp/name-lookup.h | 2 +- gcc/cp/parser.c | 65 +++++++++++--- gcc/cp/pt.c | 4 +- gcc/cp/semantics.c | 4 +- gcc/testsuite/ChangeLog | 11 +++ gcc/testsuite/g++.dg/cpp1z/init-statement1.C | 28 ++++++ gcc/testsuite/g++.dg/cpp1z/init-statement2.C | 124 +++++++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp1z/init-statement3.C | 32 +++++++ gcc/testsuite/g++.dg/cpp1z/init-statement4.C | 118 +++++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp1z/init-statement5.C | 32 +++++++ gcc/testsuite/g++.dg/cpp1z/init-statement6.C | 50 +++++++++++ gcc/testsuite/g++.dg/cpp1z/init-statement7.C | 18 ++++ gcc/testsuite/g++.dg/cpp1z/init-statement8.C | 20 +++++ 19 files changed, 520 insertions(+), 26 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/init-statement1.C create mode 100644 gcc/testsuite/g++.dg/cpp1z/init-statement2.C create mode 100644 gcc/testsuite/g++.dg/cpp1z/init-statement3.C create mode 100644 gcc/testsuite/g++.dg/cpp1z/init-statement4.C create mode 100644 gcc/testsuite/g++.dg/cpp1z/init-statement5.C create mode 100644 gcc/testsuite/g++.dg/cpp1z/init-statement6.C create mode 100644 gcc/testsuite/g++.dg/cpp1z/init-statement7.C create mode 100644 gcc/testsuite/g++.dg/cpp1z/init-statement8.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index acd1a78..dd43d98 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,28 @@ +2016-10-05 Marek Polacek + + 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 PR c++/77852 diff --git a/gcc/cp/cp-array-notation.c b/gcc/cp/cp-array-notation.c index 4687ced6..633ab09 100644 --- a/gcc/cp/cp-array-notation.c +++ b/gcc/cp/cp-array-notation.c @@ -66,7 +66,7 @@ create_an_loop (tree init, tree cond, tree incr, tree body) finish_expr_stmt (init); 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_expr (incr, for_stmt); finish_expr_stmt (body); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3fbe1d9..92e4017 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6297,7 +6297,7 @@ extern void finish_do_stmt (tree, tree, bool); extern tree finish_return_stmt (tree); extern tree begin_for_scope (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_expr (tree, tree); extern void finish_for_stmt (tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 6646062..6a08d8f 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -639,9 +639,8 @@ poplevel (int keep, int reverse, int functionbody) BLOCK_SUPERCONTEXT (link) = block; /* We still support the old for-scope rules, whereby the variables - in a for-init statement were in scope after the for-statement - ended. We only use the new rules if flag_new_for_scope is - nonzero. */ + in a init statement were in scope after the for-statement ended. + We only use the new rules if flag_new_for_scope is nonzero. */ leaving_for_scope = current_binding_level->kind == sk_for && flag_new_for_scope == 1; diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 2d5877d..d1c8274 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -4052,7 +4052,7 @@ build_vec_init (tree base, tree maxindex, tree init, tree to; 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, build_int_cst (TREE_TYPE (iterator), -1)), for_stmt, false); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 1bce63b..9e84a1b 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -1156,7 +1156,7 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend) } } /* 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 outermost block of the controlled statement. Redeclaring a variable from a for or while condition is diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index 2cb129c..fd71038 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -107,7 +107,7 @@ enum scope_kind { sk_try, /* A try-block. */ sk_catch, /* A catch-block. */ 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 of an if or switch statement. */ sk_function_parms, /* The scope containing function parameters. */ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 683a6dd..f3dc359 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2117,7 +2117,7 @@ static tree cp_parser_condition (cp_parser *); static tree cp_parser_iteration_statement (cp_parser *, bool *, bool); -static bool cp_parser_for_init_statement +static bool cp_parser_init_statement (cp_parser *, tree *decl); static tree cp_parser_for (cp_parser *, bool); @@ -2642,6 +2642,8 @@ static bool cp_parser_compound_literal_p (cp_parser *); static bool cp_parser_array_designator_p (cp_parser *); +static bool cp_parser_init_statement_p + (cp_parser *); static bool cp_parser_skip_to_closing_square_bracket (cp_parser *); @@ -10396,6 +10398,10 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr) declaration-statement attribute-specifier-seq (opt) try-block + init-statement: + expression-statement + simple-declaration + TM Extension: 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. selection-statement: - if ( condition ) statement - if ( condition ) statement else statement - switch ( condition ) statement + if ( init-statement [opt] condition ) statement + if ( init-statement [opt] condition ) statement else statement + switch ( init-statement [opt] condition ) statement Returns the new IF_STMT or SWITCH_STMT. @@ -11006,6 +11032,17 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p, else 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. */ condition = cp_parser_condition (parser); /* Look for the `)'. */ @@ -11306,7 +11343,7 @@ cp_parser_for (cp_parser *parser, bool ivdep) scope = begin_for_scope (&init); /* 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) 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; stmt = begin_for_stmt (scope, init); - /* The for-init-statement has already been parsed in - cp_parser_for_init_statement, so no work is needed here. */ - finish_for_init_stmt (stmt); + /* The init-statement has already been parsed in + cp_parser_init_statement, so no work is needed here. */ + finish_init_stmt (stmt); /* If there's a condition, process it. */ 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 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 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, LOOKUP_ONLYCONVERTING); - finish_for_init_stmt (statement); + finish_init_stmt (statement); /* The new for condition. */ 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: while ( condition ) statement do statement while ( expression ) ; - for ( for-init-statement condition [opt] ; expression [opt] ) + for ( init-statement condition [opt] ; expression [opt] ) statement 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; } -/* 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. - for-init-statement: + init-statement: expression-statement simple-declaration */ 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 expression-statement. Grammatically, this is also a diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e6b1368..e6bacdf 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -14974,7 +14974,7 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree orig_declv, if (init && TREE_CODE (init) == DECL_EXPR) { /* 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. */ decl_expr = 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: stmt = begin_for_stmt (NULL_TREE, NULL_TREE); RECUR (FOR_INIT_STMT (t)); - finish_for_init_stmt (stmt); + finish_init_stmt (stmt); tmp = RECUR (FOR_COND (t)); finish_for_cond (tmp, stmt, false); tmp = RECUR (FOR_EXPR (t)); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 1d8f336..cae5afc 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -953,11 +953,11 @@ begin_for_stmt (tree scope, tree init) 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. */ void -finish_for_init_stmt (tree for_stmt) +finish_init_stmt (tree for_stmt) { if (processing_template_decl) FOR_INIT_STMT (for_stmt) = pop_stmt_list (FOR_INIT_STMT (for_stmt)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 653dee5..6c587f6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2016-10-05 Marek Polacek + + * 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 PR fortran/67524 diff --git a/gcc/testsuite/g++.dg/cpp1z/init-statement1.C b/gcc/testsuite/g++.dg/cpp1z/init-statement1.C new file mode 100644 index 0000000..1cebc3f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/init-statement1.C @@ -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); +} diff --git a/gcc/testsuite/g++.dg/cpp1z/init-statement2.C b/gcc/testsuite/g++.dg/cpp1z/init-statement2.C new file mode 100644 index 0000000..19d8e0c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/init-statement2.C @@ -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 (); +} diff --git a/gcc/testsuite/g++.dg/cpp1z/init-statement3.C b/gcc/testsuite/g++.dg/cpp1z/init-statement3.C new file mode 100644 index 0000000..306c801 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/init-statement3.C @@ -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 (); +} diff --git a/gcc/testsuite/g++.dg/cpp1z/init-statement4.C b/gcc/testsuite/g++.dg/cpp1z/init-statement4.C new file mode 100644 index 0000000..2a0a7d0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/init-statement4.C @@ -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" } +} diff --git a/gcc/testsuite/g++.dg/cpp1z/init-statement5.C b/gcc/testsuite/g++.dg/cpp1z/init-statement5.C new file mode 100644 index 0000000..9445abf --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/init-statement5.C @@ -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; +} diff --git a/gcc/testsuite/g++.dg/cpp1z/init-statement6.C b/gcc/testsuite/g++.dg/cpp1z/init-statement6.C new file mode 100644 index 0000000..fe6518c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/init-statement6.C @@ -0,0 +1,50 @@ +// Testcase from P0305R1 +// { dg-options -std=c++1z } + +#include +#include +#include + +std::map 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 +#include +#include + +std::map 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 + } +} diff --git a/gcc/testsuite/g++.dg/cpp1z/init-statement7.C b/gcc/testsuite/g++.dg/cpp1z/init-statement7.C new file mode 100644 index 0000000..0b9cb93 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/init-statement7.C @@ -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 (); +} diff --git a/gcc/testsuite/g++.dg/cpp1z/init-statement8.C b/gcc/testsuite/g++.dg/cpp1z/init-statement8.C new file mode 100644 index 0000000..3dccd16 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/init-statement8.C @@ -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; +} -- cgit v1.1