Hi! The C fully folding code expects that EXCESS_PRECISION_EXPR is never the rhs of a COMPOUND_EXPR, instead it should wrap the whole COMPOUND_EXPR if needed. The following patch does that, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2017-03-20 Jakub Jelinek <ja...@redhat.com> PR c/80097 * c-typeck.c (build_binary_op): Add EXCESS_PRECISION_EXPR only around optional COMPOUND_EXPR with ubsan instrumentation. * gcc.dg/ubsan/pr80097.c: New test. --- gcc/c/c-typeck.c.jj 2017-03-16 17:18:24.000000000 +0100 +++ gcc/c/c-typeck.c 2017-03-20 08:59:37.515399725 +0100 @@ -11856,14 +11856,16 @@ build_binary_op (location_t location, en else if (TREE_CODE (ret) != INTEGER_CST && int_operands && !in_late_binary_op) ret = note_integer_operands (ret); - if (semantic_result_type) - ret = build1 (EXCESS_PRECISION_EXPR, semantic_result_type, ret); protected_set_expr_location (ret, location); if (instrument_expr != NULL) ret = fold_build2 (COMPOUND_EXPR, TREE_TYPE (ret), instrument_expr, ret); + if (semantic_result_type) + ret = build1_loc (location, EXCESS_PRECISION_EXPR, + semantic_result_type, ret); + return ret; } --- gcc/testsuite/gcc.dg/ubsan/pr80097.c.jj 2017-03-20 08:58:24.227483256 +0100 +++ gcc/testsuite/gcc.dg/ubsan/pr80097.c 2017-03-20 08:57:15.000000000 +0100 @@ -0,0 +1,10 @@ +/* PR c/80097 */ +/* { dg-do compile } */ +/* { dg-options "-std=c89 -fsanitize=float-divide-by-zero" } */ + +int +foo (double a) +{ + int b = (1 / a >= 1); + return b; +} Jakub