https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65858

--- Comment #3 from prathamesh3492 at gcc dot gnu.org ---
(In reply to prathamesh3492 from comment #2)
> Hi,
> Sorry for late response, I applied your patch and got the following ICE:
> -std=gnu++11 -flto --param lto-partitions=1
> Full command line options: http://pastebin.com/6JSWH9YM
> 
> ../../third_party/cld_2/src/internal/cld_generated_cjk_uni_prop_80.cc:7132:1:
> internal compiler error: in output_constructor, at lto-streamer-out.c:2152
>  }       // End namespace CLD2
>  ^
> 0xb25609 output_constructor
>       
> /home/prathamesh.kulkarni/gnu-toolchain/src/gcc.git/gcc/lto-streamer-out.c:
> 2152
> 0xb25609 lto_output()
>       
> /home/prathamesh.kulkarni/gnu-toolchain/src/gcc.git/gcc/lto-streamer-out.c:
> 2354
> 0xb7e6c1 write_lto
>       /home/prathamesh.kulkarni/gnu-toolchain/src/gcc.git/gcc/passes.c:2395
> 0xb81c0e ipa_write_summaries_1
>       /home/prathamesh.kulkarni/gnu-toolchain/src/gcc.git/gcc/passes.c:2459
> 0xb81c0e ipa_write_summaries()
>       /home/prathamesh.kulkarni/gnu-toolchain/src/gcc.git/gcc/passes.c:2519
> 0x877dda ipa_passes
>       
> /home/prathamesh.kulkarni/gnu-toolchain/src/gcc.git/gcc/cgraphunit.c:2216
> 0x877dda symbol_table::compile()
>       
> /home/prathamesh.kulkarni/gnu-toolchain/src/gcc.git/gcc/cgraphunit.c:2312
> 0x879d3c symbol_table::finalize_compilation_unit()
>       
> /home/prathamesh.kulkarni/gnu-toolchain/src/gcc.git/gcc/cgraphunit.c:2461
> 0x645c40 cp_write_global_declarations()
>       /home/prathamesh.kulkarni/gnu-toolchain/src/gcc.git/gcc/cp/decl2.c:4757
> 
> Reduced test-case:
> It appears that r222249, which fixed PR65801 introduced this issue. 
> The following test-case also ICE's for x86.
> 
> int x { 0.5 };
> int main() { return 0; }
> 
> prathamesh.kulkarni@ex40-01:~$ fsf-toolchain/bin/g++ -flto braced-init.cpp
> -c -Wno-narrowing -std=gnu++11
> prathamesh.kulkarni@ex40-01:~$ fsf-toolchain/bin/g++ -flto braced-init.o
> lto1: internal compiler error: in get_constructor, at varpool.c:331
> 0xd22c43 varpool_node::get_constructor()
>       ../../src/gcc/varpool.c:331
> 0xd23af8 varpool_node::assemble_decl()
>       ../../src/gcc/varpool.c:602
> 0x6b8633 output_in_order
>       ../../src/gcc/cgraphunit.c:2137
> 0x6b8b23 symbol_table::compile()
>       ../../src/gcc/cgraphunit.c:2378
> 0x62b025 lto_main()
>       ../../src/gcc/lto/lto.c:3496
> 
> I think it happens because, check_narrowing() returns false and it's caller
> cp/semantics.c:finish_compound_literal 
> returns error_mark_node, which then gets streamed into object file.
> 
> Conside this part of check_narrowing():
> 
> if (!ok)
>     {
>       if (cxx_dialect == cxx98)
>         warning_at (EXPR_LOC_OR_LOC (init, input_location), OPT_Wnarrowing,
>                     "narrowing conversion of %qE from %qT to %qT inside { } "
>                     "is ill-formed in C++11", init, ftype, type);
>       else if (!TREE_CONSTANT (init))
>         {
>           if (complain & tf_warning_or_error)
>             {
>               pedwarn (EXPR_LOC_OR_LOC (init, input_location),
> OPT_Wnarrowing,
>                       "narrowing conversion of %qE from %qT to %qT inside {
> }",
>                        init, ftype, type);
>               ok = true;
>             }
>         }
>       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;
> 
> For the above test-case ok is false and we enter the nested
> else if (complain & tf_error) block.
> 
> pedwarn() doesn't print anything 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 we are compiling with gnu++11 mode, cxx_dialect
> is not cxx98 and ok is false, hence check_narrowing() returns false.
> 
> cp/semantics.c:finish_compound_literal() calls check_narrowing():
>  if (SCALAR_TYPE_P (type)
>       && !BRACE_ENCLOSED_INITIALIZER_P (compound_literal)
>       && !check_narrowing (type, compound_literal, complain))
>     return error_mark_node;
> 
> I suppose that check_narrowing() returns false here and the above if
> condition becomes true and finish_compound_literal() returns
> error_mark_node which is then streamed. Is that correct ?
This part was wrong.
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 for the above test-case.

The following patch fixes the ICE.
Bootstrapped and tested on x86_64-unknown-linux-gnu:

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;
+           }
        }
     }

Thank you,
Prathamesh
> 
> I tried with the following untested patch, which prevents the ICE,
> but not sure if it's the right approach:
> diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
> index 884957b..2a25c20 100644
> --- a/gcc/cp/typeck2.c
> +++ b/gcc/cp/typeck2.c
> @@ -872,8 +872,7 @@ check_narrowing (tree type, tree init, tsubst_flags_t
> complain)
>    bool ok = true;
>    REAL_VALUE_TYPE d;
> 
> -  if (((!warn_narrowing || !(complain & tf_warning))
> -       && cxx_dialect == cxx98)
> +  if ((!warn_narrowing || !(complain & tf_warning))
>        || !ARITHMETIC_TYPE_P (type))
>      return ok;
> 
> Since we want -Wno-narrowing to also silence C++11 stricter
> narrowing rules (PR65801), I removed condition on cxx_dialect == cxx98.
> 
> Thank you,
> Prathamesh

Reply via email to