[Bug c++/91397] -Wstringop-overflow specified bound 18446744073709551615 exceeds maximum object size 9223372036854775807

2020-04-22 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91397

Martin Sebor  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |WORKSFORME

--- Comment #11 from Martin Sebor  ---
The reduced test case in comment #0 still produces the same warning with GCC 10
 but the attached test case no longer does.  I couldn't pinpoint the change
that eliminated the warning between 9 and 10 because of all the C++ errors I
get for the libstdc++ features that aren't supported by older versions of G++.

Since the small test case isn't representative of the larger one I'm going to
resolve this as WORKSFORSOME.  If the problem persists please open a new bug
with a new test case.

[Bug c++/91397] -Wstringop-overflow specified bound 18446744073709551615 exceeds maximum object size 9223372036854775807

2020-01-28 Thread marxin at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91397

Martin Liška  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2020-01-28
 CC||marxin at gcc dot gnu.org
 Ever confirmed|0   |1

[Bug c++/91397] -Wstringop-overflow specified bound 18446744073709551615 exceeds maximum object size 9223372036854775807

2019-08-08 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91397

Martin Sebor  changed:

   What|Removed |Added

 CC||msebor at gcc dot gnu.org

--- Comment #10 from Martin Sebor  ---
GCC assumes that no object can be bigger than PTRDIFF_MAX - 1 bytes and warns
when it detects code that expects otherwise.  A more general condition to add
to mem_strdupl() to avoid the warning is:

  if (len >= PTRDIFF_MAX)
__builtin_unreachable ();

GCC doesn't track pointer ranges as well as it does integers and it easily
"loses" information about their relationships.  For instance, in the functions
below, GCC folds the first test to false but it doesn't fold the second.

  void f (long a, long b)
  { 
if (a < b)
  return;

if (a - b < 0)   // folded to false
  __builtin_abort ();
  }

  void g (int *a, int *b)
  {
if (a < b)
  return;

if (a - b < 0)   // not folded
  __builtin_abort ();
  }

[Bug c++/91397] -Wstringop-overflow specified bound 18446744073709551615 exceeds maximum object size 9223372036854775807

2019-08-08 Thread steinar+gcc at gunderson dot no
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91397

--- Comment #9 from Steinar H. Gunderson  ---
Putting this at the start of mem_strdupl() suppresses the warning:

  if (len + 1 == 0) __builtin_unreachable();

This seemingly also does:

  if (static_cast(len) < 0) __builtin_unreachable();

So somehow, even though it knows that path >= last_slash (from before), it
doesn't know that last_slash - path >= 0. I don't know how easy or hard this is
to infer.

[Bug c++/91397] -Wstringop-overflow specified bound 18446744073709551615 exceeds maximum object size 9223372036854775807

2019-08-08 Thread steinar+gcc at gunderson dot no
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91397

--- Comment #8 from Steinar H. Gunderson  ---
But all of those conditions include last_slash > path.

I tried adding this just before the mem_strdupl() call:

  if (last_slash < path) {
ib::fatal() << "Logic error.";
__builtin_unreachable();
  }

and the warning still triggers.

[Bug c++/91397] -Wstringop-overflow specified bound 18446744073709551615 exceeds maximum object size 9223372036854775807

2019-08-08 Thread glisse at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91397

--- Comment #7 from Marc Glisse  ---
(In reply to Steinar H. Gunderson from comment #6)
> So basically GCC is worried that I might be calling allocate() with -1
> bytes, and gives a warning?

Yes, although it might not always give the warning, depends on various
heuristics.

> last_slash presumably has to be >= path, given that it comes out of
> strrchr().

It doesn't directly, there is a lot of last_slash-- with various conditions.

[Bug c++/91397] -Wstringop-overflow specified bound 18446744073709551615 exceeds maximum object size 9223372036854775807

2019-08-08 Thread steinar+gcc at gunderson dot no
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91397

--- Comment #6 from Steinar H. Gunderson  ---
So basically GCC is worried that I might be calling allocate() with -1 bytes,
and gives a warning?

last_slash presumably has to be >= path, given that it comes out of strrchr().
But maybe GCC won't know that.

[Bug c++/91397] -Wstringop-overflow specified bound 18446744073709551615 exceeds maximum object size 9223372036854775807

2019-08-08 Thread glisse at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91397

--- Comment #5 from Marc Glisse  ---
mem_strdupl calls allocate(len+1). If len+1 is 0, you proceed to write to
s[len] i.e. 0[-1]. I think gcc would be happier if you handled this special
case explicitly (you could error, trap, just assume it cannot happen
(__builtin_unreachable), whatever).

This type of warning can easily give false positives if your code is written
with invariants in mind that are not visible enough to the compiler.

If you had been writing to address 0, gcc would have detected that as a trap,
but it doesn't do anything special for -1.

[Bug c++/91397] -Wstringop-overflow specified bound 18446744073709551615 exceeds maximum object size 9223372036854775807

2019-08-08 Thread glisse at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91397

--- Comment #4 from Marc Glisse  ---
I guess it happens in some dead path that gcc doesn't know is dead. At some
point, you look at last_slash-path+1. Here there is a branch on whether this
number is 0, and if it is 0, nonsense happens (writing 0 at address -1, this
huge memcpy, etc). Maybe you know that last_slash is always >= path (so this
weird code path is dead) and gcc doesn't?

[Bug c++/91397] -Wstringop-overflow specified bound 18446744073709551615 exceeds maximum object size 9223372036854775807

2019-08-08 Thread steinar+gcc at gunderson dot no
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91397

--- Comment #3 from Steinar H. Gunderson  ---
Yes, the reduced one is awkward. Thus the unreduced one :-)

[Bug c++/91397] -Wstringop-overflow specified bound 18446744073709551615 exceeds maximum object size 9223372036854775807

2019-08-08 Thread glisse at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91397

--- Comment #2 from Marc Glisse  ---
if (g == 0) return (char *)malloc(0);
for (;;)
;

so the only way this can return is if g is 0. This means that in j, k is -1,
and you are calling memcpy with a huge argument. So at least in the reduced
testcase, the warning makes some sense.

[Bug c++/91397] -Wstringop-overflow specified bound 18446744073709551615 exceeds maximum object size 9223372036854775807

2019-08-08 Thread steinar+gcc at gunderson dot no
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91397

--- Comment #1 from Steinar H. Gunderson  ---
Created attachment 46689
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46689=edit
Unreduced test case