octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Undefined behavior sanitizing with Clang


From: Philipp Kutin
Subject: Re: Undefined behavior sanitizing with Clang
Date: Wed, 7 Aug 2013 13:41:48 +0200

Updating a bit. For the divides-by-zero, I guess I should be reading
IEEE-754, which seems to specify the "silent" behavior in corner
cases. (Suggested on Stackoverflow [1]). Still, it's curious that the
C and C++ Standards just take the easy route of UB. So probably that
sub-discussion should be taken to the Clang UBSan people instead.


The one with the overlarge double->float cast comes from this test in data.cc:
  assert (norm (single ([1e200, 1])), single (1e200))

However, this test doesn't make terribly much sense IMO. 1e200 is not
representable as a finite single-precision FP number, so (assuming
that 1e200 casts to Inf) it really collapses to
  assert (norm (single ([Inf, 1])), single (Inf))
which is true (and passes for me), but probably not what the intent of
the test was.

The failure was actually from another test, here's the output:
  ***** assert (log2 (complex (0,Inf)), Inf + log2 (i))
!!!!! test failed
assert (log2 (complex (0, Inf)),Inf + log2 (i)) expected
Inf + 2.266i
but got
Inf - NaNi
NaNs don't match

The test passes with an Octave built with GCC, so I don't want to
exclude that my Clang build is dodgy (meaning, either the Clang which
was compiled with GCC, or the Octave that was compiled with that
Clang).


However, there are still some cases left that deserve attention IMO.
First, when running the test
  assert (normest (A), norm (A), 1e-6),
the PRNG is initialized to a negative state in normest.m:
  rand ("state", trace (A));
  % (probably)-->
  rand("state", -8)

In oct-rand.cc, that value is cast to a uint32_t. The problem with
this is that you'll likely to get an arbitrary but fixed value for
that cast. Here's a small C program:

----------
#include <stdio.h>
int main() {
    printf("%u\n", (unsigned)(-1.0));
    printf("%u\n", (unsigned)(-2.0));
}
----------

Compiling it with {GCC, G++, Clang} x {-O0, -O2} always yields 0 as
the result for both casts. So in effect, the comment
  ## Set random number generator to depend on target matrix
  v = rand ("state");
  rand ("state", trace (A));
is only partially true (whenever A has negative trace, the state will
be identical).

Personally, I'd prefer Octave's rand() to error whenever values not in
the range of uint32_t are passed as state initialization, it would be
the most honest approach. But other ways of "fixing" are thinkable,
too.


It would be most interesing to get to the source of this one
dim-vector.cc:101:9: runtime error: signed integer overflow: 3 *
-1094795586 cannot be represented in type 'int'

Could anyone give a hint on why "make check" appears to hang for me,
or maybe how to run the test suite with a bit more control, excluding
some tests? It seems that from this point on, some graphics
functionality is tested (copyobj.m)...

[1] 
http://stackoverflow.com/questions/7267838/division-by-zero-does-not-throw-sigfpe

--Philipp


reply via email to

[Prev in Thread] Current Thread [Next in Thread]