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: 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


reply via email to

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