New user self-registration is disabled due to spam. For an account please email bugs-admin@lists.llvm.org with your e-mail address and full name.

Bug 17381 - -fsanitize=undefined false positive on conditional operator and floating-point division by 0 with constants
Summary: -fsanitize=undefined false positive on conditional operator and floating-poin...
Status: RESOLVED FIXED
Alias: None
Product: clang
Classification: Unclassified
Component: -New Bugs (show other bugs)
Version: trunk
Hardware: PC Linux
: P normal
Assignee: Richard Smith
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-09-26 08:24 PDT by Vincent Lefevre
Modified: 2015-12-02 19:36 PST (History)
3 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Vincent Lefevre 2013-09-26 08:24:17 PDT
ypig:~> clang --version
Debian clang version 3.4-1 (trunk) (based on LLVM 3.4)
Target: x86_64-pc-linux-gnu
Thread model: posix

ypig:~> cat tst.c
#include <stdio.h>

int main (void)
{
  volatile int i, t = 0;
  volatile double x;
  double z = 0.0;

  i = t ? 0 / 0 : 0;
  printf ("[1] %d\n", i);
  x = t ? z / z : z;
  printf ("[2] %g\n", x);
  x = t ? 0.0 / 0.0 : 0.0;
  printf ("[3] %g\n", x);
  return 0;
}

ypig:~> clang -fsanitize=undefined tst.c -o tst
tst.c:9:13: warning: division by zero is undefined [-Wdivision-by-zero]
  i = t ? 0 / 0 : 0;
            ^ ~
1 warning generated.

ypig:~> ./tst
[1] 0
[2] 0
tst.c:13:15: runtime error: division by zero
[3] 0

but because t == 0, the 0.0 / 0.0 in the third test should never be evaluated. The first two tests are OK, so that it seems related to floating-point division with constants specifically.

This bug yields a failure in the tget_flt test of the GNU MPFR trunk r8685 with:
  clang -O2 -fsanitize=undefined -fno-sanitize-recover
Comment 1 Richard Smith 2013-09-26 08:52:22 PDT
Weird. Here's the branch for the third conditional:

  %29 = load volatile i32* %t, align 4
  %30 = icmp ne i32 %29, 0
  br i1 false, label %32, label %31, !prof !0

That last line should be

  br i1 %30, label %31, label %32, !prof !0
Comment 2 Alexey Samsonov 2015-12-01 15:13:54 PST
This still reproduces for me.
Comment 3 Alexey Samsonov 2015-12-02 18:02:01 PST
Update here. Here's the problem: Clang sometimes emits a conditional_operator by emitting its left-hand side and right-hand side, followed by "select" instruction. Of course, it does so only in case when both sides are cheap to evaluate unconditionally, and evaluations are known to have no side effects. 

Well, they *do* have side effects if evaluation triggers UB *and* we are checking for it in UBSan.

Richard tells that he is working on a fix for expression constant evaluator to handle this properly.
Comment 4 Richard Smith 2015-12-02 19:36:56 PST
Fixed in r254574.