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

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Seems in that case we loose the precision in:
#0  fold_convert_loc (loc=0, type=<real_type 0x7fffea1582a0 float>,
arg=<real_cst 0x7fffea2af480>) at ../../gcc/fold-const.cc:2436
#1  0x000000000049c414 in cxx_eval_constant_expression (ctx=0x7fffffffcc90,
t=<excess_precision_expr 0x7fffea290960>, lval=vc_prvalue,
non_constant_p=0x7fffffffcdaf, 
    overflow_p=0x7fffffffcdae, jump_target=0x0) at
../../gcc/cp/constexpr.cc:7541
#2  0x000000000049e566 in cxx_eval_outermost_constant_expr
(t=<excess_precision_expr 0x7fffea290960>, allow_non_constant=true,
strict=true, manifestly_const_eval=false, 
    constexpr_dtor=false, object=<tree 0x0>) at ../../gcc/cp/constexpr.cc:7970
#3  0x000000000049f3b3 in maybe_constant_value (t=<excess_precision_expr
0x7fffea290960>, decl=<tree 0x0>, manifestly_const_eval=false) at
../../gcc/cp/constexpr.cc:8240
#4  0x00000000004e0a81 in cp_fully_fold (x=<excess_precision_expr
0x7fffea290960>) at ../../gcc/cp/cp-gimplify.cc:2367
#5  0x00000000004ef3ad in cp_convert_and_check (type=<real_type 0x7fffea1583f0
long double>, expr=<excess_precision_expr 0x7fffea290960>, complain=3) at
../../gcc/cp/cvt.cc:666
#6  0x000000000042b4e1 in convert_like_internal (convs=0x3b516a0,
expr=<excess_precision_expr 0x7fffea290960>, fn=<tree 0x0>, argnum=0,
issue_conversion_warnings=true, 
    c_cast_p=false, complain=3) at ../../gcc/cp/call.cc:8549
#7  0x000000000042b765 in convert_like (convs=0x3b516a0,
expr=<excess_precision_expr 0x7fffea290960>, fn=<tree 0x0>, argnum=0,
issue_conversion_warnings=true, c_cast_p=false, 
    complain=3) at ../../gcc/cp/call.cc:8604
#8  0x000000000042b7d8 in convert_like (convs=0x3b516a0,
expr=<excess_precision_expr 0x7fffea290960>, complain=3) at
../../gcc/cp/call.cc:8616
#9  0x000000000043da51 in perform_implicit_conversion_flags (type=<real_type
0x7fffea1583f0 long double>, expr=<excess_precision_expr 0x7fffea290960>,
complain=3, flags=262149)
    at ../../gcc/cp/call.cc:12999
#10 0x0000000000845343 in convert_for_assignment (type=<real_type
0x7fffea29abd0 long double>, rhs=<excess_precision_expr 0x7fffea290960>,
errtype=ICR_INIT, fndecl=<tree 0x0>, 
    parmnum=0, complain=3, flags=262149) at ../../gcc/cp/typeck.cc:10332
#11 0x00000000008459f4 in convert_for_initialization (exp=<tree 0x0>,
type=<real_type 0x7fffea29abd0 long double>, rhs=<excess_precision_expr
0x7fffea290960>, flags=262149, 
    errtype=ICR_INIT, fndecl=<tree 0x0>, parmnum=0, complain=3) at
../../gcc/cp/typeck.cc:10423
#12 0x000000000085075d in digest_init_r (type=<real_type 0x7fffea29abd0 long
double>, init=<excess_precision_expr 0x7fffea290960>, nested=0, flags=262149,
complain=3)
    at ../../gcc/cp/typeck2.cc:1276
#13 0x0000000000850e84 in digest_init_flags (type=<real_type 0x7fffea29abd0
long double>, init=<excess_precision_expr 0x7fffea290960>, flags=262149,
complain=3)
    at ../../gcc/cp/typeck2.cc:1380
#14 0x000000000084eaff in store_init_value (decl=<var_decl 0x7fffea13be10
ld11f>, init=<excess_precision_expr 0x7fffea290960>, cleanups=0x7fffffffd668,
flags=262149)
    at ../../gcc/cp/typeck2.cc:829
#15 0x00000000005270c3 in check_initializer (decl=<var_decl 0x7fffea13be10
ld11f>, init=<excess_precision_expr 0x7fffea290960>, flags=5,
cleanups=0x7fffffffd668)
    at ../../gcc/cp/decl.cc:7466
#16 0x000000000052d248 in cp_finish_decl (decl=<var_decl 0x7fffea13be10 ld11f>,
init=<excess_precision_expr 0x7fffea290960>, init_const_expr_p=true,
asmspec_tree=<tree 0x0>, 
    flags=5) at ../../gcc/cp/decl.cc:8468

Supposedly we should somewhere (temporarily) strip away the
EXCESS_PRECISION_EXPR and readd it after conversion, but it is unclear to me
where and under what conditions.
Somewhere where we know it is an implicit conversion (because explicit
conversion should round to semantic type)?
And only when converting (implicitly) to some other REAL_TYPE/COMPLEX_TYPE?
I mean, if we say try to initialize a class from some floating point value, we
should determine that conversion from the semantic type.
On the other side, e.g. for implicit conversion to bool, shouldn't we do the !=
0 comparison in excess precision?

The C patch strips EXCESS_PRECISION_EXPR unconditionally at the start of the
function.
So perhaps strip it in convert_for_assignment or
perform_implicit_conversion_flags if type is arithmetic type (dunno about
enums) only?

Reply via email to