PR c/82071 reports how compound assignment operators such as += handle excess precision inconsistently with the same operation done with a plain assignment and binary operator. There were (at least) two problems with how compound assignments handled excess precision. The EXCESS_PRECISION_EXPR for an argument with excess precision was removed too early, resulting in build_binary_op being called with an rhs operand whose type reflected the evaluation format, so not having sufficient information to achieve the intended semantics in all cases, and then the code called c_fully_fold on the results of build_binary_op without allowing for the possibility of an EXCESS_PRECISION_EXPR as the result, so leading to double rounding of the result (first to its semantic type, then to the type of the LHS of the assignment) instead of the intended single rounding. This patch fixes those problems by keeping EXCESS_PRECISION_EXPRs further through build_modify_expr (and build_atomic_assign which it calls) and only removing them locally where appropriate. Note that while this patch should achieve *consistency*, that's consistency with the understanding of C99 semantics that I originally intended to implement. For the particular case in the testcase, C11 semantics (from N1531) differ from that understanding of C99 semantics, in that an implicit conversion of an integer to floating point can have excess precision. I intend to implement those C11 semantics separately (conditional on flag_isoc11) (which will also mean that building conditional expressions can produce a result with excess precision even when the arguments lack excess precision, where previously it could not), and not to close the bug until that is also done. Tested for x86_64-pc-linux-gnu. PR c/82071 gcc/c: * c-typeck.c (build_atomic_assign): Handle argument with excess precision. Ensure any EXCESS_PRECISION_EXPR is present in argument passed to build_binary_op and convert_for_assignment but not for call to c_fully_fold. (build_modify_expr): Do not remove EXCESS_PRECISION_EXPR early. Ensure build_binary_op is called with argument with original semantic type. Avoid calling c_fully_fold with an EXCESS_PRECISION_EXPR from build_binary_op. gcc/testsuite: * gcc.target/i386/excess-precision-7.c: New test. From-SVN: r251603
Name |
Last commit
|
Last update |
---|---|---|
.. | ||
ChangeLog | Loading commit data... | |
Make-lang.in | Loading commit data... | |
c-array-notation.c | Loading commit data... | |
c-aux-info.c | Loading commit data... | |
c-convert.c | Loading commit data... | |
c-decl.c | Loading commit data... | |
c-errors.c | Loading commit data... | |
c-fold.c | Loading commit data... | |
c-lang.c | Loading commit data... | |
c-lang.h | Loading commit data... | |
c-objc-common.c | Loading commit data... | |
c-objc-common.h | Loading commit data... | |
c-parser.c | Loading commit data... | |
c-parser.h | Loading commit data... | |
c-tree.h | Loading commit data... | |
c-typeck.c | Loading commit data... | |
config-lang.in | Loading commit data... | |
gccspec.c | Loading commit data... | |
gimple-parser.c | Loading commit data... | |
gimple-parser.h | Loading commit data... |