Created attachment 35453 [details] Different narrowing behavior between GCC 4.9 and GCC 5 This is related to PR c++/65801 which allowed -Wno-narrowing to be used to silence narrowing errors in C++11 mode. Compiling something like "int foo[] = { 1, 0xFFFFFFFF, 3 };" with "-std=c++11 -Wno-error=narrowing" will initialize foo to {0, 0, 0}, whereas GCC 4.9 would initialize it to {1, -1, 3}. (Attached is the assembler code generated by both GCC versions.) (This change in behavior causes at least one crash in Chromium; when using the search box on the settings page, the tab will crash.)
I cannot reproduce this on today's 5 branch: markus@x4 tmp % echo 'int foo[] = { 1, 0xFFFFFFFF, 3 };' | g++ -S -x c++ - -o - -std=c++11 -Wno-narrowing .file "" .globl foo .data .align 8 .type foo, @object .size foo, 12 foo: .long 1 .long -1 .long 3 .ident "GCC: (GNU) 5.1.1" .section .note.GNU-stack,"",@progbits
Closing as fixed.
In particular, fixed with PR65858 r222699 (trunk) and r222700 (5 branch) commits.
I'm afraid it's not fully fixed yet; using -Wno-error=narrowing will still initialize all array elements to zero: $ echo 'int foo[] = { 1, 0xFFFFFFFF, 3 };' | g++ -S -x c++ - -o - -std=c++11 -Wno-error=narrowing .file "" <stdin>:1:32: warning: narrowing conversion of ‘4294967295u’ from ‘unsigned int’ to ‘int’ inside { } [-Wnarrowing] .globl foo .bss .align 8 .type foo, @object .size foo, 12 foo: .zero 12 .ident "GCC: (GNU) 5.1.1 20150504" .section .note.GNU-stack,"",@progbits
Created attachment 35458 [details] Different narrowing behavior between GCC 4.9 and GCC 5 (with -Wno-error=narrowing)
Ouch.
Unfortunately, I'm afraid it's a real issue. Note the test has -Wno-error=narrowing, not -Wno-narrowing. Thus the pedwarn at typeck2.c:962 returns true and ok remains false while we only emitted a warning and the compilation goes on. In other terms we have a variant of c++/65858. It may work to simply set ok = true unconditionally, after all we do the same for the previous pedwarn and in this case we are simply forcing -pedantic-errors, something that can happen for any other pedwarn as a normal user provided switch.
Index: typeck2.c =================================================================== --- typeck2.c (revision 222767) +++ typeck2.c (working copy) @@ -959,10 +959,10 @@ check_narrowing (tree type, tree init, tsubst_flag else if (complain & tf_error) { global_dc->pedantic_errors = 1; - if (!pedwarn (EXPR_LOC_OR_LOC (init, input_location), OPT_Wnarrowing, - "narrowing conversion of %qE from %qT to %qT " - "inside { }", init, ftype, type)) - ok = true; + pedwarn (EXPR_LOC_OR_LOC (init, input_location), OPT_Wnarrowing, + "narrowing conversion of %qE from %qT to %qT " + "inside { }", init, ftype, type); + ok = true; global_dc->pedantic_errors = flag_pedantic_errors; } }
(In reply to Paolo Carlini from comment #8) > Index: typeck2.c > =================================================================== > --- typeck2.c (revision 222767) > +++ typeck2.c (working copy) > @@ -959,10 +959,10 @@ check_narrowing (tree type, tree init, tsubst_flag > else if (complain & tf_error) > { > global_dc->pedantic_errors = 1; > - if (!pedwarn (EXPR_LOC_OR_LOC (init, input_location), OPT_Wnarrowing, > - "narrowing conversion of %qE from %qT to %qT " > - "inside { }", init, ftype, type)) > - ok = true; > + pedwarn (EXPR_LOC_OR_LOC (init, input_location), OPT_Wnarrowing, > + "narrowing conversion of %qE from %qT to %qT " > + "inside { }", init, ftype, type); > + ok = true; > global_dc->pedantic_errors = flag_pedantic_errors; > } > } Another possibility would be to check if the pedwarn increased errorcount, so something like: int savederrorcount = errorcount; pedwarn (EXPR_LOC_OR_LOC (init, input_location), OPT_Wnarrowing, "narrowing conversion of %qE from %qT to %qT " "inside { }", init, ftype, type); if (errorcount != savederrorcount) ok = true;
Right Jakub. To my taste, fiddling directly with those counters isn't that nice, but I know we do it in a few other places. In any case this code is rather hackish anyway, we try to do something we don't do anywhere else, effectively suppressing an hard error via -Wno-*. Also, as I already said, I was thinking that normally elsewhere in the code, we do not handle pedwarns as errors, we don't consider that -pedantic-errors may be in effect (in the pedwarn right before too). What can I say, maybe we can ask Jason, which solution he prefers in principle? In the meanwhile I do some testing.
Turns out we want to check by hand errorcount at least to avoid additional overflow diagnostic (eg, cpp0x/enum29.C)
Author: paolo Date: Mon May 4 20:58:33 2015 New Revision: 222778 URL: https://gcc.gnu.org/viewcvs?rev=222778&root=gcc&view=rev Log: /cp 2015-05-04 Paolo Carlini <paolo.carlini@oracle.com> Jakub Jelinek <jakub@redhat.com> PR c++/66007 * typeck2.c (check_narrowing): Check by-hand that the pedwarn didn't result in an actual error. /testsuite 2015-05-04 Paolo Carlini <paolo.carlini@oracle.com> Jakub Jelinek <jakub@redhat.com> PR c++/66007 * g++.dg/cpp0x/Wnarrowing4.C: New. Added: trunk/gcc/testsuite/g++.dg/cpp0x/Wnarrowing4.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/typeck2.c trunk/gcc/testsuite/ChangeLog
Author: paolo Date: Mon May 4 20:59:03 2015 New Revision: 222779 URL: https://gcc.gnu.org/viewcvs?rev=222779&root=gcc&view=rev Log: /cp 2015-05-04 Paolo Carlini <paolo.carlini@oracle.com> Jakub Jelinek <jakub@redhat.com> PR c++/66007 * typeck2.c (check_narrowing): Check by-hand that the pedwarn didn't result in an actual error. /testsuite 2015-05-04 Paolo Carlini <paolo.carlini@oracle.com> Jakub Jelinek <jakub@redhat.com> PR c++/66007 * g++.dg/cpp0x/Wnarrowing4.C: New. Added: branches/gcc-5-branch/gcc/testsuite/g++.dg/cpp0x/Wnarrowing4.C Modified: branches/gcc-5-branch/gcc/cp/ChangeLog branches/gcc-5-branch/gcc/cp/typeck2.c branches/gcc-5-branch/gcc/testsuite/ChangeLog
Fixed.