Bug 66007 - [5/6 Regression] Narrowing conversion inside { } results in all zero elements in C++11 mode with -Wno-error=narrowing
Summary: [5/6 Regression] Narrowing conversion inside { } results in all zero elements...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 5.1.1
: P3 normal
Target Milestone: 5.2
Assignee: Paolo Carlini
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-05-04 14:13 UTC by Evangelos Foutras
Modified: 2015-05-04 21:23 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2015-05-04 00:00:00


Attachments
Different narrowing behavior between GCC 4.9 and GCC 5 (258 bytes, text/plain)
2015-05-04 14:13 UTC, Evangelos Foutras
Details
Different narrowing behavior between GCC 4.9 and GCC 5 (with -Wno-error=narrowing) (347 bytes, text/plain)
2015-05-04 16:25 UTC, Evangelos Foutras
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Evangelos Foutras 2015-05-04 14:13:27 UTC
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.)
Comment 1 Markus Trippelsdorf 2015-05-04 14:34:49 UTC
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
Comment 2 Markus Trippelsdorf 2015-05-04 14:50:00 UTC
Closing as fixed.
Comment 3 Jakub Jelinek 2015-05-04 16:10:29 UTC
In particular, fixed with PR65858 r222699 (trunk) and r222700 (5 branch) commits.
Comment 4 Evangelos Foutras 2015-05-04 16:22:18 UTC
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
Comment 5 Evangelos Foutras 2015-05-04 16:25:45 UTC
Created attachment 35458 [details]
Different narrowing behavior between GCC 4.9 and GCC 5 (with -Wno-error=narrowing)
Comment 6 Markus Trippelsdorf 2015-05-04 16:31:26 UTC
Ouch.
Comment 7 Paolo Carlini 2015-05-04 16:33:13 UTC
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.
Comment 8 Paolo Carlini 2015-05-04 16:34:55 UTC
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;
 	}
     }
Comment 9 Jakub Jelinek 2015-05-04 16:40:10 UTC
(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;
Comment 10 Paolo Carlini 2015-05-04 17:09:58 UTC
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.
Comment 11 Paolo Carlini 2015-05-04 17:46:07 UTC
Turns out we want to check by hand errorcount at least to avoid additional overflow diagnostic (eg, cpp0x/enum29.C)
Comment 12 paolo@gcc.gnu.org 2015-05-04 20:59:05 UTC
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
Comment 13 paolo@gcc.gnu.org 2015-05-04 20:59:34 UTC
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
Comment 14 Paolo Carlini 2015-05-04 21:23:53 UTC
Fixed.