On Sat, Mar 13, 2010 at 12:17:14PM +0100, sean finney wrote:
> On Sat, Mar 13, 2010 at 11:07:13AM +0100, Iustin Pop wrote:
> > So again, sorry if I'm talking stupid things. But here the compiler does
> > exactly what you required it to do. 0x80000000 as a positive constant 
> > doesn't
> > work already, if you for example try to print it it's stored as a negative
> 
> 0x80000000 is perfectly valid to put into an int32_t (it is 4 bytes, after 
> all,
> isn't it?), i'm not sure what you're saying here.  interpreted/stored as
> signed value it has negative value equal to INT_MIN, but interpreted/stored as
> unsigned it has a positive value.

Agreed. What I meant is you can't represent 0x80000000 as a signed int.
Of course, as raw bits they are valid, but they don't represent that
number value.

> > value (it actually becomes equal to a, -0x80000000), which of course cannot 
> > be
> > negated again because it would overflow.
> 
> this "equivalence" is a bit sketchy.  to get my point, see what happens
> when you do
> 
> int32_t a = (int32_t)0x80000000 /* okay */
> 
> vs
> 
> int32_t a = -(int32_t)0x80000000 /* not okay */

Agreed.

> > Check this version:
> > #include <stdint.h>
> > #include <stdio.h>
> > 
> > int main(int argc, char *argv[]){
> >         int32_t a = -0x80000000;  /* okay, apparently */
> >         int32_t b = 0x80000000;
> >         printf("%i\n", b);
> >         printf("%i\n", a==b);
> >         if (argc > 1) b = -b;  /* not okay */
> >         return 0;
> > }
> > 
> > The problem occurs at the original assignment to b, not at the negation
> > of it.
> 
> you can run it step by step through a debugger (x86/amd64),
> the OF (overflow) flag will not be set until b is negated.
> 
> Breakpoint 1, main (argc=2, argv=0x7fffffffe698) at foo.c:4
> 4              int32_t a = -0x80000000;  /* okay, apparently */
> (gdb) display $eflags
> 1: $eflags = [ PF IF ]
> (gdb) next
> 5              int32_t b = 0x80000000;
> 1: $eflags = [ PF IF ]
> (gdb) 
> 6              printf("%i\n", b);
> 1: $eflags = [ PF IF ]
> (gdb) 
> -2147483648
> 7              printf("%i\n", a==b);
> 1: $eflags = [ PF IF ]
> (gdb) 
> 1
> 8              if (argc > 1) b = -b;  /* not okay */
> 1: $eflags = [ PF IF ]
> (gdb) 
> 9              return 0;
> 1: $eflags = [ CF PF SF IF OF ]

I'll have to study more to understand this, but thanks :)

> > > > #include <stdio.h>
> > > > #include <limits.h>
> > > > 
> > > > int main() {
> > > >         long long int j = LLONG_MAX;
> > > >         int check = 0;
> > > > 
> > > >         j -= 10;
> > > >         j += 5;
> > > >         j += 3;
> > > >         j += 2;
> > > >         check = (-j -1 ) == LLONG_MIN;
> > > > 
> > > >         printf("%d\n", check);
> > > >         return 0;
> > > > }
> > > > 
> > > > This small test program gives 1 with any combination of the flags below.
> > > 
> > > why shouldn't it?
> > 
> > Because I'm wrapping arround while doing arithmetic, and even after that, 
> > the
> > wraparound behaviour results in the original value. No uncertainties. No 
> > aborts
> > with -ftrapv.
> 
> i don't see any wraparound there, i see you subtract 10 from the max
> value, add it back, and then subtract one from the negated value,
> all of this is within the bounds of LLONG_MIN...LLONG_MAX.  then again
> i haven't had my coffee this morning so maybe i'm missing something :)
> 
> > > i'm not saying it *isn't* a compiler error, but inserting a few printfs 
> > > and
> > > the problem disappearing is also pretty common in other situations of
> > > "undefined behavior"...
> > 
> > I disagree here. Undefined behaviour related to integer arithmetic
> > should only corrupt the values in question, and a printf can't magically
> > make them correct again. So yes, it might be a compiler bug, but I still
> > don't think it's related to 64-bit arithmetic, but rather something else
> > (storage of 64-bits values in registers/memory? optimization of such
> > values? etc.).
> 
> undefined behavior means "undefined behavior".  a program can crash or
> print out haikus to the console, no assumptions :)

Agreed. But my problem as a maintainer is different:

- is the upstream code correct, so therefore I should report a bug
  against gcc on armel?
- or is the actual upstream code wrong, and this is an upstream bug?

Honestly, since it tends to look like gcc bug, the thing I care most is
to workaround this issue *somehow*. If the simplest way is to require
gcc 4.3, or a different version of gcc, then…

> > I'll run a compile with trapv, but a few small tests with the
> > ZigZagEncode64/ZigZagDecode64 a -ftrapv shows there is no overflow. Expect
> > results in a few hours…
> 
> i ran a compile last night with ftrapv along with all those warning flags,
> and it produced, around 4000(!) lines of warnings and resulted in an abort
> different from what we see in the buildd log:
> 
> /bin/bash: line 1: 25502 Aborted                 $oldpwd/protoc -I. 
> --cpp_out=$oldpwd google/protobuf/unittest.proto 
> google/protobuf/unittest_empty.proto google/protobuf/unittest_import.proto 
> google/protobuf/unittest_mset.proto 
> google/protobuf/unittest_optimize_for.proto 
> google/protobuf/unittest_embed_optimize_for.proto 
> google/protobuf/unittest_custom_options.proto 
> google/protobuf/unittest_lite.proto 
> google/protobuf/unittest_import_lite.proto 
> google/protobuf/unittest_lite_imports_nonlite.proto 
> google/protobuf/unittest_no_generic_services.proto 
> google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
> 
> you get that too?

yep, I get this at the exact same step.

> it seems that many of the warnings are valid (using signed ints to represent
> size, etc), but ultimately i'm guessing they're not related to the
> problem at hand.

Hmm. Hmm… Are there really no valid uses here, if you know what you're
doing?

Or put another way: is upstream lucky on other arches, or they know
exactly how integers wraparound and rely on the wraparound?

> if you want i can send you the stderr output from the
> build, might be useful to look for correlations from the aborting codepath.

Yes, please send, saves me from doing a compile run :)

thanks,
iustin



-- 
To UNSUBSCRIBE, email to debian-bugs-rc-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to