diff mbox

[C++] PR 65858

Message ID CAAgBjMkvPPYvL=kLGe8oJ6843jsEL2BZdYDEtWQwXZOGnKyfww@mail.gmail.com
State New
Headers show

Commit Message

Prathamesh Kulkarni April 30, 2015, 4:36 p.m. UTC
Hi,
The attached patch fixes ICE in PR65858.

For the test-case:
int x { 0.5 };
int main() { return 0; }

Compiling with: g++ -flto -Wno-narrowing -std=gnu++11
results in following ICE:
lto1: internal compiler error: in get_constructor, at varpool.c:331
0xd22f73 varpool_node::get_constructor()
../../src/gcc/varpool.c:331
0xd23e28 varpool_node::assemble_decl()
../../src/gcc/varpool.c:602
0x6b8793 output_in_order
../../src/gcc/cgraphunit.c:2137
0x6b8c83 symbol_table::compile()
../../src/gcc/cgraphunit.c:2378
0x62b205 lto_main()
../../src/gcc/lto/lto.c:3496

The ICE happens because error_mark_node gets streamed in the
object file and hits the assert:
gcc_assert (DECL_INITIAL (decl) != error_mark_node);

It appears that r222249, which fixed PR65801 introduced this issue.

For the above test-case convert_like_real() calls check_narrowing():
 if (convs->check_narrowing
      && !check_narrowing (totype, expr, complain))
    return error_mark_node;

Here convert_like_real() returns error_mark_node, because
check_narrowing() returns false.

Conside this part of check_narrowing():

if (!ok)
  {
     //...
     else if (complain & tf_error)
       {
         global_dc->pedantic_errors = 1;
         pedwarn (EXPR_LOC_OR_LOC (init, input_location), OPT_Wnarrowing,
                        "narrowing conversion of %qE from %qT to %qT
inside { }",
                         init, ftype, type);
         global_dc->pedantic_errors = flag_pedantic_errors;
       }
   }
return cxx_dialect == cxx98 || ok;

pedwarn() doesn't print warning here and returns 0.
That's because the following condition becomes true in
diagnostic.c:diagnostic_report_diagnostic():

/* This tests if the user provided the appropriate -Wfoo or
   -Wno-foo option.  */
if (! context->option_enabled (diagnostic->option_index,
                               context->option_state))
  return false;

So diagnostic_report_diagnostic() returns false to pedwarn()
which then returns 0 to check_narrowing() and warning is not printed.

return cxx_dialect == cxx98 || ok;
Since cxx_dialect is not cxx98 and ok is false, it returns false.

The attached patch fixes the ICE, by setting "ok = true" if
warn_narrowing is enabled thereby returning "true" to
convert_like_real().
Booststrapped and tested on x86_64-unknown-linux-gnu with no regressions.
OK for trunk ?

Thank you,
Prathamesh
/cp
2015-04-20  Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>
	
	PR c++/65858
	* typeck2.c (check_narrowing): Do not pedwarn if -Wno-narrowing is enabled.

Comments

Prathamesh Kulkarni April 30, 2015, 9:08 p.m. UTC | #1
On 1 May 2015 at 01:12, Paolo Carlini <paolo.carlini@oracle.com> wrote:
> Hi again,
>
> On 04/30/2015 08:45 PM, Paolo Carlini wrote:
>>
>> .. also, your patch doesn't seem to fix the case of -w instead of
That could be fixed as follows:
if (!warn_narrowing || inhibit_warnings)
  ok = true;
else
  // pedwarn
>> -Wno-narrowing. I think we want to check the return value of the pedwarn
>> instead. I'm testing something.
>
> I'm finishing testing the below: with hindsight, checking the return value
> of the pedwarn makes a lot of sense to me!
Indeed, checking return value of pedwarn is better compared to testing
on warning flags.
Thanks for pointing out -;)

Regards,
Prathamesh
>
> Paolo.
>
> ///////////////////////
diff mbox

Patch

Index: gcc/cp/typeck2.c
===================================================================
--- gcc/cp/typeck2.c	(revision 222573)
+++ gcc/cp/typeck2.c	(working copy)
@@ -958,11 +958,17 @@ 
 	}
       else if (complain & tf_error)
 	{
-	  global_dc->pedantic_errors = 1;
-	  pedwarn (EXPR_LOC_OR_LOC (init, input_location), OPT_Wnarrowing,
-		   "narrowing conversion of %qE from %qT to %qT inside { }",
-		   init, ftype, type);
-	  global_dc->pedantic_errors = flag_pedantic_errors;
+	  /* silence warning if -Wno-narrowing -is specified */
+	  if (!warn_narrowing)
+	    ok = true;
+	  else
+	    { 
+	      global_dc->pedantic_errors = 1;
+	      pedwarn (EXPR_LOC_OR_LOC (init, input_location), OPT_Wnarrowing,
+		      "narrowing conversion of %qE from %qT to %qT inside { }",
+		       init, ftype, type);
+	      global_dc->pedantic_errors = flag_pedantic_errors;
+	    }
 	}
     }