On Thu, Aug 11, 2011 at 5:15 PM, Florian Merz <florian.m...@kit.edu> wrote: > Dear gcc developers, > > this is about an issue that popped up in a verification project [1] based on > LLVM, but it seems to be already present in the gimple code, before llvm-gcc > transforms the gimple code to LLVM-IR. > > In short: > Calculating the difference of two pointers seems to be treated by gcc as a > signed integer subtraction. While the result should be of type ptrdiff_t and > therefore signed, we believe the subtraction itself should not be signed. > > Signed subtraction might overflow if a large positive number is subtracted > from > a large negative number. So subtracting for example from the pointer value > 0x80...0 (a large negative signed integer) the pointer value 0x7F...F (a large > positive signed integer) should in theory be perfectly fine, but trating this > as a signed subtraction causes an overflow and therefore undefined behaviour. > > Can someone explain why this is treated as a signed subtraction?
GCC restricts objects to the size of half of the address-space thus a valid pointer subtraction in C cannot overflow. Richard. > Thanks a lot and regards, > Florian > > P.S: It seems like clang does not treat this subtraction as signed. > > [1] http://baldur.iti.kit.edu/llbmc/ > > ---------- Weitergeleitete Nachricht ---------- > > Betreff: Re: [LLVMdev] Handling of pointer difference in llvm-gcc and clang > Datum: Wednesday, 10. August 2011, 19:12:43 > Von: Jack Howarth <howa...@bromo.med.uc.edu> > An: Duncan Sands <baldr...@free.fr> > Kopie: llvm...@cs.uiuc.edu > > On Wed, Aug 10, 2011 at 06:13:16PM +0200, Duncan Sands wrote: >> Hi Stephan, >> >> > We are developing a bounded model checker for C/C++ programs >> > (http://baldur.iti.kit.edu/llbmc/) that operates on LLVM's intermediate >> > representation. While checking a C++ program that uses STL containers >> > we noticed that llvm-gcc and clang handle pointer differences in >> > disagreeing ways. >> > >> > Consider the following C function: >> > int f(int *p, int *q) >> > { >> > return q - p; >> > } >> > >> > Here's the LLVM code generated by llvm-gcc (2.9): >> > define i32 @f(i32* %p, i32* %q) nounwind readnone { >> > entry: >> > %0 = ptrtoint i32* %q to i32 >> > %1 = ptrtoint i32* %p to i32 >> > %2 = sub nsw i32 %0, %1 >> > %3 = ashr exact i32 %2, 2 >> > ret i32 %3 >> > } >> > >> > And here is what clang (2.9) produces: >> > define i32 @f(i32* %p, i32* %q) nounwind readnone { >> > %1 = ptrtoint i32* %q to i32 >> > %2 = ptrtoint i32* %p to i32 >> > %3 = sub i32 %1, %2 >> > %4 = ashr exact i32 %3, 2 >> > ret i32 %4 >> > } >> > >> > Thus, llvm-gcc added the nsw flag to the sub, whereas clang didn't. >> > >> > We think that clang is right and llvm-gcc is wrong: it could be the >> > case that p and q point into the same array, that q is 0x80000000, and >> > that p is 0x7FFFFFFE. Then the sub results in a signed overflow, i.e., >> > sub with nsw is a trap value. >> > >> > Is this a bug in llvm-gcc? >> >> in llvm-gcc (and dragonegg) this is coming directly from GCC's gimple: >> >> f (int * p, int * q) >> { >> long int D.2718; >> long int D.2717; >> long int p.1; >> long int q.0; >> int D.2714; >> >> <bb 2>: >> q.0_2 = (long int) q_1(D); >> p.1_4 = (long int) p_3(D); >> D.2717_5 = q.0_2 - p.1_4; >> D.2718_6 = D.2717_5 /[ex] 4; >> D.2714_7 = (int) D.2718_6; >> return D.2714_7; >> >> } >> >> Signed overflow in the difference of two long int (ptrdiff_t) values results >> in >> undefined behaviour according to the GCC type system, which is where the nsw >> flag comes from. >> >> The C front-end generates this gimple in the pointer_diff routine. The above > is >> basically a direct transcription of what pointer_diff does. >> >> In short, I don't know if this is right or wrong; but if it is wrong it > seems >> to be a bug in GCC's C frontend. > > Shouldn't we cc this over to the gcc mailing list for clarification then? > Jack > >> >> Ciao, Duncan. >> _______________________________________________ >> LLVM Developers mailing list >> llvm...@cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > _______________________________________________ > LLVM Developers mailing list > llvm...@cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > > ------------------------------------------------------------- >