[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Undefined behavior sanitizing with Clang
From: |
Mike Miller |
Subject: |
Re: Undefined behavior sanitizing with Clang |
Date: |
Wed, 7 Aug 2013 09:12:54 -0400 |
On Wed, Aug 7, 2013 at 13:41:48 +0200, Philipp Kutin wrote:
> 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.
Probably. You'll note there's also a couple of lines not far from there:
%! flo = single(1e-300);
%! fhi = single(1e+300);
This seems to me like a copy/paste from the double-precision section.
> 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
I get the same result with Debian clang 3.3-4.
> 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).
Not exactly. Try the following amended test program instead. Literals
and variables are treated differently in the case of casting to an
unsigned.
---
#include <stdio.h>
double num() { return -2.0; }
int main() {
printf("%u\n", (unsigned)(-1.0));
printf("%u\n", (unsigned)(-2.0));
printf("%u\n", (unsigned)(num()));
}
---
> 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.
If Matlab's rand('state',s) accepts negative numbers, then ours does
as well. The best we can do is map any possible input values to the
uint32_t array in a deterministic way.
> 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)...
I don't see either of these problems with my build (Debian clang
3.3-4, no sanitize options used).
--
mike