[PATCH] c/55976 -Werror=return-type should error on returning a value from a void function
This patch fixes spurious failure for C test added with original patch for bug 55976. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55976 Added dg-prune-output for extraneous message causing unexpected test failure for test gcc.dg/noncompile/pr55976-1.c Bootstrap tests run successfully x86_64-linux. --Dave /testsuite 2018-06-19 David Pagan PR c/55976 * gcc.dg/noncompile/pr55976-1.c: Add dg-prune-output for extraneous message causing unexpected test FAIL. Index: gcc/testsuite/gcc.dg/noncompile/pr55976-1.c === --- gcc/testsuite/gcc.dg/noncompile/pr55976-1.c (revision 261613) +++ gcc/testsuite/gcc.dg/noncompile/pr55976-1.c (working copy) @@ -1,6 +1,7 @@ /* PR c/55976 */ /* { dg-do compile } */ /* { dg-options "-Werror=return-type" } */ +/* { dg-prune-output "some warnings being treated as errors" } */ /* Verify warnings for return type become errors. */
Re: [PATCH] c/55976 -Werror=return-type should error on returning a value from a void function
Thanks for pointing this out. I'll check out what's going on and fix the issue --Dave On 05/31/2018 05:53 AM, H.J. Lu wrote: On Wed, May 30, 2018 at 3:56 PM, Jeff Law wrote: On 04/22/2018 01:17 PM, dave.pa...@oracle.com wrote: This patch fixes handling of -Werror=return-type as well as -Wno-return-type. Currently, -Werror=return-type does not turn the warnings into errors and -Wno-return-type does not turn off warning/error. Now they both work as expected. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55976 Initialize warn_return_type only for C++/C++ with ObjC extensions. In C, this allows us to differentiate between default (no option), or cases where -Wreturn-type/-Wno-return-type are specified. Elsewhere, update references to warn_return_type (for C) to reflect change in initialization. Patch was successfully bootstrapped and tested on x86_64-linux. --Dave CL-55976 /c 2018-04-22 David Pagan PR c/55976 * c-decl.c (grokdeclarator): Update check for return type warnings. (start_function): Likewise. (finish_function): Likewise. * c-typeck.c (c_finish_return): Update check for return type warnings. Pass OPT_Wreturn_type to pedwarn when appropriate. * c-opts.c (c_common_post_options): Set default for warn_return_type for C++/C++ with ObjC extensions only. For C, makes it possible to differentiate between default (no option), -Wreturn-type, and -Wno-return-type. /testsuite 2018-04-22 David Pagan PR c/55976 * gcc.dg/noncompile/pr55976-1.c: New test. * gcc.dg/noncompile/pr55976-2.c: New test. THanks. Installed on the trunk. On x86, I got FAIL: gcc.dg/noncompile/pr55976-1.c -O0 (test for excess errors) FAIL: gcc.dg/noncompile/pr55976-1.c -O1 (test for excess errors) FAIL: gcc.dg/noncompile/pr55976-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none (test for excess errors) FAIL: gcc.dg/noncompile/pr55976-1.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects (test for excess errors) FAIL: gcc.dg/noncompile/pr55976-1.c -O2 (test for excess errors) FAIL: gcc.dg/noncompile/pr55976-1.c -O3 -g (test for excess errors) FAIL: gcc.dg/noncompile/pr55976-1.c -Os (test for excess errors) [hjl@gnu-skx-1 testsuite]$ /export/ssd/git/gcc-test-native/bld/gcc/xgcc -B/export/ssd/git/gcc-test-native/bld/gcc/ /export/ssd/git/gcc-test-native/src-trunk/gcc/testsuite/gcc.dg/noncompile/pr55976-1.c -mx32 -B/export/ssd/git/gcc-test-native/bld/x86_64-pc-linux-gnu/32/libmpx/ -B/export/ssd/git/gcc-test-native/bld/x86_64-pc-linux-gnu/32/libmpx/mpxrt -L/export/ssd/git/gcc-test-native/bld/x86_64-pc-linux-gnu/32/libmpx/mpxrt/.libs -B/export/ssd/git/gcc-test-native/bld/x86_64-pc-linux-gnu/32/libmpx/ -B/export/ssd/git/gcc-test-native/bld/x86_64-pc-linux-gnu/32/libmpx/mpxwrap -L/export/ssd/git/gcc-test-native/bld/x86_64-pc-linux-gnu/32/libmpx/mpxwrap/.libs -fno-diagnostics-show-caret -fdiagnostics-color=never -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects -Werror=return-type -S -o pr55976-1.s /export/ssd/git/gcc-test-native/src-trunk/gcc/testsuite/gcc.dg/noncompile/pr55976-1.c: In function \u2018t\u2019: /export/ssd/git/gcc-test-native/src-trunk/gcc/testsuite/gcc.dg/noncompile/pr55976-1.c:7:20: error: \u2018return\u2019 with a value, in function returning void [-Werror=return-type] /export/ssd/git/gcc-test-native/src-trunk/gcc/testsuite/gcc.dg/noncompile/pr55976-1.c:7:6: note: declared here /export/ssd/git/gcc-test-native/src-trunk/gcc/testsuite/gcc.dg/noncompile/pr55976-1.c: In function \u2018b\u2019: /export/ssd/git/gcc-test-native/src-trunk/gcc/testsuite/gcc.dg/noncompile/pr55976-1.c:8:12: error: \u2018return\u2019 with no value, in function returning non-void [-Werror=return-type] /export/ssd/git/gcc-test-native/src-trunk/gcc/testsuite/gcc.dg/noncompile/pr55976-1.c:8:5: note: declared here cc1: some warnings being treated as errors [hjl@gnu-skx-1 testsuite]$
[PING][PATCH] c/55976 -Werror=return-type should error on returning a value from a void function
Ping for the following C patch sent on 4/22/2018 https://gcc.gnu.org/ml/gcc-patches/2018-04/msg01034.html Thanks, --Dave == On 04/22/2018 12:17 PM, dave.pa...@oracle.com wrote: This patch fixes handling of -Werror=return-type as well as -Wno-return-type. Currently, -Werror=return-type does not turn the warnings into errors and -Wno-return-type does not turn off warning/error. Now they both work as expected. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55976 Initialize warn_return_type only for C++/C++ with ObjC extensions. In C, this allows us to differentiate between default (no option), or cases where -Wreturn-type/-Wno-return-type are specified. Elsewhere, update references to warn_return_type (for C) to reflect change in initialization. Patch was successfully bootstrapped and tested on x86_64-linux. --Dave
[PATCH] c/55976 -Werror=return-type should error on returning a value from a void function
This patch fixes handling of -Werror=return-type as well as -Wno-return-type. Currently, -Werror=return-type does not turn the warnings into errors and -Wno-return-type does not turn off warning/error. Now they both work as expected. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55976 Initialize warn_return_type only for C++/C++ with ObjC extensions. In C, this allows us to differentiate between default (no option), or cases where -Wreturn-type/-Wno-return-type are specified. Elsewhere, update references to warn_return_type (for C) to reflect change in initialization. Patch was successfully bootstrapped and tested on x86_64-linux. --Dave /c 2018-04-22 David PaganPR c/55976 * c-decl.c (grokdeclarator): Update check for return type warnings. (start_function): Likewise. (finish_function): Likewise. * c-typeck.c (c_finish_return): Update check for return type warnings. Pass OPT_Wreturn_type to pedwarn when appropriate. * c-opts.c (c_common_post_options): Set default for warn_return_type for C++/C++ with ObjC extensions only. For C, makes it possible to differentiate between default (no option), -Wreturn-type, and -Wno-return-type. /testsuite 2018-04-22 David Pagan PR c/55976 * gcc.dg/noncompile/pr55976-1.c: New test. * gcc.dg/noncompile/pr55976-2.c: New test. Index: gcc/c/c-decl.c === --- gcc/c/c-decl.c (revision 259017) +++ gcc/c/c-decl.c (working copy) @@ -5745,7 +5745,7 @@ grokdeclarator (const struct c_declarator *declara /* Issue a warning if this is an ISO C 99 program or if -Wreturn-type and this is a function, or if -Wimplicit; prefer the former warning since it is more explicit. */ - if ((warn_implicit_int || warn_return_type || flag_isoc99) + if ((warn_implicit_int || warn_return_type > 0 || flag_isoc99) && funcdef_flag) warn_about_return_type = 1; else @@ -8739,7 +8739,7 @@ start_function (struct c_declspecs *declspecs, str if (warn_about_return_type) warn_defaults_to (loc, flag_isoc99 ? OPT_Wimplicit_int - : (warn_return_type ? OPT_Wreturn_type + : (warn_return_type > 0 ? OPT_Wreturn_type : OPT_Wimplicit_int), "return type defaults to % "); @@ -9450,8 +9450,9 @@ finish_function (void) finish_fname_decls (); - /* Complain if there's just no return statement. */ - if (warn_return_type + /* Complain if there's no return statement only if option specified on + command line. */ + if (warn_return_type > 0 && TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE && !current_function_returns_value && !current_function_returns_null /* Don't complain if we are no-return. */ Index: gcc/c/c-typeck.c === --- gcc/c/c-typeck.c(revision 259017) +++ gcc/c/c-typeck.c(working copy) @@ -10129,13 +10129,13 @@ c_finish_return (location_t loc, tree retval, tree if (!retval) { current_function_returns_null = 1; - if ((warn_return_type || flag_isoc99) + if ((warn_return_type >= 0 || flag_isoc99) && valtype != NULL_TREE && TREE_CODE (valtype) != VOID_TYPE) { bool warned_here; if (flag_isoc99) warned_here = pedwarn - (loc, 0, + (loc, warn_return_type >= 0 ? OPT_Wreturn_type : 0, "% with no value, in function returning non-void"); else warned_here = warning_at @@ -10153,7 +10153,7 @@ c_finish_return (location_t loc, tree retval, tree bool warned_here; if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE) warned_here = pedwarn - (xloc, 0, + (xloc, warn_return_type >= 0 ? OPT_Wreturn_type : 0, "% with a value, in function returning void"); else warned_here = pedwarn Index: gcc/c-family/c-opts.c === --- gcc/c-family/c-opts.c (revision 259017) +++ gcc/c-family/c-opts.c (working copy) @@ -994,8 +994,9 @@ c_common_post_options (const char **pfilename) flag_extern_tls_init = 1; } - if (warn_return_type == -1) -warn_return_type = c_dialect_cxx (); + /* Enable by default only for C++ and C++ with ObjC extensions. */ + if (warn_return_type == -1 && c_dialect_cxx ()) +warn_return_type = 1; if (num_in_fnames > 1) error ("too many filenames given. Type %s --help for usage", Index: gcc/testsuite/gcc.dg/noncompile/pr55976-1.c === --- gcc/testsuite/gcc.dg/noncompile/pr55976-1.c (revision 0) +++
Re: [PATCH] c/55976 -Werror=return-type should error on returning a value from a void function
On 04/04/2018 07:44 PM, Martin Sebor wrote: On 04/04/2018 05:50 PM, dave.pa...@oracle.com wrote: On 04/04/2018 10:58 AM, Martin Sebor wrote: On 04/04/2018 11:15 AM, Jakub Jelinek wrote: On Tue, Apr 03, 2018 at 01:36:13PM -0600, Martin Sebor wrote: On 04/03/2018 10:26 AM, dave.pa...@oracle.com wrote: This patch fixes handlng of -Werror=return-type. Currently, even with the flag specified, return type errors remain warnings. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55976 Function c_finish_return (), when calling pedwarn, should specifiy OPT_Wreturn_type as the diagnostic index if warn_return_type is set so that the given diagnostic is generated as an error, not a warning. Patch was successfully bootstrapped and tested on x86_64-linux. I would expect the option to control the warning consistently so that when the test case is compiled with just -Wno-return-type (and no other options) the warning is not issued. But that's not what happens because pedwarn() is called with a zero argument as the option. I think we need to make sure we error out even with -Wno-return-type when -pedantic-errors. That would seem surprising to me. Is there an existing precedent for this in GCC? (Any other warnings or options that are treated this way?) It would also diverge from Clang, which would be particularly unhelpful to users of both compilers. I would suggest to follow what Clang does in terms of controlling the warning (though not necessarily in its severity). It's consistent and intuitive. (Clang has -Werror=return-type by default; that may be overly strict.) I think these are both good points. While I tend to lean toward consistency (both within GCC and with clang), if this sort of problem is potentially worse in GCC 8 (as Jakub suggests) then perhaps it's worth thinking about how to help prevent it. If we do choose to go this direction with -pedantic-errors, and there isn't a precedent for it, then the documentation would require an update to reflect the new behavior. I actually don't think -Wpedantic is the appropriate option to control the warning in the case Jakub is concerned about (it may be appropriate for warning about returning a value from a void function because that's a constraint violation). -Wpedantic is meant for diagnostics that are required by the C/C++ standards but that GCC may otherwise silently accept as extensions. Defining a non-void function that doesn't return a value is valid in C is not incorrect and does not require a diagnostic. (Using the return value is undefined, but when it isn't used there is no problem.) (This is different in recent versions of C++ where a return statement with no operand in a non-void function requires a diagnostic, so the C++ handling may need to be different.) Also, thoughts on this question from my last email? Since this patch does fix the original problem, what do you recommend? Scrap this patch? Or let it proceed and submit a new bug noting the (existing) incorrect behavior of -Wno-return-type? We could add the discussion in this email to any new bug we create for -Wno-return-type. I think for C, handling it under the same bug and in the same patch would be best. The C++ bits could come later if needed. Ok. Thanks, Martin. I'll add proper handling of -Wno-return-type to this patch and resubmit it. --Dave Martin --Dave Martin Especially when issues this pedwarn warns about are very hard to debug show stoppers for anybody calling such functions in GCC 8 (because we turn such spots into __builtin_unreachable () and thus randomly can execute completely unrelated code). So, I think consistency isn't that important here. Jakub
Re: [PATCH] c/55976 -Werror=return-type should error on returning a value from a void function
On 04/04/2018 10:58 AM, Martin Sebor wrote: On 04/04/2018 11:15 AM, Jakub Jelinek wrote: On Tue, Apr 03, 2018 at 01:36:13PM -0600, Martin Sebor wrote: On 04/03/2018 10:26 AM, dave.pa...@oracle.com wrote: This patch fixes handlng of -Werror=return-type. Currently, even with the flag specified, return type errors remain warnings. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55976 Function c_finish_return (), when calling pedwarn, should specifiy OPT_Wreturn_type as the diagnostic index if warn_return_type is set so that the given diagnostic is generated as an error, not a warning. Patch was successfully bootstrapped and tested on x86_64-linux. I would expect the option to control the warning consistently so that when the test case is compiled with just -Wno-return-type (and no other options) the warning is not issued. But that's not what happens because pedwarn() is called with a zero argument as the option. I think we need to make sure we error out even with -Wno-return-type when -pedantic-errors. That would seem surprising to me. Is there an existing precedent for this in GCC? (Any other warnings or options that are treated this way?) It would also diverge from Clang, which would be particularly unhelpful to users of both compilers. I would suggest to follow what Clang does in terms of controlling the warning (though not necessarily in its severity). It's consistent and intuitive. (Clang has -Werror=return-type by default; that may be overly strict.) I think these are both good points. While I tend to lean toward consistency (both within GCC and with clang), if this sort of problem is potentially worse in GCC 8 (as Jakub suggests) then perhaps it's worth thinking about how to help prevent it. If we do choose to go this direction with -pedantic-errors, and there isn't a precedent for it, then the documentation would require an update to reflect the new behavior. Also, thoughts on this question from my last email? Since this patch does fix the original problem, what do you recommend? Scrap this patch? Or let it proceed and submit a new bug noting the (existing) incorrect behavior of -Wno-return-type? We could add the discussion in this email to any new bug we create for -Wno-return-type. --Dave Martin Especially when issues this pedwarn warns about are very hard to debug show stoppers for anybody calling such functions in GCC 8 (because we turn such spots into __builtin_unreachable () and thus randomly can execute completely unrelated code). So, I think consistency isn't that important here. Jakub
Re: [PATCH] c/55976 -Werror=return-type should error on returning a value from a void function
Hi Martin, Hadn't thought about, but you're right ... it should be consistent. Currently, -Wno-return-type has no effect on this warning, but it should. Since this patch does fix the original problem, what do you recommend? Scrap this patch? Or let it proceed and submit a new bug noting the (existing) incorrect behavior of -Wno-return-type? --Dave On 04/03/2018 12:36 PM, Martin Sebor wrote: On 04/03/2018 10:26 AM, dave.pa...@oracle.com wrote: This patch fixes handlng of -Werror=return-type. Currently, even with the flag specified, return type errors remain warnings. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55976 Function c_finish_return (), when calling pedwarn, should specifiy OPT_Wreturn_type as the diagnostic index if warn_return_type is set so that the given diagnostic is generated as an error, not a warning. Patch was successfully bootstrapped and tested on x86_64-linux. I would expect the option to control the warning consistently so that when the test case is compiled with just -Wno-return-type (and no other options) the warning is not issued. But that's not what happens because pedwarn() is called with a zero argument as the option. Martin
[PATCH] c/55976 -Werror=return-type should error on returning a value from a void function
This patch fixes handlng of -Werror=return-type. Currently, even with the flag specified, return type errors remain warnings. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55976 Function c_finish_return (), when calling pedwarn, should specifiy OPT_Wreturn_type as the diagnostic index if warn_return_type is set so that the given diagnostic is generated as an error, not a warning. Patch was successfully bootstrapped and tested on x86_64-linux. --Dave /c 2018-04-03 David PaganPR c/55976 * c-typeck.c (c_finish_return): If -Wreturn-type enabled (warn_return_type), pass OPT_Wreturn_type to pedwarn so warning is turned into an error when -Werror=return-type specified. /testsuite 2018-04-03 David Pagan PR c/55976 * gcc.dg/noncompile/pr55976.c: New test. Index: gcc/c/c-typeck.c === --- gcc/c/c-typeck.c(revision 259017) +++ gcc/c/c-typeck.c(working copy) @@ -10135,7 +10135,7 @@ c_finish_return (location_t loc, tree retval, tree bool warned_here; if (flag_isoc99) warned_here = pedwarn - (loc, 0, + (loc, warn_return_type ? OPT_Wreturn_type : 0, "% with no value, in function returning non-void"); else warned_here = warning_at @@ -10153,7 +10153,7 @@ c_finish_return (location_t loc, tree retval, tree bool warned_here; if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE) warned_here = pedwarn - (xloc, 0, + (xloc, warn_return_type ? OPT_Wreturn_type : 0, "% with a value, in function returning void"); else warned_here = pedwarn Index: gcc/testsuite/gcc.dg/noncompile/pr55976.c === --- gcc/testsuite/gcc.dg/noncompile/pr55976.c (revision 0) +++ gcc/testsuite/gcc.dg/noncompile/pr55976.c (working copy) @@ -0,0 +1,12 @@ +/* PR c/55976 */ +/* { dg-do compile } */ +/* { dg-options "-Werror=return-type" } */ + +void t () { return 1; } /* { dg-error "return" "function returning void" } */ +int b () { return; } /* { dg-error "return" "function returning non-void" } */ + +int main() +{ + t(); b(); + return 0; +}
[PATCH] PR c/30552 gcc crashes when compiling examples with GNU statement expressions in VLAs
This patch fixes ICE when statement expression used in old-style function declaration parameter list. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=30552 In c_parser_postfix_expression (), after seeing a left paren followed by a left curly brace, in addition to checking for existing statement list, also check to see if we're in the parameter scope an old-style function declaration. In either case, generate a "braced-group within expression allowed only inside a function" error. Patch successfully bootstrapped and tested on x86_64-linux. --Dave /c 2018-03-13 David PaganPR c/30552 * c-decl.c (old_style_parameter_scope): New function. * c-parser.c (c_parser_postfix_expression): Check for statement expressions in old-style function parameter list declarations. /c-family 2018-03-13 David Pagan PR c/30552 * c-common.h (old_style_parameter_scope): New extern declaration. /testsuite 2018-03-13 David Pagan PR c/30552 * gcc.dg/noncompile/pr30552-1.c: New test. * gcc.dg/noncompile/pr30552-2.c: New test. * gcc.dg/noncompile/pr30552-3.c: New test. * gcc.dg/noncompile/pr30552-4.c: New test. Index: c/c-decl.c === --- c/c-decl.c (revision 258257) +++ c/c-decl.c (working copy) @@ -952,6 +952,17 @@ global_bindings_p (void) return current_scope == file_scope; } +/* Return true if we're declaring parameters in an old-style function + declaration. */ + +bool +old_style_parameter_scope (void) +{ + /* If processing parameters and there is no function statement list, we + * have an old-style function declaration. */ + return (current_scope->parm_flag && !DECL_SAVED_TREE(current_function_decl)); +} + void keep_next_level (void) { Index: c/c-parser.c === --- c/c-parser.c(revision 258257) +++ c/c-parser.c(working copy) @@ -7929,7 +7929,10 @@ c_parser_postfix_expression (c_parser *parser) c_parser_consume_token (parser); brace_loc = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); - if (!building_stmt_list_p ()) + /* If we've not yet started the current function's statement list, +or we're in the parameter scope of an old-style function +declaration, statement expressions are not allowed. */ + if (!building_stmt_list_p () || old_style_parameter_scope ()) { error_at (loc, "braced-group within expression allowed " "only inside a function"); Index: c-family/c-common.h === --- c-family/c-common.h (revision 258257) +++ c-family/c-common.h (working copy) @@ -581,6 +581,7 @@ extern tree push_stmt_list (void); extern tree pop_stmt_list (tree); extern tree add_stmt (tree); extern void push_cleanup (tree, tree, bool); +extern bool old_style_parameter_scope (void); extern tree build_modify_expr (location_t, tree, tree, enum tree_code, location_t, tree, tree); Index: testsuite/gcc.dg/noncompile/pr30552-1.c === --- testsuite/gcc.dg/noncompile/pr30552-1.c (revision 0) +++ testsuite/gcc.dg/noncompile/pr30552-1.c (working copy) @@ -0,0 +1,17 @@ +/* PR c/30552 */ + +/* Statement expression as formal array argument size in nested old-style + function declaration should generate user error, not internal compiler + error. */ + +/* { dg-do compile } */ +/* { dg-options "" } */ + +int main() +{ + void fun(int a) /* { dg-error "old-style parameter declarations in prototyped function definition" } */ +int a[({void h(){}2;})]; /* { dg-error "braced-group within expression allowed only inside a function" } */ + { + } + return 0; +} Index: testsuite/gcc.dg/noncompile/pr30552-2.c === --- testsuite/gcc.dg/noncompile/pr30552-2.c (revision 0) +++ testsuite/gcc.dg/noncompile/pr30552-2.c (working copy) @@ -0,0 +1,17 @@ +/* PR c/30552 */ + +/* Another example of a statement expression as formal array argument size in + * nested old-style function declaration should generate user error, not + * internal compiler error. */ + +/* { dg-do compile } */ +/* { dg-options "" } */ + +int main() +{ + void fun(a) +int a[({int b=2; b;})]; /* { dg-error "braced-group within expression allowed only inside a function" } */ + { + } + return 0; +} Index: testsuite/gcc.dg/noncompile/pr30552-3.c === --- testsuite/gcc.dg/noncompile/pr30552-3.c (revision 0) +++ testsuite/gcc.dg/noncompile/pr30552-3.c (working copy) @@ -0,0 +1,15 @@ +/* PR c/30552 */ +
[PATCH] PR c/46921 Lost side effect when struct initializer expression uses comma operator
This patch fixes improper handling of comma operator expression in a struct field initializer as described in: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46921 Currently, function output_init_element () does not evaluate the left hand expression in a comma operator that's used for a struct initializer field if the right hand side is zero-sized. However, the left hand expression must be evaluated if it's found to have side effects (for example, a function call). Patch was successfully bootstrapped and tested on x86_64-linux. --Dave /c 2018-02-26 David PaganPR c/46921 * c-typeck.c (output_init_element): Ensure field initializer expression is always evaluated if there are side effects. /testsuite 2018-02-26 David Pagan PR c/46921 * gcc.dg/pr46921.c: New test. Index: gcc/c/c-typeck.c === --- gcc/c/c-typeck.c(revision 257975) +++ gcc/c/c-typeck.c(working copy) @@ -9208,12 +9208,14 @@ output_init_element (location_t loc, tree value, t "enum conversion in initialization is invalid in C++"); } - /* If this field is empty (and not at the end of structure), - don't do anything other than checking the initializer. */ + /* If this field is empty and does not have side effects (and is not at + the end of structure), don't do anything other than checking the + initializer. */ if (field && (TREE_TYPE (field) == error_mark_node || (COMPLETE_TYPE_P (TREE_TYPE (field)) && integer_zerop (TYPE_SIZE (TREE_TYPE (field))) + && !TREE_SIDE_EFFECTS (new_value) && (TREE_CODE (constructor_type) == ARRAY_TYPE || DECL_CHAIN (field) return; Index: gcc/testsuite/gcc.dg/pr46921.c === --- gcc/testsuite/gcc.dg/pr46921.c (revision 0) +++ gcc/testsuite/gcc.dg/pr46921.c (working copy) @@ -0,0 +1,40 @@ +/* PR c/46921 lost side effect when struct initializer expr uses comma + operator */ + +/* { dg-do run } */ +/* { dg-options "" } */ + +extern int printf(const char *, ...); +extern void abort (void); + +typedef struct __uws_0 { } uw_unit; +uw_unit uw_unit_v = {}; + +struct __uws_1 +{ + struct __uws_0 __uwf_1; + struct __uws_1* __uwf_2; +}; + +static int left_hand_eval = 0; + +static void +foo (const char *s) +{ + ++left_hand_eval; + printf("%s", s); +} + +int +main () +{ + struct __uws_1 tmp = {(foo("Inner\n"), uw_unit_v)}; + + printf("Outer\n"); + /* left hand expression in comma operator initializer must always be + evaluated if there are side effects. */ + if (!left_hand_eval) +abort (); + + return 0; +}