[Bug c/103343] Invalid codegen when comparing pointer to one past the end and then dereferencing that pointer

2021-11-22 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103343

--- Comment #5 from Andrew Pinski  ---
> The only thing that is questionable is the comparison with pointer past the 
> end of an object, which is merely unspecified.

Ok, it is a dup of bug 93051.

*** This bug has been marked as a duplicate of bug 93051 ***

[Bug c/103343] Invalid codegen when comparing pointer to one past the end and then dereferencing that pointer

2021-11-22 Thread leni536 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103343

--- Comment #4 from Lénárd Szolnoki  ---
A complete program example:

f.h:
```
#pragma once
extern int x[1];
extern int y;

int f(int* p, int* q);
```

f.cpp:
```
#include "f.h"

int f(int* p, int* q) {
*q = y;
if (p == (x + 1)) {
*p = 2;
return y;
}
return 0;
}
```

x_y.cpp:
```
#include "f.h"

int y;
int x[1];
```

main.cpp:
```
#include "f.h"

int main() {
y=1;
int i;
return f(, );
}
```

Compile with `g++ -o main main.cpp f.cpp x_y.cpp`.
https://godbolt.org/z/G4KTKc7hE

The well-formed program above has two possible evaluations, due to the
unspecified comparison. In one evaluation `main` returns 0, in the other it
returns 2. Compiled with g++ the program returns 1.

Within the single invocation of `f` `p` is pointer to an object, namely `y`.
Even after the unspecified comparison evaluates to true, `p` remains a pointer
to `y`. Therefore dereferencing `p` is still valid in that branch.

I don't think that it is a duplicate of bug 61502. The program does not rely on
the object representation of the pointer objects, their printed value or their
value converted to uintptr_t. The only thing that is questionable is the
comparison with pointer past the end of an object, which is merely unspecified.

[Bug c/103343] Invalid codegen when comparing pointer to one past the end and then dereferencing that pointer

2021-11-22 Thread gabravier at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103343

--- Comment #3 from Gabriel Ravier  ---
Well the code does not invoke undefined behavior here, it just so happens that
`p == (x + 1)` because `y` happens to be laid out in memory after `x` (note:
this isn't a guarantee, of course, but GCC can't prove this isn't the case as
it's defined in another TU and it's quite easy to make this happen). The
comparison doesn't imply the pointers have the same provenance, and the
standard has a specific provision for this exact comparison:

"If one pointer represents the address of a complete object, and another
pointer represents the address one past the last element of a different
complete object,72 the result of the comparison is unspecified."
- [expr.eq] (https://eel.is/c++draft/expr.eq#3.1)

Also, `y` isn't accessed through a pointer to `x`: I've already said the case
where the function is incorrect is when `f` is called with `` as the first
argument. If doing `p == (x + 1)` implied they derived from the same object,
then that would imply after doing ` == (x + 1)` doing `*` would invoke
undefined behavior which is obviously ridiculous.

Although there is a case to be made that this code is stupid and deserves a
warning, though... I won't argue with that, this code is just something I wrote
to test things after a 3 hour long conversation about DR 260
() and a lot of
standardese lawyering, so it's not intended to be real life code. I'd say,
though, that the warning is quite inaccurate in the details of what it's
saying, as `p` isn't actually equivalent to `(x + 1)` just because `p == (x +
1)`.

[Bug c/103343] Invalid codegen when comparing pointer to one past the end and then dereferencing that pointer

2021-11-22 Thread msebor at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103343

Martin Sebor  changed:

   What|Removed |Added

 CC||msebor at gcc dot gnu.org

--- Comment #2 from Martin Sebor  ---
(In reply to Gabriel Ravier from comment #0)
> PS: This also results in plenty of invalid warnings when compiling with
> -Wall:
> 
> : In function 'f':
> :6:9: warning: array subscript 1 is outside array bounds of 'int[1]'
> [-Warray-bounds]
> 6 | *p = 2;
>   | ^~
> :1:12: note: at offset 4 into object 'x' of size 4
> 1 | extern int x[1], y;
>   |^

The warning in this case is valid and helpful: it's undefined to attempt to
access an object using a pointer derived from a pointer to an unrelated object
(the equality between pointers to adjacent objects notwithstanding).

[Bug c/103343] Invalid codegen when comparing pointer to one past the end and then dereferencing that pointer

2021-11-20 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103343

Andrew Pinski  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |DUPLICATE

--- Comment #1 from Andrew Pinski  ---
Dup of bug 61502. (or a dup of bug 93052 or many others).

*** This bug has been marked as a duplicate of bug 61502 ***