On Tue, 7 Jan 2025 at 18:07, Frank Mehnert
<frank.mehn...@kernkonzept.com> wrote:
>
> On Dienstag, 7. Januar 2025 17:38:52 MEZ Kjetil Oftedal wrote:
> > On Tue, 7 Jan 2025 at 17:09, Frank Mehnert
> > <frank.mehn...@kernkonzept.com> wrote:
> > >
> > > On Dienstag, 7. Januar 2025 16:45:03 MEZ Kjetil Oftedal wrote:
> > > > On Tue, 7 Jan 2025 at 16:19, Frank Mehnert
> > > > <frank.mehn...@kernkonzept.com> wrote:
> > > > >
> > > > > On Dienstag, 7. Januar 2025 15:55:28 MEZ Kjetil Oftedal wrote:
> > > > > > On Tue, 7 Jan 2025 at 15:33, Frank Mehnert
> > > > > > <frank.mehn...@kernkonzept.com> wrote:
> > > > > > > [...]
> > > > > > >
> > > > > > > With offset=1 and x=0xffffffff'fffffff, y will 0, so y does not 
> > > > > > > belong to
> > > > > > > the same object as x. There is no other value of x which could 
> > > > > > > lead to a
> > > > > > > result y<x with offset=1!
> > > > > > >
> > > > > > > The comparison tests the wrap around and adapts end_ptr in that 
> > > > > > > case.
> > > > > > >
> > > > > > > Again: If there was a wrap around, then the pointer arithmetic 
> > > > > > > operation
> > > > > > > was wrong (undefined behavior). Hence, we can remove the test 
> > > > > > > plus the code
> > > > > > > which is executed if the test succeeds.
> > > > > >
> > > > > > [...]
> > > > > >
> > > > > > I see the point. I just don't agree with the conclusion.
> > > > > > As I see it the LLVM group is claiming that if there is any 
> > > > > > possiblity for UB,
> > > > > > even if it is dependent on input arguments, then it is always UB, 
> > > > > > and
> > > > > > the compiler can
> > > > > > remove code as it sees fit. (Which will be a nightmare for security 
> > > > > > code)
> > > > >
> > > > > I admit I thought so some time ago but in my opinion you do a wrong
> > > > > conclusion:
> > > > >
> > > > > There is a test in the code.
> > > > >
> > > > > The result of the test can _only_ be true if the code before the test
> > > > > triggered undefined behavior.
> > > > >
> > > > > In other words, if the test succeeded, then we can be sure that the 
> > > > > test
> > > > > compared two pointers belonging to different objects -- which is 
> > > > > undefined
> > > > > behavior.
> > > > >
> > > > > Therefore, the compiler is fine removing the test because the 
> > > > > compiler does
> > > > > not support the case where the test result is true.
> > > > >
> > > > > If the test result is false, everything is fine, both objects may or 
> > > > > may not
> > > > > point to different objects, but the compiler assumes that they do. 
> > > > > But: If
> > > > > the test result is false, end_ptr does not need an adaption, 
> > > > > therefore that
> > > > > line can be optimized out.
> > > > >
> > > > > [...]
> > > >
> > > > Let us flip the variables around and review:
> > > > E.g.
> > > > if ( str < end_ptr )
> > > > instead of
> > > > if ( end_ptr < str )
> > > >
> > > > Should the compiler then always evaluate the clause to true?
> > > > end_ptr might still be lower than str due to overflow in the artihmetic.
> > >
> > > Not sure what you mean by "then always evaluate the clause to true".
> > > Are you asking if the compiler may assume that (str < end_ptr) is always
> > > true because only this is "defined behavior"?
> > >
> > > No, the compiler cannot assume that. But this is no contradiction to what
> > > I said before.
> > >
> > > The compiler does the following steps for the original problem,
> > > (end_ptr < str):
> > >
> > >   1. Generate code for the test.
> > >   2. The test result can either be true or false. The compiler generates
> > >      code for both cases.
> > >   3. No code needs to be generated for the case "false".
> > >   4. Generate code for the case "true".
> > >   5. Optimize the code. The compiler observes that the "false" case can
> > >      only happen if the previous calculation triggered undefined behavior
> > >      (str and end_ptr point to different objects).
> > >
> > > In your case (str < end_ptr), the compiler still needs to generate code 
> > > for
> > > the test because the compiler must assume that both pointers (str and 
> > > end_ptr)
> > > belong to the same object, therefore the test is valid.
> > >
> > > In the original case (end_ptr < str), the compiler knows for sure that 
> > > both
> > > pointers belong to different objects!
> >
> > [...]
> >
> > Is this true for all cases for strings?
> >
> > > In the original case (end_ptr < str), the compiler knows for sure that
> > > both pointers belong to different objects!
> >
> > ---
> > const char* str = "Hello World!"
> > const char* sub_str = strstr(str, "Wor");
> >
> > strnlen(sub_str, X);
> > ---
> >
> > For some values of X end_ptr is still pointing to a valid array entry
> > for the original "Hello World" string,
> > even if it is not within the "World!" substring. Is it then not
> > pointing to a valid array of objects?
> > (E.g if X is the unsigned representation of -1,-2,...-6)
>
> OK, I think you have a point.
>
> Basically this derives into the question if adding a huge offset to a pointer
> is the same as subtracting a small offset from a pointer. So far I couldn't
> find any C++ rule related to this problem.
>
> Kind regards,
>
> Frank
> --
> Dr.-Ing. Frank Mehnert, frank.mehn...@kernkonzept.com, +49-351-41 883 224
>
> Kernkonzept GmbH.  Sitz: Dresden.  Amtsgericht Dresden, HRB 31129.
> Geschäftsführer: Dr.-Ing. Michael Hohmuth
>
>
Hi,

I think it is purely academic as this point though :)

The change is probably fine. Just a bit annoyed that clang forces
changes to the code
in a lot of projects, instead of clang accepting defacto standard patterns.

Best regards,
Kjetil Oftedal
_______________________________________________
devel mailing list -- devel@uclibc-ng.org
To unsubscribe send an email to devel-le...@uclibc-ng.org

Reply via email to