[Bug ipa/115237] -Wsuggest-attribute=pure false positive for obviously non-pure function

2024-05-27 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115237

--- Comment #2 from Paul Eggert  ---
(In reply to Richard Biener from comment #1)
> 'pure' means the function has no side-effect besides reading global memory
> _when it returns_, so it's valid to turn
> 
>  x = unite (5, 6);
>  y = unite (5, 6);
> 
> into
> 
>  x = unite (5, 6);
>  y = x;
Although that particular optimization is valid, as I understand it pure
functions have an additional constraint: they must return. So, if 'unite' is
pure it's also valid to turn this statement:

  unite (5, 6);

into a no-op. For example, when compiled with gcc -O2 -S, this program:

  int unite (int, int) __attribute__((pure));

  int
  main (int argc, char **argv)
  {
unite (argc, argc + 1);
  }

generates the same machine code as the no-op program 'int main (int argc, char
**argv) {}', because GCC optimizes away the call to 'unite'.

Since this sort of optimization is invalid for calls to the 'unite' function I
gave (which sometimes does not return), 'unite' should not be given the
attribute 'pure'.

[Bug c/115237] New: -Wsuggest-attribute=pure false positive for obviously non-pure function

2024-05-26 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115237

Bug ID: 115237
   Summary: -Wsuggest-attribute=pure false positive for obviously
non-pure function
   Product: gcc
   Version: 14.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

This is gcc (GCC) 14.1.1 20240507 (Red Hat 14.1.1-1) on x86-64. I ran into this
problem when compiling tzcode; this is a stripped-down version of the problem.
Compile the following with 'gcc -O2 -Wsuggest-attribute=pure -S t.i':

  _Noreturn void error ();

  int
  unite (int a, int b)
  {
int sum;
if (a & b)
  error ();
return a | b;
  }

GCC complains:

  t.i: In function ‘unite’:
  t.i:4:3: warning: function might be candidate for attribute ‘pure’ if it is
known to return normally [-Wsuggest-attribute=pure]
  4 |   unite (int a, int b)
|   ^

However, an important goal of the function is to report an error and exit if
a is nonzero. The function must not be pure, because pure functions must
return; they cannot exit or longjmp out or whatever. So this warning is clearly
incorrect.

I suggest suppressing the warning if the function that might call a noreturn
function.

[Bug ipa/109914] --suggest-attribute=pure misdiagnoses static functions

2024-05-26 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109914

--- Comment #6 from Paul Eggert  ---
(In reply to Jan Hubicka from comment #5)
> yes, however both const and pure attributes allows compiler to also
> remove the call if return value is unused.  So here finiteness matters.
Thanks for mentioning that. I now see that there are other differences between
const/pure and unsequenced/reproducible: see N2956
, which says
that the GCC notions are stricter than the corresponding C23 notions. N2956
doesn't mention finiteness as one of the strictness differences, though, I
guess because the C23 standardizers didn't notice that part of the GCC
documentation.

So my idea that "[[reproducible]] and __attribute__((pure)) are supposed to be
the same thing" is incorrect. Similarly, [[unsequenced]] and
__attribute__((const) are not the same thing. Oh well. We may need to change
Gnulib because of these discrepancies.

>> I agree with Bruno's main point that none of this stuff should matter for
>> static functions. --suggest-attribute=* warnings are useless chatter for
>> static functions.
> It helps the compiler to solve the halting problem.
This isn't a halting-problem situation. If GCC cannot deduce that a static
function halts, and if no calls to that function discard the return value (so
the optimization you mentioned can't apply), then suggesting to the developer
to add __attribute__((pure)) merely wastes developers' time, and developers
either disable the warning or ignore it, neither of which is good. So Bruno's
suggestion of suppressing the false positive for his test case still seems to
be a good one.

[Bug ipa/109914] --suggest-attribute=pure misdiagnoses static functions

2024-05-25 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109914

Paul Eggert  changed:

   What|Removed |Added

 CC||eggert at cs dot ucla.edu

--- Comment #4 from Paul Eggert  ---
(In reply to Jan Hubicka from comment #2)
> The reason why gcc warns is that it is unable to prove that the function is
> always finite.

I don't see why finiteness matters. If a pure function returns the first time
it's called, and if there's no change to visible state after that, it should
return the second time with the same value. And if the pure function didn't
return the first time evaluation won't even get to the second time. So common
subexpression elimination (which is the point of 'pure') will work even if a
pure function does not return.

C23 has standardized this stuff with the [[reproducible]] attribute, and as far
as I can see (the wording is admittedly murky) C23 does not impose a finiteness
constraint on reproducible functions. If my reading of C23 is correct, GCC
should not impose finiteness constraints on reproducible functions when it gets
around to implementing [[reproducible]], and if [[reproducible]] and
__attribute__((pure)) are supposed to be the same thing then GCC should drop
the  finiteness constraint on pure functions as well.


I agree with Bruno's main point that none of this stuff should matter for
static functions. --suggest-attribute=* warnings are useless chatter for static
functions.


(I ran into this GCC bug when building recent versions of the TZDB code, which
is why I found this bug report.)

[Bug tree-optimization/114965] [13/14/15 Regression] wrong code generated for Emacs/Gnulib strftime (regression from 13.2)

2024-05-07 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114965

--- Comment #12 from Paul Eggert  ---
Thanks for fixing GCC.

I installed into Gnulib a patch that clarifies strftime's implementation, and
this also works around the GCC bug. It'll take some time for this to propagate
out, though, as Gnulib is a source code library and each package incorporates
Gnulib code when it sees fit. The patch is here:

https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=4121ae7ad2859331447fe719d255e3d22953f327

[Bug c/114965] New: wrong code generated for Emacs/Gnulib strftime (regression from 13.2)

2024-05-06 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114965

Bug ID: 114965
   Summary: wrong code generated for Emacs/Gnulib strftime
(regression from 13.2)
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 58111
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58111=edit
Test with "gcc -O2 u5.i; ./a.out". The output should be a "123   " line.

I ran into this problem when building newish GNU Emacs with gcc (GCC) 14.0.1
20240411 (Red Hat 14.0.1-0) on x86-64.

GCC generates incorrect code for emacs/lib/nstrftime.c, which is taken from
Gnulib. The incorrect code causes some of Emacs's own test cases ("make check")
to fail. Possibly you'll see a similar problem with glibc strftime, though I
haven't tested this.

A stripped-down version of the problem is attached. Compile and run it with:

  gcc -O2 u5.i
  ./a.out

The output is "123000", but it should be "123   " - that is, three spaces
should follow the "123" instead of three zeros.

Looking at the generated code, it appears that GCC gets confused by the
complicated logic involving the 'pad' local variable, switch statements, etc.
The code generated for line 62 behaves as if (pad == '0' || pad == '+') is
true, even though it is false because pad == '_'.

Compiling without -O2 makes the problem go away. The problem does not occur
with GCC 13.2.0, which I built myself. Nor does it occur with gcc (GCC) 8.5.0
20210514 (Red Hat 8.5.0-4).

[Bug c/114893] New: -Wanalyzer-null-dereference false positive in Emacs select_window

2024-04-29 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114893

Bug ID: 114893
   Summary: -Wanalyzer-null-dereference false positive in Emacs
select_window
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 58074
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58074=edit
"gunzip t.i; gcc -std=gnu23 -O2 -S -fanalyzer t.i" to see false positivfe

This is gcc (GCC) 14.0.1 20240411 (Red Hat 14.0.1-0) on x86-64. Uncompress the
attached program t.i (derived from Emacs src/textconv.c) and compile with:

gcc -std=gnu23 -O2 -S -fanalyzer t.i

The incorrect output is at the end of this bug report. The bug seems to be
fragile, in that if I edit the program a bit the false positive goes away. A
curious thing is that GCC complains about dereferencing w in line 94026 in this
context:

 94023struct window *w;
 94024w = XWINDOW (window);
 94025if ((w)->mini
 94026&& BUFFERP ((w)->contents)
 94027&& !EQ (window, Factive_minibuffer_window ()))
 94028  ...

even though line 95026 is reachable only via line 94025, which dereferences w
but is not diagnosed.

Anyway, here's the incorrect output:

t.i: In function ‘select_window’:
t.i:94026:10: warning: dereference of NULL ‘w’ [CWE-476]
[-Wanalyzer-null-dereference]
94026 |   && BUFFERP ((w)->contents)
  |  ^~~
  ‘handle_pending_conversion_events’: events 1-3
|
|95150 | handle_pending_conversion_events (void)
|  | ^~~~
|  | |
|  | (1) entry to ‘handle_pending_conversion_events’
|..
|95166 |   for ((tail) = Vframe_list; (CONSP (tail) && (frame = XCAR
(tail), true));
|  | 
~
|  ||   |
|  ||   (3) inlined
call to ‘XCAR’ from ‘handle_pending_conversion_events’
|  |(2) following ‘true’
branch...
|
+--> ‘XCAR’: event 4
   |
   | 8266 |   return XCONS (c)->u.s.car;
   |  |  ^
   |  |  |
   |  |  (4) inlined call to ‘XCONS’ from ‘XCAR’
   |
   +--> ‘XCONS’: event 5
  |
  | 8244 |   return ((struct Lisp_Cons *) ((uintptr_t) XLP (a)
-
  |  | ^~~
  |  | |
  |  | (5) ...to here
  |
<-+
|
  ‘handle_pending_conversion_events’: events 6-10
|
|95181 |   if (w && (last_point != w->ephemeral_last_point))
|  |  ^
|  |  |
|  |  (6) following ‘false’ branch (when ‘w’ is NULL)...
|..
|95199 |   action = f->conversion.actions;
|  |   ~~
|  |  |
|  |  (7) ...to here
|95200 |   if (!action)
|  |  ~
|  |  |
|  |  (8) following ‘false’ branch (when ‘action’ is
non-NULL)...
|95201 | break;
|95202 |   if (action->operation == TEXTCONV_BARRIER
|  |   ~
|  | |
|  | (9) ...to here
|..
|95207 |   w = handle_pending_conversion_events_1 (f, action);
|  |   ~~
|  |   |
|  |   (10) calling ‘handle_pending_conversion_events_1’
from ‘handle_pending_conversion_events’
|
+--> ‘handle_pending_conversion_events_1’: events 11-16
   |
   |95048 | handle_pending_conversion_events_1 (struct frame *f,
   |  | ^~
   |  | |
   |  | (11) entry to ‘handle_pending_conversion_events_1’
   |..
   |95062 |   if (conversion_disabled_p ())
   |  |  ~
   |  |  |
   |  |  (12) following ‘false’ branch...
   |95063 | return ((void *) 0);
   |95064 |   context.check = false;
   |  |   ~
   |  | |
   |  | (13) ...to here
   |..
   |95078 |   switch (operation)
   |  |   ~~
   |  |   |
   |  |   (14) following ‘case 1:’ branch...
  

[Bug middle-end/61118] [11/12/13/14/15 Regression] Indirect call generated for pthread_cleanup_push with constant cleanup function

2024-04-28 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61118

Paul Eggert  changed:

   What|Removed |Added

 CC||eggert at cs dot ucla.edu

--- Comment #32 from Paul Eggert  ---
Created attachment 58065
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58065=edit
Run "gunzip t.i.gz; gcc -O2 -S -Wclobbered t.i" to reproduce the false
positives

I ran into this bug today when compiling GNU Emacs with gcc (GCC) 14.0.1
20240411 (Red Hat 14.0.1-0) on x86-64 (Fedora 40). I didn't see it with earlier
GCC releases so I thought I'd attach a test case, derived from Emacs. Compile
with:

gunzip t.i
gcc -O2 -S -Wclobbered t.i

and the incorrect diagnostics are:

t.i: In function ‘internal_lisp_condition_case’:
t.i:7969:15: warning: variable ‘sym’ might be clobbered by ‘longjmp’ or ‘vfork’
[-Wclobbered]
 7969 |   Lisp_Object sym = XSYMBOL_WITH_POS (a)->sym;
  |   ^~~
t.i:94273:43: warning: argument ‘var’ might be clobbered by ‘longjmp’ or
‘vfork’ [-Wclobbered]
94273 | internal_lisp_condition_case (Lisp_Object var, Lisp_Object bodyform,
  |   ^~~

[Bug analyzer/107060] -fanalyzer unbearably slow when compiling GNU Emacs

2024-04-28 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107060

--- Comment #10 from Paul Eggert  ---
Created attachment 58064
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58064=edit
"gunzip u.i" then "gcc -O2 -S -fanalyzer u.i" to see how much memory GCC uses

I'm having more trouble with this when using gcc (GCC) 14.0.1 20240411 (Red Hat
14.0.1-0) on x86-64. I am now getting "gcc: fatal error: Killed signal
terminated program cc1" when compiling Emacs xdisp.c. To reproduce the problem,
run

gunzip u.i
gcc -O2 -S -fanalyzer u.i

with the attached file u.i.gz. GCC keeps allocating more and more virtual
memory, almost all via brk (wouldn't mmap be better? but I digress) until it
goes past 10 GB and exhausts my little machine's swap space (7.7G of zram).

I didn't see this problem with GCC 13 on Fedora 39, so in some sense I suppose
this is a regression. Maybe there's a new memory leak of some sort? Or perhaps
it's just -fanalyzer doing new checks for GCC 14.

[Bug analyzer/114882] New: Two -fanalyzer false positives after realloc grows buffer

2024-04-28 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114882

Bug ID: 114882
   Summary: Two -fanalyzer false positives after realloc grows
buffer
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 58062
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58062=edit
Run "gcc -O2 -fanalyzer -S v.i" to see the false positives

This is gcc (GCC) 14.0.1 20240411 (Red Hat 14.0.1-0) on x86-64. I ran into this
problem when compiling GNU Emacs's etags.c program. A simplified version of the
problem is attached.

-fanalyzer issues two false-positive diagnostics for the same source line.
Either GCC's analyzer is confused about how realloc works, or it is confused
about buffer size calculations, or both.

To reproduce the problem, compile the attached program v.i with:

gcc -O2 -fanalyzer -S v.i

This program calls realloc in a common way when growing a buffer. The original
Emacs code doubles the buffer size when reallocating; in this simplified
version the code merely adds 1 to the buffer size when reallocating. Either
way, GCC incorrectly warns about out-of-bounds writes and about accessing
uninitialized storage.

I plan to work around the problem for now by disabling
-Wanalyzer-use-of-uninitialized-value when compiling etags.c.

Here are the diagnostics from the above GCC invocation. They're all false
positives.

v.i: In function ‘oemacs_etags_readline_internal’:
v.i:30:26: warning: use of uninitialized value ‘p[-1]’ [CWE-457]
[-Wanalyzer-use-of-uninitialized-value]
   30 |   if (buffer < p && p[-1] == '\r')
  | ~^~~~
  ‘oemacs_etags_readline_internal’: events 1-13
|
|   11 |   if (!buffer)
|  |  ^
|  |  |
|  |  (1) following ‘false’ branch (when ‘buffer’ is non-NULL)...
|..
|   14 |   char *pend = p + buf_size;
|  | 
|  | |
|  | (2) ...to here
|..
|   18 |   if (p == pend)
|  |  ~
|  |  |
|  |  (3) following ‘true’ branch (when ‘p == pend’)...
|   19 | {
|   20 |   size_t new_buf_size = buf_size + 1;
|  |  
|  |  |
|  |  (4) ...to here
|   21 |   if (new_buf_size < buf_size)
|  |  ~
|  |  |
|  |  (5) following ‘false’ branch (when ‘buf_size <=
new_buf_size’)...
|   22 | __builtin_abort ();
|   23 |   buffer = realloc (buffer, new_buf_size);
|  |~~
|  ||
|  |(6) ...to here
|  |(7) when ‘realloc’ succeeds, moving buffer
|  |(8) region created on heap here
|   24 |   if (!buffer)
|  |  ~
|  |  |
|  |  (9) following ‘false’ branch (when ‘buffer’ is
non-NULL)...
|   25 | __builtin_abort ();
|   26 |   p = buffer + buf_size;
|  |   ~
|  | |
|  | (10) ...to here
|..
|   30 |   if (buffer < p && p[-1] == '\r')
|  |  ~  ~
|  |  |   |
|  |  |   (12) ...to here
|  |  |   (13) use of uninitialized value ‘p[-1]’
here
|  |  (11) following ‘true’ branch (when ‘buffer < p’)...
|
v.i:32:12: warning: heap-based buffer overflow [CWE-122]
[-Wanalyzer-out-of-bounds]
   32 |   *p++ = c;
  |   ~^~~
  ‘oemacs_etags_readline_internal’: events 1-10
|
|   10 |   char *buffer = malloc (buf_size);
|  |  ^
|  |  |
|  |  (1) capacity: 1 byte
|   11 |   if (!buffer)
|  |  ~
|  |  |
|  |  (2) following ‘false’ branch (when ‘buffer’ is non-NULL)...
|..
|   14 |   char *pend = p + buf_size;
|  |   
|  | |
|  | (3) ...to here
|..
|   18 |   if (p == pend)
|  |  ~
|  |  |
|  |  (4) following ‘false’ branch (when ‘p != pend’)...
|  |  (8) following ‘false’ branch (when ‘p != pend’)...
|..
|   30 |   if (buffer < p && p[-1] == '\r')
|  |  ~
|  |  |
|  |  (5) ...to here
|  |  (6) 

[Bug c/114870] New: stddef.h problem with -Wsystem-headers on Fedora 40

2024-04-26 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114870

Bug ID: 114870
   Summary: stddef.h problem with -Wsystem-headers on Fedora 40
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 58049
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58049=edit
fix stddef.h to survive multiple includes, some with __need_size_t etc.

I found this when trying to build GNU diffutils on Fedora 40. This is gcc (GCC)
14.0.1 20240411 (Red Hat 14.0.1-0) on x86-64. Compile the following two-line
program t.c with 'gcc -std=gnu23  -Wsystem-headers -E t.c >t.i':

  #include 
  #include 

GCC issues the following diagnostics:

  In file included from /usr/include/time.h:29,
   from t.c:2:
  /usr/lib/gcc/x86_64-redhat-linux/14/include/stddef.h:457:9: warning:
"__STDC_VERSION_STDDEF_H__" redefined
457 | #define __STDC_VERSION_STDDEF_H__   202311L
| ^
  In file included from t.c:1:
  /usr/lib/gcc/x86_64-redhat-linux/14/include/stddef.h:457:9: note: this is the
location of the previous definition
457 | #define __STDC_VERSION_STDDEF_H__   202311L
| ^

It seems that  is not properly protected against multiple includes,
some with __need_size_t and __need_NULL and some without.

The attached patch to stddef.h worked around the problem for me.

[Bug c/114869] New: GCC says nullptr_t is a C built in but it should be in

2024-04-26 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114869

Bug ID: 114869
   Summary: GCC says nullptr_t is a C built in but it should be in

   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

This is gcc (GCC) 14.0.1 20240411 (Red Hat 14.0.1-0) on x86-64. Compile the
following one-line program with 'gcc -S t.c':

   nullptr_t x;

GCC fails to issue a diagnostic that is required because nullptr_t is used
without being defined.

Conversely, compile the following program with 'gcc -std=gnu23 -Wshadow
-Wsystem-headers -S t.c':

   #include 
   nullptr_t x;

GCC issues the following incorrect diagnostic:

  In file included from t.c:1:
  /usr/lib/gcc/x86_64-redhat-linux/14/include/stddef.h:450:31: warning:
declaration of ‘nullptr_t’ shadows a global declaration [-Wshadow]
450 |   typedef __typeof__(nullptr) nullptr_t;
|   ^
  cc1: note: shadowed declaration is here

It seems that gcc defines nullptr_t as a built in identifier, which is
incorrect; nullptr_t should be defined by  just like ptrdiff_t is.

[Bug tree-optimization/114833] New: --suggest-attribute=returns_nonnull misdiagnoses functions with __attribute__((nonnull))

2024-04-23 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114833

Bug ID: 114833
   Summary: --suggest-attribute=returns_nonnull misdiagnoses
functions with __attribute__((nonnull))
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

This is gcc (GCC) 14.0.1 20240411 (Red Hat 14.0.1-0) on Fedora 40 x86-64. Put
this code into the file t.i:

  extern char const *foo () __attribute__ ((returns_nonnull));
  char const *
  foo ()
  {
return "abc";
  }

and compile it with:

  gcc -S -O2 -Wsuggest-attribute=returns_nonnull t.i

The output is:

  t.i: In function ‘foo’:
  t.i:3:3: warning: function might be candidate for attribute ‘returns_nonnull’
[-Wsuggest-attribute=returns_nonnull]
  3 |   foo ()
|   ^~~

This diagnostic is obviously wrong, as foo is already declared with the
suggested attribute.

[Bug middle-end/114347] wrong constant folding when casting __bf16 to int

2024-03-20 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114347

--- Comment #10 from Paul Eggert  ---
(In reply to Jakub Jelinek from comment #6)
> You can use -fexcess-precision=16 if you don't want treating _Float16 and
> __bf16 as having excess precision.  With excess precision, I think the above
> behavior is correct.

So the constant 257.0bf16 has a value that the type __bf16 cannot represent?
Although the C standard allows this sort of thing, it doesn't sound wise.

For example, it breaks a common use of 'typeof' that is given in the GCC manual
section 6.7 "Referring to a Type with 'typeof'". In this program:

  #define MAX(a, b) ((a) > (b) ? (a) : (b))
  #define max(a, b) \
({ typeof (a) _a = (a); \
   typeof (b) _b = (b); \
   _a > _b ? _a : _b; })

  int main (void)
  {
returnmax(257.0bf16, 256.0bf16)
   == MAX(257.0bf16, 256.0bf16);
  }

'main' surprisingly returns 0 when I expect pretty much everybody would expect
it to return 1. This is because "max" surprisingly changes the values of its
arguments before comparing, whereas MAX does not.

If GCC's "bf16" and "f16" suffixes arranged for floating point constants to be
representable as __bf16 and _Float16, respectively, we wouldn't have this sort
of confusion. Surely that would be better than the current situation.

[Bug middle-end/114347] wrong constant folding when casting __bf16 to int

2024-03-14 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114347

--- Comment #2 from Paul Eggert  ---
(In reply to Andrew Pinski from comment #1)
> I am not so sure that 257.0bf16 gets rounded to 256.

It should get rounded to 256, since 257 has no exact representation in __bf16
and 256 is the closest representable value.

And GCC does this correctly in my experiments. If I compile this:

  __bf16 w = 256.0bf16;
  __bf16 x = 257.0bf16;

with "gcc -O2 -S", the assembly code says ".value 17280" for both constants.

[Bug c/114347] New: wrong constant folding when casting __bf16 to int

2024-03-14 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114347

Bug ID: 114347
   Summary: wrong constant folding when casting __bf16 to int
   Product: gcc
   Version: 13.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

This is gcc (GCC) 13.2.1 20231205 (Red Hat 13.2.1-6) on Fedora 39. I found this
bug when looking into a GNU coreutils report 
originally reported against Clang (Clang has a different bug).

Compile and run this program:

  __bf16 x = 257.0bf16;
  int
  main (void)
  {
return (int) x != (int) 257.0bf16;
  }

with "gcc -O2 v.c; ./a.out; echo $?". This prints "1"; it should print "0".

The problem is that GCC constant-folds '(int) 257.0bf16' to 257. This is
incorrect, as 257.0bf16 is exactly equal to 256.0bf16, due to rounding when the
constant is parsed. The expression '(int) x' correctly yields 256 at runtime,
and 256 is not equal to the 257 incorrectly yielded by the constant folding.

[Bug tree-optimization/51084] bounds checking not optimized to a single comparison

2024-02-18 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51084

Paul Eggert  changed:

   What|Removed |Added

 CC||eggert at cs dot ucla.edu

--- Comment #4 from Paul Eggert  ---
I still see the problem with gcc (GCC) 13.2.1 20231205 (Red Hat 13.2.1-6) on
x86-64.

[Bug analyzer/113963] analyzer-null-dereference, analyzer-malloc-leak false alarms in Gnulib savedir.c

2024-02-16 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113963

--- Comment #1 from Paul Eggert  ---
Created attachment 57442
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=57442=edit
test program without line number directives (also compressed)

This is the same program as savedir.i, except without line number directives.
Like the other test program, it's compressed with gzip.

[Bug analyzer/113963] New: analyzer-null-dereference, analyzer-malloc-leak false alarms in Gnulib savedir.c

2024-02-16 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113963

Bug ID: 113963
   Summary: analyzer-null-dereference, analyzer-malloc-leak false
alarms in Gnulib savedir.c
   Product: gcc
   Version: 13.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 57441
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=57441=edit
test program with line number directives

I ran into this problem when compiling programs using Gnulib's lib/savedir.c
code.

This is gcc (GCC) 13.2.1 20231205 (Red Hat 13.2.1-6) on x86-64. Compile the
attached programs with:

gcc -O2 -fanalyzer -S savedir.i
gcc -O2 -fanalyzer -S savedis.i

Two problems. First, although savedis.i is merely a copy of savedir.i with line
number directives removed, the second command outputs an extra
-Wanalyzer-null-argument warning that the first command does not. Surely the
presence of line number directives should not affect which warnings are issued.

Second and more important, all the warnings are false positives. The pointers
can't possibly be null when the sizes are nonzero, and there is no memory leak.

The source files savedir.i and savedis.i are attached, compressed.

Here are the incorrect warnings that I get:

$ gcc -O2 -fanalyzer -S savedir.i
savedir.c: In function ‘streamsavedir’:
savedir.c:135:42: warning: dereference of NULL ‘entries’ [CWE-476]
[-Wanalyzer-null-dereference]
  135 |   entries[entries_used].name = used;
  |   ~~~^~
  ‘streamsavedir’: event 1
|
|savedir.c:106:6:
|  106 |   if (dirp == NULL)
|  |  ^
|  |  |
|  |  (1) following ‘false’ branch (when ‘dirp’ is non-NULL)...
|
  ‘streamsavedir’: event 2
|
|cc1:
| (2): ...to here
|
  ‘streamsavedir’: events 3-5
|
|savedir.c:116:10:
|  116 |   if (! dp)
|  |  ^
|  |  |
|  |  (3) following ‘false’ branch (when ‘dp’ is non-NULL)...
|..
|  121 |   entry = dp->d_name;
|  |   ~~
|  | |
|  | (4) ...to here
|  122 |   if (entry[entry[0] != '.' ? 0 : entry[1] != '.' ? 1 : 2] !=
'\0')
|  |  ~
|  |  |
|  |  (5) following ‘true’ branch...
|
  ‘streamsavedir’: event 6
|
|savedir.c:124:30:
|  124 |   idx_t entry_size = _D_EXACT_NAMLEN (dp) + 1;
|
  ‘streamsavedir’: event 7
|
|savedir.c:125:14:
|  125 |   if (allocated - used <= entry_size)
|  |  ^
|  |  |
|  |  (7) following ‘true’ branch...
|
  ‘streamsavedir’: event 8
|
|  126 | name_space = xpalloc (name_space, ,
|
  ‘streamsavedir’: events 9-14
|
|savedir.c:130:14:
|  130 |   if (cmp)
|  |  ^
|  |  |
|  |  (9) following ‘true’ branch (when ‘cmp’ is
non-NULL)...
|  131 | {
|  132 |   if (entries_allocated == entries_used)
|  |  ~~
|  |  |  |
|  |  |  (10) ...to here
|  |  (11) following ‘false’ branch...
|..
|  135 |   entries[entries_used].name = used;
|  |   ~
|  |  |   |
|  |  (12) ...to here (14) dereference of NULL
‘entries + (long unsigned int)entries_used * 16’
|  |  (13) ‘entries’ is NULL
|
savedir.c:169:3: warning: leak of ‘name_space’ [CWE-401]
[-Wanalyzer-malloc-leak]
  169 |   free (entries);
  |   ^~
  ‘savedir’: events 1-2
|
|  179 | savedir (char const *dir, enum savedir_option option)
|  | ^~~
|  | |
|  | (1) entry to ‘savedir’
|..
|  182 |   if (! dirp)
|  |  ~
|  |  |
|  |  (2) following ‘false’ branch (when ‘dirp’ is non-NULL)...
|
  ‘savedir’: events 3-5
|
|savedir.c:186:26:
|  186 |   char *name_space = streamsavedir (dirp, option);
|  |  ^~~~
|  |  |
|  |  (3) ...to here
|  |  (4) allocated here
|  |  (5) calling ‘streamsavedir’ from
‘savedir’
|
+--> ‘streamsavedir’: event 6
   |
   |savedir.c:96:1:
   |   96 | streamsavedir (DIR *dirp, enum 

[Bug analyzer/102671] -Wanalyzer-null-dereference false positive when compiling GNU Emacs

2024-01-06 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102671

--- Comment #6 from Paul Eggert  ---
(In reply to Paul Eggert from comment #4)
> Created attachment 56996 [details]
> marker.i example from GNU Emacs
> 
> Here is another example of the problem, taken from bleeding-edge GNU Emacs

Ooops, please ignore this marker.i example; I included it by mistake here. This
was work product while I was working on bug 113253. The xselect.i example
should be good.

[Bug analyzer/113253] New: gcc -g causes -fanalyzer to issue false positive

2024-01-06 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113253

Bug ID: 113253
   Summary: gcc -g causes -fanalyzer to issue false positive
   Product: gcc
   Version: 13.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 56998
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=56998=edit
marker1.i file illustrating -fanalyzer -g bug

This is a weird one, taken from bleeding-edge GNU Emacs, compiled with gcc
(GCC) 13.2.1 20231205 (Red Hat 13.2.1-6) on x86-64. Compile the attached with:

gcc -O2 -S -g -fanalyzer marker1.i

I get the following diagnostic, which is a false positive. If I do not use the
gcc's "-g" option, the compile is clean with no diagnostics.

marker1.i: In function ‘set_marker_internal’:
marker1.i:17754:7: warning: check of ‘(long unsigned int)buffer +
18446744073709551611’ for NULL after already dereferencing it
[-Wanalyzer-deref-before-check]
17752 |   if (NILP (position)
  |   ~~~
17753 |   || (MARKERP (position) && !XMARKER (position)->buffer)
  |   ~~
17754 |   || !b)
  |   ^
  ‘set_marker_restricted’: events 1-2
|
|17803 | set_marker_restricted (Lisp_Object marker, Lisp_Object position,
|  | ^
|  | |
|  | (1) entry to ‘set_marker_restricted’
|..
|17806 |   return set_marker_internal (marker, position, buffer,
|  |  ~~
|  |  |
|  |  (2) calling ‘set_marker_internal’ from
‘set_marker_restricted’
|17807 |1
|  |~
|17808 |);
|  |~
|
+--> ‘set_marker_internal’: events 3-4
   |
   |17743 | set_marker_internal (Lisp_Object marker, Lisp_Object
position,
   |  | ^~~
   |  | |
   |  | (3) entry to ‘set_marker_internal’
   |..
   |17749 |   struct buffer *b = live_buffer (buffer);
   |  |  ~
   |  |  |
   |  |  (4) inlined call to ‘live_buffer’ from
‘set_marker_internal’
   |
   +--> ‘live_buffer’: event 5
  |
  |17737 |   struct buffer *b = decode_buffer (buffer);
  |  |  ^~
  |  |  |
  |  |  (5) calling ‘decode_buffer’
from ‘set_marker_internal’
  |
‘decode_buffer’: events 6-9
  |
  |11274 | decode_buffer (Lisp_Object b)
  |  | ^
  |  | |
  |  | (6) entry to ‘decode_buffer’
  |11275 | {
  |11276 |   return NILP (b) ?
(current_thread->m_current_buffer) : (CHECK_BUFFER (b), XBUFFER (b));
  |  | 
~~~
  |  | 
  |  |
  |  | 
  |  (8) ...to here
  |  | 
  |  (9) calling ‘CHECK_BUFFER’ from ‘decode_buffer’
  |  | 
  (7) following ‘false’ branch (when ‘b’ is non-NULL)...
  |
  +--> ‘CHECK_BUFFER’: event 10
 |
 |10892 | CHECK_BUFFER (Lisp_Object x)
 |  | ^~~~
 |  | |
 |  | (10) entry to ‘CHECK_BUFFER’
 |
 +--> ‘CHECK_BUFFER’: event 11
|
|10894 |   CHECK_TYPE (BUFFERP (x),
builtin_lisp_symbol (346), x);
|  |   ^
|  |   |
|  |   (11) inlined call to
‘BUFFERP’ from ‘CHECK_BUFFER’
|
+--> ‘BUFFERP’: event 12
   |
   |10889 |   return PSEUDOVECTORP (a,
PVEC_BUFFER);
   

[Bug analyzer/102671] -Wanalyzer-null-dereference false positive when compiling GNU Emacs

2024-01-06 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102671

--- Comment #5 from Paul Eggert  ---
Created attachment 56997
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=56997=edit
xselect.i example from GNU Emacs

Attached is another example taken from bleeding-edge GNU Emacs, compiled with
gcc (Ubuntu 13.2.0-4ubuntu3) 13.2.0 on x86-64. Compile with:

gunzip xselect.i
gcc -O2 -S -fanalyzer xselect.i

and the incorrect output is:

xselect.i: In function ‘x_get_local_selection’:
xselect.i:81397:58: warning: dereference of NULL ‘dpyinfo’ [CWE-476]
[-Wanalyzer-null-dereference]
81397 | local_value = assq_no_quit (selection_symbol,
dpyinfo->terminal->Vselection_alist);
  |   ~~~^~
  ‘Fx_get_local_selection’: events 1-2
|
|83313 | __attribute__((section (".subrs"))) static union Aligned_Lisp_Subr
Sx_get_local_selection = {{{ PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, { .a2 =
Fx_get_local_selection }, 0, 2, "x-get-local-selection", {0}, 0}}; Lisp_Object
Fx_get_local_selection
|  |   
   
  
^~
|  |   
   
   |
|  |   
   
   (1)
entry to ‘Fx_get_local_selection’
|..
|83318 |   CHECK_SYMBOL (target);
|  |   ~
|  |   |
|  |   (2) calling ‘CHECK_SYMBOL’ from ‘Fx_get_local_selection’
|
+--> ‘CHECK_SYMBOL’: events 3-4
   |
   | 7282 | (CHECK_SYMBOL) (Lisp_Object x)
   |  |  ^~~~
   |  |  |
   |  |  (3) entry to ‘CHECK_SYMBOL’
   | 7283 | {
   | 7284 |   CHECK_TYPE (SYMBOLP (x), builtin_lisp_symbol (1360), x);
   |  |   ~
   |  |   |
   |  |   (4) inlined call to ‘CHECK_TYPE’ from ‘CHECK_SYMBOL’
   |
   +--> ‘CHECK_TYPE’: event 5
  |
  | 3127 |   ((ok) ? (void) 0 : wrong_type_argument (predicate,
x));
  |  |  
~^
  |  ||
  |  |(5) following ‘true’ branch...
  |
   <--+
   |
 ‘CHECK_SYMBOL’: event 6
   |
   | 7285 | }
   |  | ^
   |  | |
   |  | (6) ...to here
   |
<--+
|
  ‘Fx_get_local_selection’: events 7-8
|
|83318 |   CHECK_SYMBOL (target);
|  |   ^
|  |   |
|  |   (7) returning to ‘Fx_get_local_selection’ from ‘CHECK_SYMBOL’
|83319 |   Lisp_Object v = value; CHECK_CONS (v);
|  |  ~~
|  |  |
|  |  (8) calling ‘CHECK_CONS’ from
‘Fx_get_local_selection’
|
+--> ‘CHECK_CONS’: events 9-10
   |
   | 7468 | CHECK_CONS (Lisp_Object x)
   |  | ^~
   |  | |
   |  | (9) entry to ‘CHECK_CONS’
   | 7469 | {
   | 7470 |   CHECK_TYPE (CONSP (x), builtin_lisp_symbol (443), x);
   |  |   ~
   |  |   |
   |  |   (10) inlined call to ‘CHECK_TYPE’ from ‘CHECK_CONS’
   |
   +--> ‘CHECK_TYPE’: event 11
  |
  | 3127 |   ((ok) ? (void) 0 : wrong_type_argument (predicate,
x));
  |  |  
~^
  |  ||
  |  |(11) following ‘false’ branch...
  |
   <--+
   |
 ‘CHECK_CONS’: event 12
   |
   | 7471 | }
   |  | ^
   |  | |
   |  | (12) ...to here
   |
<--+
|
  ‘Fx_get_local_selection’: events 13-14
|
|83319 |   Lisp_Object v = value; CHECK_CONS (v);
|  |  ^~
|  |  |
|  |  (13) returning to
‘Fx_get_local_selection’ from ‘CHECK_CONS’
|83320 |   name = XCAR (v); v = XCDR (v); CHECK_CONS (v);
|  |  ~~
|  | 

[Bug analyzer/102671] -Wanalyzer-null-dereference false positive when compiling GNU Emacs

2024-01-06 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102671

--- Comment #4 from Paul Eggert  ---
Created attachment 56996
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=56996=edit
marker.i example from GNU Emacs

Here is another example of the problem, taken from bleeding-edge GNU Emacs
compiled with gcc (Ubuntu 13.2.0-4ubuntu3) 13.2.0. Reproduce the bug via:

gcc -O2 -S -fanalyzer marker.i

The incorrect output (false positive) is:

marker.i: In function ‘BUF_ZV’:
marker.i:11203:6: warning: dereference of NULL ‘buf’ [CWE-476]
[-Wanalyzer-null-dereference]
11203 |: NILP (((buf)->zv_marker_)) ? buf->zv
  |  ^~
  ‘set_marker_restricted’: events 1-2
|
|17941 | set_marker_restricted (Lisp_Object marker, Lisp_Object position,
|  | ^
|  | |
|  | (1) entry to ‘set_marker_restricted’
|..
|17944 |   return set_marker_internal (marker, position, buffer,
|  |  ~~
|  |  |
|  |  (2) calling ‘set_marker_internal’ from
‘set_marker_restricted’
|17945 |1
|  |~
|17946 |);
|  |~
|
+--> ‘set_marker_internal’: events 3-4
   |
   |17882 | set_marker_internal (Lisp_Object marker, Lisp_Object
position,
   |  | ^~~
   |  | |
   |  | (3) entry to ‘set_marker_internal’
   |..
   |17888 |   struct buffer *b = live_buffer (buffer);
   |  |  ~
   |  |  |
   |  |  (4) inlined call to ‘live_buffer’ from
‘set_marker_internal’
   |
   +--> ‘live_buffer’: event 5
  |
  |17877 |   return BUFFER_LIVE_P (b) ? b :
  |  |  ~~^
  |  ||
  |  |(5) following ‘false’
branch...
  |17878 | ((void *)0)
  |  | ~~~
  |
   <--+
   |
 ‘set_marker_internal’: event 6
   |
   |cc1:
   | (6): ...to here
   |
 ‘set_marker_internal’: event 7
   |
   |17889 |   CHECK_MARKER (marker);
   |  |   ^
   |  |   |
   |  |   (7) calling ‘CHECK_MARKER’ from ‘set_marker_internal’
   |
   +--> ‘CHECK_MARKER’: event 8
  |
  |17584 | CHECK_MARKER (Lisp_Object x)
  |  | ^~~~
  |  | |
  |  | (8) entry to ‘CHECK_MARKER’
  |
  +--> ‘CHECK_MARKER’: event 9
 |
 |17586 |   CHECK_TYPE (MARKERP (x),
builtin_lisp_symbol (974), x);
 |  |   ^
 |  |   |
 |  |   (9) inlined call to ‘MARKERP’
from ‘CHECK_MARKER’
 |
 +--> ‘MARKERP’: event 10
|
| 8374 |   return PSEUDOVECTORP (x,
PVEC_MARKER);
|  |  ^
|  |  |
|  |  (10) inlined call to
‘PSEUDOVECTORP’ from ‘MARKERP’
|
+--> ‘PSEUDOVECTORP’: event 11
   |
   | 6413 |   return (TAGGEDP ((a),
Lisp_Vectorlike) && union vectorlike_header *) ((uintptr_t) XLP ((a)) -
(uintptr_t) ((Lisp_Word_tag) (Lisp_Vectorlike) << (((0x7fffL
   |  | 
^~~
   |  |
 |
   |  |
 (11) following ‘true’ branch...
   | 6414 | >> (3 - 1)) / 2 <
   |  | ~   
   | 6415 | (9223372036854775807L)
   |  | ~~  
   

[Bug middle-end/51446] -fno-trapping-math generates NaN constant with different sign

2023-10-01 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446

--- Comment #20 from Paul Eggert  ---
(In reply to jos...@codesourcery.com from comment #14)
> This is just the same as other unspecified things like converting an 
> out-of-range value from floating-point to integer.
No, because when GCC's constant folding disagrees with machine arithmetic, GCC
can generate code that violates the relevant standards.

Here's an example taken from Bug 111655:

  int
  main ()
  {
double x = 0.0 / 0.0;
return !__builtin_signbit (x) == !__builtin_signbit (-x);
  }

'main' must return 0 no matter what x's sign happens to be, because "-x" must
flip x's sign bit, so __builtin_signbit(-x) must yield the opposite result from
__builtin_signbit(x). However, this code returns 1 with gcc (GCC) 13.2.1
20230728 (Red Hat 13.2.1-1) on x86-64, compiled with -O2.

The bug occurs because the evaluation of __builtin_signbit (x) is
constant-folded to 0 (under the assumption that 0.0/0.0 yields +NaN), whereas
the evaluation of __builtin_signbit (-x) iuses machine arithmetic to first
calculate 0.0/0.0 (i.e., -NaN), then negate that to +NaN, and then calculate
its sign bit to be 0.

At least for this particular example, GCC is generating the wrong code so this
bug report should be decorated with a "wrong-code" keyword.

[Bug target/111655] wrong code generated for __builtin_signbit and 0./0. on x86-64 -O2

2023-10-01 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111655

--- Comment #5 from Paul Eggert  ---
> I am thinking this is all under specified really ...
Although it is indeed unspecified whether 0.0/0.0 yields -NaN or +NaN, it is
well understood that negating a floating point value flips its sign bit. The
original test case demonstrates that gcc -O2 currently mishandles this, as that
test case negates a floating point value but the sign bit remains unchanged.

Old GCC and Clang handle this correctly, as do the other non-GCC compilers that
I checked. As far as I know, only recentish gcc gets this wrong, and even then
only when optimization is enabled.

Here is a sharper example of the bug:

  int
  main ()
  {
double x = 0.0 / 0.0;
return !__builtin_signbit (x) == !__builtin_signbit(-x);
  }

This should return 0 no matter what X's value is, but it returns 1 with recent
gcc -O2 on x86-64.


> The match pattern which causes the issue:
> (simplify
>  /* signbit(x) -> 0 if x is nonnegative.  */
>  (SIGNBIT tree_expr_nonnegative_p@0)
>  { integer_zero_node; })
I don't see anything wrong with that match pattern.

I speculate that what's wrong is that GCC incorrectly thinks that 0.0/0.0 is
nonnegative. Although it's tempting to say that the sign bit of a division is
the exclusive OR of the sign bits of its operands, evidently this is not true
on x86-64 when NaNs are involved.

[Bug tree-optimization/111655] New: wrong code generated for __builtin_signbit on x86-64 -O2

2023-10-01 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111655

Bug ID: 111655
   Summary: wrong code generated for __builtin_signbit on x86-64
-O2
   Product: gcc
   Version: 13.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

I ran into this bug when testing Gnulib code on Fedora 38 x86-64, which uses
gcc (GCC) 13.2.1 20230728 (Red Hat 13.2.1-1). The problem is a regression from
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44), which does the right thing.

Here is a stripped-down version of the bug. Compile and run the following code
with "gcc -O2 t.i; ./a.out".

  int
  main ()
  {
double x = 0.0 / 0.0;
if (!__builtin_signbit (x))
  x = -x;
return !__builtin_signbit (x);
  }

Although a.out's exit status should be 0, it is 1. If I compile without -O2 the
bug goes away.

Here's the key part of the generated assembly language:

  main:
pxor%xmm0, %xmm0
divsd   %xmm0, %xmm0
xorpd   .LC1(%rip), %xmm0
movmskpd%xmm0, %eax
testb   $1, %al
sete%al
movzbl  %al, %eax
ret

  .LC1:
.long   0
.long   -2147483648

On the x86-64, the "divsd %xmm0, %xmm0" instruction that implements 0.0 / 0.0
generates a NaN with the sign bit set. I determined this by testing on a Xeon
W-1350, although I don't see where the NaN's sign bit is documented by Intel in
this situation.

It appears that GCC's optimization incorrectly assumes that 0.0 / 0.0 generates
a NaN with the sign bit clear, which causes the "if (!__builtin_signbit (x)) x
= -x;" to be compiled as if it were merely "x = -x;", which is obviously
incorrect.

[Bug middle-end/111576] gcc generates conditional branch for bitwise "&"

2023-09-24 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111576

--- Comment #5 from Paul Eggert  ---
(In reply to Andrew Pinski from comment #4)
> >111715
> 
> That is not a valid bug # either.

Sorry, I meant Bug 111575.

[Bug tree-optimization/111576] gcc generates conditional branch for bitwise "&"

2023-09-24 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111576

--- Comment #1 from Paul Eggert  ---
Created attachment 55984
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55984=edit
Generated assembly language for the program

[Bug tree-optimization/111576] New: gcc generates conditional branch for bitwise "&"

2023-09-24 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111576

Bug ID: 111576
   Summary: gcc generates conditional branch for bitwise "&"
   Product: gcc
   Version: 13.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 55983
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55983=edit
source code for branch-free test for "." or ".."

Although this is low prioriy for me, I thought I'd mention it in case it would
help GCC optimize better for others.

I looked into implementing a test for "." or ".." that was branch free. In
other words, implement "strcmp (p, ".") == 0 || strcmp (p, "..") == 0" without
using conditional branches. I came up with an expression that should do this,
but GCC translates a bitwise "&" into code that involves conditional branches.
Normally I would think conditional branches would be better avoided for bitwise
"&".

To see the situation, compile the attached program t.c with 'gcc -O2 -S t.c'
using gcc (GCC) 13.2.1 20230728 (Red Hat 13.2.1-1). It generates the attached
assembly language output t.s. The code generated for 'f' contains two
conditional branches, even though the source uses '&'. Furthermore, the
generated code evaluates the more complicated side of the '&' first, to see
whether it should evaluate the easy part, and this is not likely to be faster
than just evaluating the whole thing.

The code generated for the logically equivalent function 'g' is branch free,
but g's source code is trickier as it substitutes "~+!!" for plain "!". (The
"+" is present to work around GCC bug 111715.)

[Bug c/111575] New: -Wbool-operation mistakenly warns about an int operation

2023-09-24 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111575

Bug ID: 111575
   Summary: -Wbool-operation mistakenly warns about an int
operation
   Product: gcc
   Version: 13.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Compile the following with 'gcc -Wall -O2 -S u.c' (gcc (GCC) 13.2.1 20230728
(Red Hat 13.2.1-1 on x86-64):

int
f (int x)
{
  return ~((int) !x);
}

It generate the following false positive:

u.c: In function ‘f’:
u.c:4:10: warning: ‘~’ on a boolean expression [-Wbool-operation]
4 |   return ~((int) !x);
  |  ^
u.c:4:10: note: did you mean to use logical not?
4 |   return ~((int) !x);
  |  ^
  |  !

The expression is an int expression, not a bool expression, so it should not be
warned about.

I put in the cast to pacify GCC's false alarm but the cast didn't work.

[Bug rtl-optimization/111143] [missed optimization] unlikely code slows down diffutils x86-64 ASCII processing

2023-08-26 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43

--- Comment #7 from Paul Eggert  ---
(In reply to Alexander Monakov from comment #6)

> Are you binding the benchmark to some core in particular?

I did the benchmark on performance cores, which was my original use case. On
efficiency cores, adding the (unnecessary) 'mov eax, 1' doesn't change timing
much (0.9% speedup on one test).

> it is better to have 'add rbx, 1' instead of 'add rbx, rax' in this loop on 
> any CPU

Somewhat counterintuitively, that doesn't seem to be the case for the
efficiency cores on this platform, as the "38% faster" code is 7% slower on
E-cores. However, the use cases I'm concerned about are typically run on
performance cores.

[Bug rtl-optimization/111143] [missed optimization] unlikely code slows down diffutils x86-64 ASCII processing

2023-08-25 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43

--- Comment #5 from Paul Eggert  ---
(In reply to Alexander Monakov from comment #4)

> To evaluate scheduling aspect, keep 'mov eax, 1' while changing 'add rbx,
> rax' to 'add rbx, 1'.

Adding the (unnecessary) 'mov eax, 1' doesn't affect the timing much, which is
what I would expect on a newer processor.

When I reran the benchmark on the same laptop (Intel i5-1335U), I got 3.289s
for GCC-generated code, 2.256s for the "38% faster" code (now it's 46% faster;
don't know why) and 2.260 s for the faster code with the unnecessary 'mov eax,
1' inserted.

[Bug rtl-optimization/110823] [missed optimization] >50% speedup for x86-64 ASCII processing a la GNU diffutils

2023-08-24 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110823

--- Comment #5 from Paul Eggert  ---
Also see bug 43 for a related performance issue, which is perhaps more
important given the current state of bleeding-edge GNU diffutils.

[Bug rtl-optimization/111143] [missed optimization] unlikely code slows down diffutils x86-64 ASCII processing

2023-08-24 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43

--- Comment #2 from Paul Eggert  ---
Created attachment 55790
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55790=edit
asm code that's 38% faster on my platform

[Bug rtl-optimization/111143] [missed optimization] unlikely code slows down diffutils x86-64 ASCII processing

2023-08-24 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43

--- Comment #1 from Paul Eggert  ---
Created attachment 55789
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55789=edit
asm code generated by gcc -O2 -S

[Bug rtl-optimization/111143] New: [missed optimization] unlikely code slows down diffutils x86-64 ASCII processing

2023-08-24 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43

Bug ID: 43
   Summary: [missed optimization] unlikely code slows down
diffutils x86-64 ASCII processing
   Product: gcc
   Version: 13.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: rtl-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 55788
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55788=edit
source code illustrating the performance problem

This bug report may be related to bug 110823 (also found for diffutils) but the
symptoms differ somewhat so I am reporting it separately. I observed it with
GCC 13.1.1 20230614 (Red Hat 13.1.1-4) on x86-64.

While tuning GNU diffutils I noticed that its loops to process mostly-ASCII
text were not compiled well by GCC on x86-64. For a stripped-down example of
the problem, compile the attached program with:

gcc -O2 -S code-mcel.c

The result is in the attached file code-mcel.s. Its loop kernel assuming ASCII
text (starting on line 44) looks like this:

.L6:
movsbq  (%rbx), %rax
testb   %al, %al
js  .L4
addq%rax, %r12
movl$1, %eax
.L5:
addq%rax, %rbx
cmpq%r13, %rbx
jb  .L6

The "movl $1, %eax" immediately followed by "addq %rax, %rbx" is poorly
scheduled; the resulting dependency makes the code run quite a bit slower than
it should. Replacing it with "addq $1, %rbx" and readjusting the surrounding
code accordingly, as is done in the attached file code-mcel-opt.s, causes the
benchmark to run 38% faster on my laptop's Intel i5-1335U.

It seems that code that GCC knows is unlikely (because of __builtin_expect) is
causing the kernel, which GCC knows is likely, to be poorly optimized.

[Bug middle-end/110884] strncmp false positive with -Wstringop-overread on coreutils

2023-08-06 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110884

--- Comment #5 from Paul Eggert  ---
(In reply to Andrew Pinski from comment #4)
> PTRDIFF_MAX is required to be less than SIZE_MAX and is the max size of an
> array because otherwise a-b would be undefined ...

That is true for glibc, but it's not guaranteed by the C standard or by POSIX,
and coreutils tries to be portable to odd but conforming platforms. In theory
size_t can be 32 bits while ptrdiff_t is 64 bits. It's not much trouble to
write MIN (PTRDIFF_MAX, SIZE_MAX) in the few places where it matters.

C and POSIX also allow arrays with more than PTRDIFF_MAX elements. However,
coreutils takes pains to never create such an array, even on the non-glibc
platforms that allow them; this avoids the undefined behavior you mentioned.

[Bug middle-end/110884] strncmp false positive with -Wstringop-overread on coreutils

2023-08-05 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110884

--- Comment #3 from Paul Eggert  ---
(In reply to Richard Biener from comment #2)
> you are basically trying to use strcmp (a, b), so why not do that?

strcmp would not work on Fedora 38, or on most current coreutils platforms.

In the full coreutils code, src/system.h contains this definition[1]:

  /* n==-1 means unbounded */
  #define STREQ_LEN(a, b, n) (strncmp (a, b, n) == 0)

and src/who.c contains this expression[2]:

  STREQ_LEN (ttyname_b, utmp_buf->ut_line, UT_LINE_SIZE)

where UT_LINE_SIZE is an enum that is a small positive number on Fedora and
most platforms (where the arguments are UT_LINE_SIZE-byte character arrays,
possibly not null-terminated), and UT_LINE_SIZE is -1 on rare platforms (where
the arguments are char * pointers to null-terminated strings of unbounded
length).

By the way, we tried to work around the GCC false positive this way:

  #define STREQ_LEN(a, b, n) \
((n) < 0 ? strcmp (a, b) == 0 : strncmp (a, b, n) == 0)

but this didn't pacify GCC. When N is a negative constant expression, GCC emits
a -Wstringop-overread false positive even on the strncmp call that cannot
possibly be executed.

GCC -Wstringop-overread is supposed to (quoting the GCC manual) "Warn for calls
to string manipulation functions such as ‘memchr’, or ‘strcpy’ that are
determined to read past the end of the source sequence." But the abovementioned
calls to strncpy do not read past the end of the source sequence. So this is a
situation where either GCC's code or its documentation is incorrect.

Getting back to the code that prompted this bug report: strncmp is a primitive
designed for an oddball data structure designed back in the 1970s for tiny
machines. This data structure is a fixed-size character array that either
contains a null-terminated string, or contains all non-null bytes. Nobody liked
this data structure back in the day; people put up with it only because the
machines were so small (and hey! I was there! I wrote code for those
machines!). Nowadays the only code that should use strncmp is code like
coreutils/src/who.c that is still stick with ancient data structures designed
for 1970s machines. People who maintain legacy strncmp-using code should know
what they're doing, and if you know what you're doing (as I hope is the case
with the GNU coreutils maintainers :-) it's OK to pass SIZE_MAX to strncmp.

[1]: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/system.h#n195
[2]: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/who.c#n612



(In reply to Andrew Pinski from comment #1)
> You could use SSIZE_MAX here ...
> That is what 9223372036854775807 is in this case ...

Although that would work on GNU/Linux, POSIX doesn't guarantee it to be
portable, since ssize_t be 32 bits on platforms with 64-bit size_t (and some
historical implementations did that; on these systems syscalls like 'read'
never returned a value greater than 2**31 - 1).

Using (PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : SIZE_MAX) would work, but is (as
I wrote) awkward. Among other things, the coreutils code uses an enum to record
the size (or -1), and enums can't portably hold values as large as SIZE_MAX or
PTRDIFF_MAX. So we'd have to use a macro instead, and that would have its own
problems.

[Bug middle-end/110884] New: strncmp false positive with -Wstringop-overread on coreutils

2023-08-03 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110884

Bug ID: 110884
   Summary: strncmp false positive with -Wstringop-overread on
coreutils
   Product: gcc
   Version: 13.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: middle-end
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

I have this problem with both GCC 13.2.0 (x86-64) and GCC 13.1.1 20230614 (Red
Hat 13.1.1-4) x86-64. I see that bug 104854 was filed for something similar,
but was then closed with a request for "test cases, preferably from real code".
I hope the test case below helps.

I ran into the problem when hacking on GNU coreutils, which needs to deal with
a data structure that on some platforms is a fixed size array suitable for
strnlen, strncmp, etc., and on other platforms is a null-terminated string.
Consider the following code, abstracted from coreutils:

  int strncmp (char const *, char const *, unsigned long);

  #ifdef FIXED_SIZE_BUFFERS
  enum { SIZE = 512 };
  #else
  enum { SIZE = -1 }; /* no limit */
  #endif

  _Bool
  equal_buffers (char *a, char *b)
  {
return strncmp (a, b, SIZE) == 0;
  }

Although this code is correct, "gcc -O2 -S t.c" complains:

  t.c: In function ‘equal_buffers’:
  t.c:12:10: warning: ‘strncmp’ specified bound 18446744073709551615 exceeds
maximum object size 9223372036854775807 [-Wstringop-overread]
 12 |   return strncmp (a, b, SIZE) == 0;
|  ^~~~

This warning is irrelevant to strncmp since it doesn't matter that (size_t) -1
is greater than any object size; strncmp will stop at the first '\0' byte,
which is what is wanted when FIXED_SIZE_BUFFERS is not defined.

Although I can work around the bug by "#define SIZE 9223372036854775807" on
this platform, that's awkward and confusing.

I assume there are similar problems with strnlen etc.

I think I'll work around the problem by disabling -Wstringop-overread until the
bug is fixed somehow or a better workaround is suggested.

[Bug rtl-optimization/110823] [missed optimization] >50% speedup for x86-64 ASCII processing a la GNU diffutils

2023-07-26 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110823

--- Comment #2 from Paul Eggert  ---
Created attachment 55645
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55645=edit
code-mbcel1.s with the optimization suggested in the bug report

[Bug rtl-optimization/110823] [missed optimization] >50% speedup for x86-64 ASCII processing a la GNU diffutils

2023-07-26 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110823

--- Comment #1 from Paul Eggert  ---
Created attachment 55644
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55644=edit
gcc -O2 -S output (from code-mbcel1.i)

[Bug rtl-optimization/110823] New: [missed optimization] >50% speedup for x86-64 ASCII processing a la GNU diffutils

2023-07-26 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110823

Bug ID: 110823
   Summary: [missed optimization] >50% speedup for x86-64 ASCII
processing a la GNU diffutils
   Product: gcc
   Version: 13.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: rtl-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 55643
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55643=edit
proprocessed source code inspired by GNU diffutils

This is GCC 13.1.1 20230614 (Red Hat 13.1.1-4) on x86-64.

While tuning GNU diffutils I noticed that its loops to process mostly-ASCII
text were not compiled well by GCC on x86-64. For a stripped-down example of
the problem, compile the attached program with:

gcc -O2 -S code-mbcel1.i

The result is in the attached file code-mbcel1.s. Its loop kernel assuming
ASCII text (starting on line 212) looks like this:

  .L33:
testb   %al, %al
js  .L30
movl$1, %edx
  .L31:
movl%eax, %eax
addq%rdx, %rbx
addq%rax, %rbp
movsbl  (%rbx), %eax
testb   %al, %al
jne .L33

As I understand it the "movl %eax, %eax" is unnecessary, as all code that
reaches .L31 guarantees that %rax's top 32 bits are zero.

Also, the loop body executes "testb %al, %al" twice when once would suffice.
(As a minor point, since the compiler can easily tell that %al is positive when
the loop is entered, it can omit the first testb.)

Suppose we change the above code to the following, as is done in the attached
file code-mbcel1-opt.s:

  .L33:
movl$1, %edx
  .L31:
addq%rdx, %rbx
addq%rax, %rbp
movsbl  (%rbx), %eax
testb   %al, %al
jg  .L33
js  .L30

This small change improves performance significantly: for me, the test program
runs 55% faster on a circa-2021 Intel Xeon W-1350, and 74% faster on a
circa-2010 AMD Phenom II x4 910e, using the following commands to benchmark:

gcc -O2 code-mbcel1.i -o code-mbcel1
gcc -O2 code-mbcel1-opt.s -o code-mbcel1-opt
time ./code-mbcel1
time ./code-mbcel1-opt

[Bug tree-optimization/110333] GCC 13 -Wformat-overflow=2 should reflect real libc limits for sprintf

2023-06-21 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110333

--- Comment #2 from Paul Eggert  ---
(In reply to Jakub Jelinek from comment #1)

> it is I think a portability warning.

OK, but the 4095-byte portability concern applies to printf, too, and yet
printf doesn't get the warning because of the fix for bug#88993. sprintf should
be no different from printf in this respect.

It sounds like the the exceeds-4095 business should be a separate warning that
can be enabled/disabled independently. As the 4095-byte warning is hardly ever
useful in practice, it shouldn't be implied by the more-useful
-Wformat-overflow=2 option.

As things stand, many GNU apps are disabling -Wformat-overflow=2 because of
this kind of false positive, and unfortunately this throws out the baby with
the bathwater.

[Bug tree-optimization/88993] [9 Regression] GCC 9 -Wformat-overflow=2 should reflect real libc limits

2023-06-21 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88993

Paul Eggert  changed:

   What|Removed |Added

 CC||eggert at cs dot ucla.edu

--- Comment #16 from Paul Eggert  ---
Although fixed for printf, this bug remains for sprintf so I filed a followup
report for that, bug#110333.

[Bug tree-optimization/110333] New: GCC 13 -Wformat-overflow=2 should reflect real libc limits for sprintf

2023-06-21 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110333

Bug ID: 110333
   Summary: GCC 13 -Wformat-overflow=2 should reflect real libc
limits for sprintf
   Product: gcc
   Version: 13.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

This bug report follows up to GCC bug#88993 which was resolved as fixed in
2019. Although bug#88993 was fixed for printf, it remains for sprintf. We have
been disabling -Wformat-overflow=2 in Gnulib-using applications like coreutils
and Emacs because of this false positive. Since bug#88993 is reported as fixed
I tried enabling -Wformat-overflow=2 today, but still see problems with
sprintf.

To reproduce the bug, compile the following with "gcc -S -Wformat-overflow=2
foo.c" using gcc (GCC) 13.1.1 20230511 (Red Hat 13.1.1-2) x86-64:

  int sprintf (char *restrict, const char *restrict, ...)
__attribute__ ((nothrow));
  typedef unsigned long long ull;
  char *
  human_readable (ull n, char *buf, ull from, ull to)
  {
long double dto = to;
long double damt = n * (from / dto);
sprintf (buf, "%.0Lf", damt);
return buf;
  }
  static char buffer[1];
  char *
  call_human_readable (ull n, ull from, ull to)
  {
return human_readable (n, buffer, from, to);
  }

gcc's output is:

  foo.c: In function ‘human_readable’:
  foo.c:9:20: warning: ‘%.0Lf’ directive output between 1 and 4934 bytes may
exceed minimum required size of 4095 [-Wformat-overflow=]
  9 | sprintf (buf, "%.0Lf", damt);
|^

This is a false positive, as the output buffer is plenty large enough. In fact,
as the code stands the sprintf can generate at most 40 bytes including the
terminating NUL byte.

printf does not generate a similar warning.

The libc limit is INT_MAX bytes, not 4095 bytes. I assume the "4095" is a
revenant of an old glibc bug that is no longer of practical interest. Let's
change it to INT_MAX instead.

[Bug middle-end/109856] -Wnull-dereference false positive in Emacs itree.c (regression from GCC 12)

2023-06-15 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109856

--- Comment #1 from Paul Eggert  ---
Created attachment 55337
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55337=edit
Another illustration of the bug, taken from GNU tar

Here is another example of the bug, taken from GNU tar. Compile it with:

gcc -O2 -Wnull-dereference -S w.i

The output is:

w.i: In function ‘_write_volume_label.part.0’:
w.i:9290:30: warning: potential null pointer dereference [-Wnull-dereference]
 9290 |   label->header.typeflag = 'V';
  |   ~~~^
w.i:9290:30: warning: potential null pointer dereference [-Wnull-dereference]

This is a false positive, since the local variable 'label' cannot be null in
line 9290, given that line 9284 has checked that it is not null. Also, the two
copies of the same diagnostic are suspicious.

[Bug middle-end/90094] better handling of x == LONG_MIN on x86-64

2023-06-14 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90094

Paul Eggert  changed:

   What|Removed |Added

 CC||eggert at cs dot ucla.edu

--- Comment #3 from Paul Eggert  ---
Slightly better is this equivalent:

unsigned f (long a)
{
  return __builtin_sub_overflow (0, a, );
}

which gcc -O2 (or -Os) compiles into:

f:  xor %eax, %eax
neg %rdi
seto%al
ret

which with GCC is one byte less machine code than the __builtin_sub_overflow(a,
1, ) approach.

[Bug analyzer/110014] New: -Wanalyzer-allocation-size mishandles realloc (..., .... * sizeof (object))

2023-05-28 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110014

Bug ID: 110014
   Summary: -Wanalyzer-allocation-size mishandles realloc (...,
 * sizeof (object))
   Product: gcc
   Version: 13.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 55179
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55179=edit
compile with 'gcc -fanalyzer -S' to reproduce the bug

This is a followup to bug 109577, and reports a more serious problem with
-Wanalyzer-allocation-size: it mishandles realloc even when the last argument
is obviously a multiple of the object size.

I discovered this problem when compiling an experimental version of GNU
diffutils.

This is with gcc (GCC) 13.1.1 20230511 (Red Hat 13.1.1-2) x86-64.

Compile the attached program with:

gcc -fanalyzer -S w.i

The output is as follows. All the warnings are incorrect. The last warning is
for a call of the form realloc(p, N * sizeof (long)) even though the result is
used as a long * so the call is obviously well-sized.


w.i: In function ‘slurp’:
w.i:11:14: warning: allocated buffer size is not a multiple of the pointee's
size [CWE-131] [-Wanalyzer-allocation-size]
   11 | buffer = realloc (buffer, cc);
  |  ^~~~
  ‘slurp’: events 1-4
|
|9 |   if (!__builtin_add_overflow (file_size - file_size % sizeof
(long),
|  |  ^
|  |  |
|  |  (1) following ‘true’ branch...
|   10 |2 * sizeof (long), ))
|   11 | buffer = realloc (buffer, cc);
|  |  
|  |  |
|  |  (2) ...to here
|  |  (3) allocated ‘cc’ bytes here
|  |  (4) assigned to ‘long int *’ here; ‘sizeof (long
int)’ is ‘8’
|
w.i: In function ‘slurp1’:
w.i:18:10: warning: allocated buffer size is not a multiple of the pointee's
size [CWE-131] [-Wanalyzer-allocation-size]
   18 |   return realloc (buffer, file_size - file_size % sizeof (long));
  |  ^~~
  ‘slurp1’: events 1-2
|
|   18 |   return realloc (buffer, file_size - file_size % sizeof (long));
|  |  ^~~
|  |  |
|  |  (1) allocated ‘file_size & 18446744073709551608’ bytes
here
|  |  (2) assigned to ‘long int *’ here; ‘sizeof (long int)’ is
‘8’
|
w.i: In function ‘slurp2’:
w.i:24:10: warning: allocated buffer size is not a multiple of the pointee's
size [CWE-131] [-Wanalyzer-allocation-size]
   24 |   return realloc (buffer, (file_size / sizeof (long)) * sizeof (long));
  |  ^
  ‘slurp2’: events 1-2
|
|   24 |   return realloc (buffer, (file_size / sizeof (long)) * sizeof
(long));
|  | 
^
|  |  |
|  |  (1) allocated ‘file_size & 18446744073709551608’ bytes
here
|  |  (2) assigned to ‘long int *’ here; ‘sizeof (long int)’ is
‘8’
|

[Bug middle-end/21161] [10/11/12/13/14 Regression] "clobbered by longjmp" warning ignores the data flow

2023-05-19 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21161

Paul Eggert  changed:

   What|Removed |Added

 CC||eggert at cs dot ucla.edu

--- Comment #26 from Paul Eggert  ---
Created attachment 55122
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55122=edit
GCC bug 21161 as triggered by GNU diffutils

I ran into a similar problem when compiling GNU diffutils with gcc (GCC) 13.1.1
20230511 (Red Hat 13.1.1-2) on x86.64. Here is a stripped-down illustrating of
the diffutils problem. Compile the attached program with:

gcc -O2 -W -S pr21161.i

The output, which is a false positive, is:

pr21161.i: In function ‘find_dir_file_pathname’:
pr21161.i:22:15: warning: variable ‘match’ might be clobbered by ‘longjmp’ or
‘vfork’ [-Wclobbered]
   22 |   char const *match = file;
  |   ^

[Bug tree-optimization/101770] -Wmaybe-uninitialized false alarm with only locals in GNU diffutils

2023-05-19 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101770

--- Comment #5 from Paul Eggert  ---
I can no longer reproduce the bug in bleeding-edge GNU diffutils, so this bug
is not so important in its own right - that is, it's merely that GCC 13.1.1
still mishandles w.i.

[Bug middle-end/24639] [meta-bug] bug to track all Wuninitialized issues

2023-05-19 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24639
Bug 24639 depends on bug 101770, which changed state.

Bug 101770 Summary: -Wmaybe-uninitialized false alarm with only locals in GNU 
diffutils
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101770

   What|Removed |Added

 Status|RESOLVED|REOPENED
 Resolution|FIXED   |---

[Bug tree-optimization/101770] -Wmaybe-uninitialized false alarm with only locals in GNU diffutils

2023-05-19 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101770

Paul Eggert  changed:

   What|Removed |Added

 Resolution|FIXED   |---
 Status|RESOLVED|REOPENED
Version|11.2.1  |13.1.1

--- Comment #4 from Paul Eggert  ---
I seeing the bug with gcc (GCC) 13.1.1 20230511 (Red Hat 13.1.1-2) on x86-64
when compiling GNU diffutils, so although the bug was reported fixed on the
trunk last year, it appears that the fix hasn't propagated GCC 13 despite the
Target Milestone being 13.0.

The symptoms are:

$ gcc -O2 -Wmaybe-uninitialized -S w.i
w.i: In function ‘edit’:
w.i:50:18: warning: ‘cmd1’ may be used uninitialized [-Wmaybe-uninitialized]
   50 |   return !cmd1;
  |  ^
w.i:7:11: note: ‘cmd1’ was declared here
7 |   int cmd1;
  |   ^~~~

This appears to be the same bug as before so I am taking the liberty of
reopening the bug report.

[Bug middle-end/109856] New: -Wnull-dereference false positive in Emacs itree.c (regression from GCC 12)

2023-05-14 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109856

Bug ID: 109856
   Summary: -Wnull-dereference false positive in Emacs itree.c
(regression from GCC 12)
   Product: gcc
   Version: 13.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: middle-end
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 55083
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55083=edit
compile with 'gcc -O2 -Wnull-dereference' to reproduce the bug

This is GCC 13.1.1 20230426 (Red Hat 13.1.1-1) on x86-64, and this is a
regression from GCC (Ubuntu 12.2.0-17ubuntu1) 12.2.0. I ran into this problem
when compiling GNU Emacs src/itree.c. This is a stripped-down version of the
original problem (the code makes no sense by itself).

Compile the attached program with:

gcc -O2 -S -Wnull-dereference v2.i

The output is:

v2.i: In function ‘itree_remove_fix’:
v2.i:28:16: warning: potential null pointer dereference [-Wnull-dereference]
   28 |   if (other->left)
  |   ~^~

First, the diagnostic is confusing, because it highlights an entire expression,
which cannot itself be a null pointer dereference.

Second, there's no possible null pointer dereference here. The previous two
lines are "if (!other)__builtin_unreachable ();" so OTHER itself cannot be
null.

[Bug analyzer/109847] New: -Wanalyzer-out-of-bounds false positive with Emacs tagged pointers

2023-05-13 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109847

Bug ID: 109847
   Summary: -Wanalyzer-out-of-bounds false positive with Emacs
tagged pointers
   Product: gcc
   Version: 13.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 55078
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55078=edit
compile with 'gcc -O2 -fanalyzer' to illustrate the false positive

I ran into this problem when compiling GNU Emacs with GCC 13.1.1 20230426 (Red
Hat 13.1.1-1) on x86-64. The attached file contains stripped-down source code
to illustrate the problem. Compile it with:

gcc -O2 -fanalyzer -S analyzer-bounds-bug.i

The output is shown below. This output is incorrect, since it is complaining
about the access to the 'size' member, but that access is never executed as the
previous condition '! (((unsigned) (long) a - 5) & 7)' is false.

If you change line 51 from 'CHECK_STRING (buffer_or_name);' to 'if (0)
CHECK_STRING (buffer_or_name);' the warning goes away. But line 51 is executed
after the line being warned about. It looks like line 51 is confusing the
analyzer into thinking that line 50 can be executed in an impossible way.

As can be seen below, GCC also issues an incorrect
-Wanalyzer-use-of-uninitialized-value diagnostic, but since that may be
cascading from the earlier bug I am not reporting it separately.


In function ‘PSEUDOVECTORP’,
inlined from ‘BUFFERP’ at analyzer-bounds-bug.i:44:10,
inlined from ‘Fget_buffer’ at analyzer-bounds-bug.i:50:9:
analyzer-bounds-bug.i:39:50: warning: stack-based buffer under-read [CWE-127]
[-Wanalyzer-out-of-bounds]
   39 |   && ((struct buffer *) ((char *) a - 5))->size == code);
  |  ^~
  ‘init_buffer’: events 1-2
|
|   56 | init_buffer (void)
|  | ^~~
|  | |
|  | (1) entry to ‘init_buffer’
|..
|   60 |   Fget_buffer (scratch);
|  |   ~
|  |   |
|  |   (2) calling ‘Fget_buffer’ from ‘init_buffer’
|
+--> ‘Fget_buffer’: events 3-4
   |
   |   48 | Fget_buffer (Lisp_Object buffer_or_name)
   |  | ^~~
   |  | |
   |  | (3) entry to ‘Fget_buffer’
   |   49 | {
   |   50 |   if (! BUFFERP (buffer_or_name))
   |  | ~
   |  | |
   |  | (4) inlined call to ‘BUFFERP’ from ‘Fget_buffer’
   |
   +--> ‘BUFFERP’: event 5
  |
  |   44 |   return PSEUDOVECTORP (a, 13);
  |  |  ^
  |  |  |
  |  |  (5) inlined call to ‘PSEUDOVECTORP’ from
‘BUFFERP’
  |
  +--> ‘PSEUDOVECTORP’: events 6-8
 |
 |   38 |   return (! (((unsigned) (long) a - 5) & 7)
 |  |  ~~
 |   39 |   && ((struct buffer *) ((char *) a -
5))->size == code);
 |  |  
^~
 |  |   |  
   |
 |  |   |  
   (7) ...to here
 |  |   (6) following ‘true’ branch... 
   (8) out-of-bounds read at byte -1 but ‘’ starts at byte 0
 |
analyzer-bounds-bug.i:39:50: warning: use of uninitialized value ‘((struct
buffer *)((char *)buffer_or_name + 3))[2305843009213693951].size’ [CWE-457]
[-Wanalyzer-use-of-uninitialized-value]
   39 |   && ((struct buffer *) ((char *) a - 5))->size == code);
  |  ^~
  ‘init_buffer’: events 1-3
|
|   56 | init_buffer (void)
|  | ^~~
|  | |
|  | (1) entry to ‘init_buffer’
|..
|   59 | (&(struct Lisp_String) {{{9, "*scratch*"}}}, 4);
|  |~
|  ||
|  |(2) region created on stack here
|   60 |   Fget_buffer (scratch);
|  |   ~
|  |   |
|  |   (3) calling ‘Fget_buffer’ from ‘init_buffer’
|
+--> ‘Fget_buffer’: events 4-5
   |
   |   48 | Fget_buffer (Lisp_Object buffer_or_name)
   |  | ^~~
   |  | |
   |  | (4) entry to ‘Fget_buffer’
   |   49 | {
   |   50 |   if (! BUFFERP (buffer_or_name))
   |  | ~
 

[Bug analyzer/109839] New: -Wanalyzer-fd-leak false positive with routine dup2

2023-05-12 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109839

Bug ID: 109839
   Summary: -Wanalyzer-fd-leak false positive with routine dup2
   Product: gcc
   Version: 13.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 55072
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55072=edit
test program illustrating false positive with -Wanalyzer-fd-leak

I ran into this problem when compiling GNU Emacs with GCC 13.1.1 20230426 (Red
Hat 13.1.1-1) on x86-64. Compile the attached program (which is a stripped-down
version) with:

gcc -fanalyzer dup2-analyzer.c

The output is as follows. This is a false alarm, as the dup2 is a routine I/O
redirection and should not be considered to be a leak. In typical use, it's
better to not consider dup2's return value to be a leak.

dup2-analyzer.c: In function ‘main’:
dup2-analyzer.c:6:6: warning: leak of file descriptor ‘dup2(1, 2)’ [CWE-775]
[-Wanalyzer-fd-leak]
6 |   if (dup2 (STDOUT_FILENO, STDERR_FILENO) < 0)
  |  ^
  ‘main’: events 1-2
|
|6 |   if (dup2 (STDOUT_FILENO, STDERR_FILENO) < 0)
|  |  ~^~~
|  |  ||
|  |  |(1) opened here
|  |  (2) ‘dup2(1, 2)’ leaks here; was opened at (1)
|

[Bug analyzer/109577] -Wanalyzer-allocation-size mishandles __builtin_mul_overflow

2023-05-12 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109577

Paul Eggert  changed:

   What|Removed |Added

 CC||eggert at cs dot ucla.edu

--- Comment #1 from Paul Eggert  ---
I ran into the same problem with gcc (GCC) 13.1.1 20230426 (Red Hat 13.1.1-1)
but I don't know how to update the version number in Bugzilla.

Also, I came up with the following simpler test case. Compile this with "gcc
-O2 -S -fanalyzer foo.c", and it will complain "allocated buffer size is not a
multiple of the pointee's size" in the function "safer", but it will not
complain about the function "unsafe" (which, unlike "safer", does not check for
integer overflow and so is less safe).

void *malloc (unsigned long);

double *
unsafe (unsigned long n)
{
  return malloc (n * sizeof (double));
}

double *
safer (unsigned long n)
{
  unsigned long nbytes;
  if (__builtin_mul_overflow (n, sizeof (double), ))
return 0;
  return malloc (nbytes);
}

[Bug analyzer/109635] New: -Wanalyzer-use-of-uninitialized-value false alarm involving adding 8 to index

2023-04-26 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109635

Bug ID: 109635
   Summary: -Wanalyzer-use-of-uninitialized-value false alarm
involving adding 8 to index
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 54926
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54926=edit
compile with -O2 -fanalyzer to reproduce false positive

This is gcc (GCC) 13.0.1 20230401 (Red Hat 13.0.1-0) on x86-64. I ran into this
problem when building Coreutils. Compile the attached program with:

gcc -S -O2 -fanalyzer make-prime-list.i

The output is at the end of this bug report. It's a false alarm, since primes[i
+ 8].p is accessed only when 8 <= i + 8 < nprimes, and every entry from
primes[0] up to (but not including) primes[nprimes] is initialized by the call
to process_prime.

If you change both instances of 'i + 8' to 'i + 1' in line 1997, the false
alarm goes away. The false alarm is present if you use 'i + 2', though. I don't
know why the problem starts occuring between i + 1 and i + 2.

Here's the output:

make-prime-list.i: In function ‘output_primes’:
make-prime-list.i:1997:56: warning: use of uninitialized value ‘*primes_42(D) +
_3.p’ [CWE-457] [-Wanalyzer-use-of-uninitialized-value]
 1997 |   unsigned int d8 = i + 8 < nprimes ? primes[i + 8].p - primes[i].p
: 0xff;
  |   ~^~
  ‘main’: events 1-6
|
| 2038 | main (int argc, char **argv)
|  | ^~~~
|  | |
|  | (1) entry to ‘main’
|..
| 2045 |   if (argc != 2)
|  |  ~
|  |  |
|  |  (2) following ‘false’ branch (when ‘argc == 2’)...
|..
| 2055 |   limit = atoi (argv[1]);
|  |   ~~
|  |   |
|  |   (3) ...to here
| 2056 |   if (limit < 3)
|  |  ~
|  |  |
|  |  (4) following ‘false’ branch...
|..
| 2060 |   if ( !(limit & 1))
|  | ~~~
|  ||
|  |(5) ...to here
|..
| 2063 |   sieve = xalloc (size);
|  |   ~
|  |   |
|  |   (6) calling ‘xalloc’ from ‘main’
|
+--> ‘xalloc’: events 7-9
   |
   | 2025 | xalloc (size_t s)
   |  | ^~
   |  | |
   |  | (7) entry to ‘xalloc’
   |..
   | 2028 |   if (p)
   |  |  ~
   |  |  |
   |  |  (8) following ‘true’ branch (when ‘p’ is non-NULL)...
   | 2029 | return p;
   |  |~
   |  ||
   |  |(9) ...to here
   |
<--+
|
  ‘main’: events 10-11
|
| 2063 |   sieve = xalloc (size);
|  |   ^
|  |   |
|  |   (10) returning to ‘main’ from ‘xalloc’
| 2064 |   memset (sieve, 1, size);
| 2065 |   prime_list = xalloc (size * sizeof (*prime_list));
|  |
|  ||
|  |(11) calling ‘xalloc’ from ‘main’
|
+--> ‘xalloc’: events 12-15
   |
   | 2025 | xalloc (size_t s)
   |  | ^~
   |  | |
   |  | (12) entry to ‘xalloc’
   | 2026 | {
   | 2027 |   void *p = malloc (s);
   |  | ~~
   |  | |
   |  | (13) region created on heap here
   | 2028 |   if (p)
   |  |  ~
   |  |  |
   |  |  (14) following ‘true’ branch (when ‘p’ is non-NULL)...
   | 2029 | return p;
   |  |~
   |  ||
   |  |(15) ...to here
   |
<--+
|
  ‘main’: events 16-19
|
| 2065 |   prime_list = xalloc (size * sizeof (*prime_list));
|  |^~~~
|  ||
|  |(16) returning to ‘main’ from ‘xalloc’
| 2066 |   nprimes = 0;
| 2067 |   for (i = 0; i < size;)
|  |   
|  | |
|  | (17) following ‘true’ branch (when ‘i < size’)...
| 2068 | {
| 2069 |   unsigned p = 3 + 2 * i;
|  |~
|  |  |
|  |  (18) ...to here
| 2070 |   unsigned j;
| 2071 |   process_prime (_list[nprimes++], p);
|  |  

[Bug analyzer/109628] New: -Wanalyzer-use-of-uninitialized-value false positive on static storage

2023-04-25 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109628

Bug ID: 109628
   Summary: -Wanalyzer-use-of-uninitialized-value false positive
on static storage
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 54919
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54919=edit
compile with "gcc -fanalyzer -S" to reproduce the bug

I ran into this problem when compiling GNU coreutils fmt.c. This is with gcc
(GCC) 13.0.1 20230401 (Red Hat 13.0.1-0) on x86-64. Compile the attached
program with:

gzip -d u.i.gz
gcc -fanalyzer -S u.i

GCC outputs the following diagnostic which is a false positive because 'this'
points to the static array unused_word_type, and static storage by definition
is initialized.

u.i: In function ‘base_cost’:
u.i:5950:7: warning: use of uninitialized value ‘((unsigned
char*)&*this)[16]’ [CWE-457] [-Wanalyzer-use-of-uninitialized-value]
 5950 |   if (this->paren)
  |   ^~~~
  ‘fmt_paragraph’: events 1-4
|
| 5894 | fmt_paragraph (void)
|  | ^
|  | |
|  | (1) entry to ‘fmt_paragraph’
|..
| 5903 |   for (start = word_limit - 1; start >= unused_word_type;
start--)
|  |~
|  |  |
|  |  (2) following ‘true’
branch...
| 5904 | {
| 5905 |   best = ((COST) (! (! ((COST) 0 < (COST) -1)) ?
(COST) -1 : COST) 1 << ((sizeof (COST) * 8
|  |  
~
|  ||
|  |(3) ...to here
| 5906 | ) - 2)) - 1) * 2 + 1)));
|  | ~~~
|..
| 5913 |   wcost = line_cost (w, len) + w->best_cost;
|  |   ~~
|  |   |
|  |   (4) calling ‘line_cost’ from
‘fmt_paragraph’
|
+--> ‘line_cost’: events 5-7
   |
   | 5957 | line_cost (WORD *next, int len)
   |  | ^
   |  | |
   |  | (5) entry to ‘line_cost’
   |..
   | 5961 |   if (next == word_limit)
   |  |  ~
   |  |  |
   |  |  (6) following ‘true’ branch...
   | 5962 | return 0;
   |  |~
   |  ||
   |  |(7) ...to here
   |
<--+
|
  ‘fmt_paragraph’: events 8-9
|
| 5913 |   wcost = line_cost (w, len) + w->best_cost;
|  |   ^~
|  |   |
|  |   (8) returning to ‘fmt_paragraph’ from
‘line_cost’
|..
| 5922 |   if (w == word_limit)
|  |  ~ 
|  |  |
|  |  (9) following ‘true’ branch...
|
  ‘fmt_paragraph’: event 10
|
|cc1:
| (10): ...to here
|
  ‘fmt_paragraph’: event 11
|
| 5927 |   start->best_cost = best + base_cost (start);
|  | ^
|  | |
|  | (11) calling ‘base_cost’
from ‘fmt_paragraph’
|
+--> ‘base_cost’: events 12-13
   |
   | 5932 | base_cost (WORD *this)
   |  | ^
   |  | |
   |  | (12) entry to ‘base_cost’
   |..
   | 5950 |   if (this->paren)
   |  |   
   |  |   |
   |  |   (13) use of uninitialized value ‘((unsigned
char*)&*this)[16]’ here
   |

[Bug analyzer/109614] New: -Wanalyzer-use-after-free gets confused about a free function in Coreutils

2023-04-24 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109614

Bug ID: 109614
   Summary: -Wanalyzer-use-after-free gets confused about a free
function in Coreutils
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 54915
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54915=edit
bug reproducer

This is (GCC) 13.0.1 20230401 (Red Hat 13.0.1-0) on x86-64. Compile the
attached file (derived from GNU coreutils csplit) with:

  gzip -d a.i.gz
  gcc -fanalyzer -S a.i

The first warning is a false positive. As near as I can make out, -fanalyzer
got confused and is treating free_buffer as if it calls itself or was called
twice, which is obviously wrong (the diagnostic is confusing at any rate). The
full set of diagnostics is shown below.

a.i: In function ‘free_buffer’:
a.i:4491:21: warning: use after ‘free_buffer’ of ‘buf’ [CWE-416]
[-Wanalyzer-use-after-free]
 4491 |   for (struct line *l = buf->line_start; l;)
  | ^
  ‘main’: events 1-6
|
| 5509 | main (int argc, char **argv)
|  | ^~~~
|  | |
|  | (1) entry to ‘main’
|..
| 5588 |   if (argc - optind < 2)
|  |  ~
|  |  |
|  |  (2) following ‘false’ branch...
|..
| 5598 |   idx_t prefix_len = strlen (prefix);
|  |  ~~~
|  |  |
|  |  (3) ...to here
|..
| 5616 |   if (__builtin_add_overflow (prefix_len,
max_digit_string_len + 1, _size))
|  |  ~
|  |  |
|  |  (4) following ‘false’ branch...
| 5617 | xalloc_die ();
| 5618 |   filename_space = ximalloc (filename_size);
|  |
|  ||
|  |(5) ...to here
| 5619 |   set_input_file (argv[optind++]);
|  |   ~~~
|  |   |
|  |   (6) calling ‘set_input_file’ from ‘main’
|
+--> ‘set_input_file’: events 7-11
   |
   | 4708 | set_input_file (char const *name)
   |  | ^~
   |  | |
   |  | (7) entry to ‘set_input_file’
   | 4709 | {
   | 4710 |   if (! (strcmp (name, "-") == 0) && fd_reopen (
   |  |  ~~~
   |  |  ||  |
   |  |  ||  (9) ...to here
   |  |  |(10) following
‘false’ branch...
   |  |  (8) following ‘true’ branch (when the strings
are non-equal)...
   | 4711 |0
   |  |~
   | 4712 |   
, name,
   |  |   
~~~
   | 4713 |
   00
   |  |
   ~~
   | 4714 |
   , 0) < 0)
   |  |
   
   |..
   | 4731 | }
   |  | ~
   |  | |
   |  | (11) ...to here
   |
<--+
|
  ‘main’: events 12-21
|
| 5619 |   set_input_file (argv[optind++]);
|  |   ^~~
|  |   |
|  |   (12) returning to ‘main’ from ‘set_input_file’
|..
| 5651 | for (i = 0; i < nsigs; i++)
|  | ~
|  |   |
|  |   (13) following ‘true’ branch (when ‘i <=
10’)...
|  |   (15) following ‘true’ branch (when ‘i <=
10’)...
| 5652 |   {
| 5653 | sigaction (sig[i],
|  |~~
   

[Bug analyzer/109613] New: -Wanalyzer-null-dereference false positive involving __builtin_unreachable

2023-04-24 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109613

Bug ID: 109613
   Summary: -Wanalyzer-null-dereference false positive involving
__builtin_unreachable
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 54914
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54914=edit
compile with "gcc -fanalyzer -S -O2 u.i" to reproduce the bug

I ran into this problem compiling GNU coreutils with gcc (GCC) 13.0.1 20230401
(Red Hat 13.0.1-0) on x86-64. Compile the attached program with:

  gzip -d u.i.gz
  gcc -fanalyzer -S -O2 u.i

The output is shown below. The first warning is wrong, since 'mode' is not null
there. Although this should be deducible even without the __builtin_unreachable
calls in lines 9025, 9027, 9029 (because xpalloc returns nonnull), it's clearly
deducible with those three lines, since if new_mode_len is nonnegative (checked
by line 9029) then xpalloc must be called and therefore 'mode' cannot be null.

If I remove line 9027, which is merely "((0 <= mode_comma_len) ? (void) 0 :
__builtin_unreachable ());", the false positive goes away. There must be
something wrong there too, as that line merely adds a constraint.


u.i: In function ‘main’:
u.i:9033:28: warning: dereference of NULL ‘mode’ [CWE-476]
[-Wanalyzer-null-dereference]
 9033 | mode[mode_len] = ',';
  | ~~~^
  ‘main’: events 1-11
|
| 8988 |   while ((c = getopt_long (argc, argv,
|  |  ~
| 8989 |   
("Rcfvr::w::x::X::s::t::u::g::o::a::,::+::=::"
|  |   
~~
| 8990 | "0::1::2::3::4::5::6::7::"),
|  | 
| 8991 |long_options,
|  |~
| 8992 | ((void *)0)
|  | ~~~
| 8993 | ))
|  | ~~
| 8994 |  != -1)
|  |  ^
|  |  |
|  |  (1) following ‘true’ branch (when ‘c != -1’)...
| 8995 | {
| 8996 |   switch (c)
|  |   ~~
|  |   |
|  |   (2) ...to here
|  |   (3) following ‘case 43 ... 44:, case 48 ... 55:,
case 61:, case 88:, case 97:, case 103:, case 111:, case 114 ... 117:, case 119
... 120:’ branch...
| 8997 | {
| 8998 | case 'r':
|  | 
|  | |
|  | (4) ...to here
|..
| 9027 | ((0 <= mode_comma_len) ? (void) 0 :
__builtin_unreachable ());
|  |
~
|  |   |
|  |   (5)
following ‘false’ branch (when ‘mode_comma_len >= 0’)...
| 9028 | idx_t new_mode_len = mode_comma_len + arg_len;
|  |   
|  |   |
|  |   (6) ...to here
| 9029 | ((0 <= new_mode_len) ? (void) 0 :
__builtin_unreachable ());
| 9030 | if (mode_alloc <= new_mode_len)
|  |~
|  ||
|  |(7) following ‘false’ branch...
|..
| 9033 | mode[mode_len] = ',';
|  | 
|  | |  |
|  | |  (11) dereference of NULL ‘mode
+ (sizetype)mode_len’
|  | (8) ...to here
|  | (9) ‘mode’ is NULL
| 9034 | memcpy (mode + mode_comma_len, arg, arg_len +
1);
|  | ~
|  |  |
|  |  (10) ‘mode’ is NULL
|

[Bug c/107947] __has_c_attribute incorrectly identifies attribute as supported

2022-12-01 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107947

--- Comment #5 from eggert at cs dot ucla.edu ---
Thanks for reporting the conformance bug in TZDB. I fixed it in the TZDB
development repository here:

https://github.com/eggert/tz/commit/9cfe9507fcc22cd4a0c4da486ea1c7f0de6b075f

and the fix should appear in the next TZDB release.

[Bug analyzer/107565] New: -Wanalyzer-use-of-uninitialized-value false positive with rdrand

2022-11-07 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107565

Bug ID: 107565
   Summary: -Wanalyzer-use-of-uninitialized-value false positive
with rdrand
   Product: gcc
   Version: 12.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 53846
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53846=edit
test program illustrating the -fanalyzer false positive

This is gcc (GCC) 12.2.1 20220819 (Red Hat 12.2.1-2) on x86-64. Compile the
attached program with the command:

gcc -O2 -mrdrnd -fanalyzer -S t.c

GCC says "warning: use of uninitialized value ‘x’ [CWE-457]
[-Wanalyzer-use-of-uninitialized-value]". This is a false positive, as x cannot
possibly be uninitialized. Apparently -fanalyzer is confused about how
__builtin_ia32_rdrand64_step works.

GCC 11.3.0 does not issue this diagnostic, so this is a regression.

[Bug c/107116] New: -Woverflow false alarm in unreachable code

2022-10-01 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107116

Bug ID: 107116
   Summary: -Woverflow false alarm in unreachable code
   Product: gcc
   Version: 12.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

This bug is following up on a bug reported against coreutils
. In the coreutils bug report, a build failed
because of a false alarm generated by GCC. I simplified the source and came up
with two different GCC test cases, shown in the shell transcript below. I
generated this transcript on Fedora 36 x86-64, which has gcc (GCC) 12.2.1
20220819 (Red Hat 12.2.1-2).

In the first (shorter) test case v.i, gcc -O2 -Woverflow incorrectly complains
about INT_MAX + 1900 in code that is unreachable because YEAR must be both
negative and nonnegative to reach the expression, which is impossible.

The second (longer) test case t.c has the same false alarm; I'm including it
mostly to give you a feel for the false alarm's context in coreutils, which is
even more complicated than the second test case.


$ cat v.i
enum { INT_MAX = 0x7fff };
_Bool
to_tm_year (long year)
{
  return
(year < 0
 && (year < 0
 ? year + 1900 < 0
 : INT_MAX + 1900 < year));
}
$ gcc -O2 -S -Woverflow v.i
v.i: In function ‘to_tm_year’:
v.i:9:20: warning: integer overflow in expression of type ‘int’ results in
‘-2147481749’ [-Woverflow]
9 |  : INT_MAX + 1900 < year));
  |^
$ cat t.c
enum { INT_MAX = 0x7fff, INT_MIN = -1 - INT_MAX };
#define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v))
#define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v))
#define _GL_EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)
#define _GL_INT_SUBTRACT_RANGE_OVERFLOW(a, b, tmin, tmax) \
  (((a) < 0) == ((b) < 0) \
   ? ((a) < (b) \
  ? !(tmin) || -1 - (tmin) < (b) - (a) - 1 \
  : (tmax) < (a) - (b)) \
   : (a) < 0 \
   ? ((!_GL_EXPR_SIGNED (_GL_INT_CONVERT ((a) - (tmin), b)) && (a) - (tmin) <
0) \
  || (a) - (tmin) < (b)) \
   : ((! (_GL_EXPR_SIGNED (_GL_INT_CONVERT (tmax, b)) \
  && _GL_EXPR_SIGNED (_GL_INT_CONVERT ((tmax) + (b), a))) \
   && (tmax) <= -1 - (b)) \
  || (tmax) + (b) < (a)))
#define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, ut, t) \
  ((t) ((ut) (a) op (ut) (b)))
#define _GL_INT_OP_CALC(a, b, r, op, overflow, ut, t, tmin, tmax) \
  (overflow (a, b, tmin, tmax) \
   ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 1) \
   : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 0))
#define _GL_INT_OP_WRAPV(a, b, r, op, overflow) \
   _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
int, INT_MIN, INT_MAX)
#define _GL_INT_SUBTRACT_WRAPV(a, b, r) \
   _GL_INT_OP_WRAPV (a, b, r, -, _GL_INT_SUBTRACT_RANGE_OVERFLOW)
#define INT_SUBTRACT_WRAPV(a, b, r) _GL_INT_SUBTRACT_WRAPV (a, b, r)

_Bool
year_out_of_range (long year)
{
  int i;
  return INT_SUBTRACT_WRAPV (year, 1900, );
}
$ gcc -O2 -S -Woverflow t.c
t.c: In function ‘year_out_of_range’:
t.c:16:17: warning: integer overflow in expression of type ‘int’ results in
‘-2147481749’ [-Woverflow]
   16 |   || (tmax) + (b) < (a)))
  | ^
t.c:20:4: note: in expansion of macro ‘_GL_INT_SUBTRACT_RANGE_OVERFLOW’
   20 |   (overflow (a, b, tmin, tmax) \
  |^~~~
t.c:24:8: note: in expansion of macro ‘_GL_INT_OP_CALC’
   24 |_GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
  |^~~
t.c:27:4: note: in expansion of macro ‘_GL_INT_OP_WRAPV’
   27 |_GL_INT_OP_WRAPV (a, b, r, -, _GL_INT_SUBTRACT_RANGE_OVERFLOW)
  |^~~~
t.c:28:37: note: in expansion of macro ‘_GL_INT_SUBTRACT_WRAPV’
   28 | #define INT_SUBTRACT_WRAPV(a, b, r) _GL_INT_SUBTRACT_WRAPV (a, b, r)
  | ^~
t.c:34:10: note: in expansion of macro ‘INT_SUBTRACT_WRAPV’
   34 |   return INT_SUBTRACT_WRAPV (year, 1900, );
  |  ^~
$

[Bug analyzer/107060] New: -fanalyzer unbearably slow when compiling GNU Emacs

2022-09-27 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107060

Bug ID: 107060
   Summary: -fanalyzer unbearably slow when compiling GNU Emacs
   Product: gcc
   Version: 12.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 53634
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53634=edit
compressed source file that gcc -S -fanalyzer -O2 compiles vey slowly

For a while, gcc -fanalyzer has been so unbearably slow when compiling GNU
Emacs that we Emacs developers disable -fanalyzer unless the builder
specifically asks for it, which almost nobody does because it's sooo slow. I
haven't bothered to file a bug report because I assumed the analyzer code was
still being worked on and tuned, but I just now tried -fanalyzer again on a new
machine and it was still so slow that I am finally filing a bug report.

The biggest pole in the tent is when gcc compiles Emacs's xdisp.c file, which
is large for Emacs (38 Klines) but not that large. I am attaching the
preprocessed output as the file u.i.gz. Compile it with:

gzip -d u.i
gcc -S -fanalyzer -O2 u.i

On my older Fedora 36 desktop (AMD Phenom II X4 910e) with gcc (GCC) 12.2.1
20220819 (Red Hat 12.2.1-2) GCC takes 12 minutes 3 seconds, which is
ridiculous. On my newer Ubuntu 22.04 desktop (Intel Xeon W-1350) with gcc-12
(Ubuntu 12.1.0-2ubuntu1~22.04) 12.1.0, GCC takes 3 minutes 43 seconds, which is
still way too long.

Could you please take a look at this test case and see what's slowing down
-fanalyzer? If you can't improve GCC, is there some easy way we Emacs
developers can rewrite the source to avoid the performance issue, whatever it
is? Thanks.

[Bug middle-end/106947] New: -Waddress + bool + pragma generates meaningless diagnostic

2022-09-14 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106947

Bug ID: 106947
   Summary: -Waddress + bool + pragma generates meaningless
diagnostic
   Product: gcc
   Version: 12.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: middle-end
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

I found this while testing Gnulib with gcc (GCC) 12.1.1 20220507 (Red Hat
12.1.1-1) on x86-64.

Compile the following with "gcc -Waddress -S t.c":

#pragma GCC diagnostic ignored "-Waddress"
int s;
_Bool e = 
int
main ()
{
  int error = 0;
  {
_Bool e1 = 
if (!e1)
  error = 1;
  }
  return error;
}

The output is the meaningless diagnostic:

t.c: In function ‘main’:
t.c:2:5: note: ‘s’ declared here
2 | int s;
  | ^

[Bug analyzer/106436] New: -Wanalyzer-null-dereference false positive suggests data corruption in GCC

2022-07-25 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106436

Bug ID: 106436
   Summary: -Wanalyzer-null-dereference false positive suggests
data corruption in GCC
   Product: gcc
   Version: 12.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 53347
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53347=edit
Compile with -O2 -S -fanalyzer (GCC 12 x86-64) to reproduce the bug.

I found this problem when compiling Gnu Tar with GCC 12.1.1 20220507 (Red Hat
12.1.1-1) on x86-64. Compile the attached program t.i with:

gcc -O2 -S -fanalyzer t.i

The output is below. The first diagnostic is a false positive. Attempting to
silence it by inserting "if (!listed_loc) abort ();" before line 13975 causes
unrelated diagnostics to change, suggesting that there's some sort of confusion
in the internal data structure that GCC uses to represent the program.

t.i: In function ‘optloc_eq’:
t.i:12193:8: warning: dereference of NULL ‘a’ [CWE-476]
[-Wanalyzer-null-dereference]
12193 |   if (a->source != b->source)
  |   ~^~~~
  ‘main’: events 1-4
|
|14348 | main (int argc, char **argv)
|  | ^~~~
|  | |
|  | (1) entry to ‘main’
|..
|14373 |   if (stdopen ())
|  |  ~
|  |  |
|  |  (2) following ‘false’ branch...
|..
|14383 |   allocated_archive_names = 10;
|  |   
|  |   |
|  |   (3) ...to here
|..
|14400 |   decode_options (argc, argv);
|  |   ~~~
|  |   |
|  |   (4) calling ‘decode_options’ from ‘main’
|
+--> ‘decode_options’: events 5-7
   |
   |13764 | decode_options (int argc, char **argv)
   |  | ^~
   |  | |
   |  | (5) entry to ‘decode_options’
   |..
   |13767 |   struct option_locus loc = { OPTS_COMMAND_LINE, 0,
0, 0 };
   |  |   ~~~
   |  |   |
   |  |   (6) ‘loc.prev’ is NULL
   |..
   |13890 |   parse_default_options ();
   |  |   ~
   |  |   |
   |  |   (7) calling ‘parse_default_options’ from
‘decode_options’
   |
   +--> ‘parse_default_options’: events 8-10
  |
  |13721 | parse_default_options (struct tar_args
*args)
  |  | ^
  |  | |
  |  | (8) entry to ‘parse_default_options’
  |..
  |13725 |   struct option_locus loc = { OPTS_ENVIRON,
"TAR_OPTIONS", 0, 0 };
  |  |   ~~~
  |  |   |
  |  |   (9) ‘loc.prev’ is NULL
  |  |   (10) ‘loc.prev’ is
NULL
  |
   <--+
   |
 ‘decode_options’: events 11-20
   |
   |12176 |   return option_class[id];
   |  |  
   |  |  |
   |  |  (17) ...to here
   |  |  (18) ‘0’ is NULL
   |  |  (19) ‘0’ is NULL
   |..
   |13890 |   parse_default_options ();
   |  |   ^
   |  |   |
   |  |   (11) returning to ‘decode_options’ from
‘parse_default_options’
   |13891 | 
   |13892 |   if (argp_parse (, argc, argv, 0x08, ,
))
   |  |  ~
   |  |  |
   |  |  (12) following ‘false’ branch...
   |13893 | exit (2);
   |13894 |   if (args.o_option)
   |  |   ~
   |  |   |
   |  |   (13) ...to here
   

[Bug analyzer/106428] New: -Wanalyzer-file-leak false positive with if ((ptr = fopen(...)) == NULL) ...

2022-07-24 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106428

Bug ID: 106428
   Summary: -Wanalyzer-file-leak false positive with if ((ptr =
fopen(...)) == NULL) ...
   Product: gcc
   Version: 12.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 53342
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53342=edit
Compile with '-O2 -S -fanalyzer' to demonstrate the bug

This is GCC 12.1.1 20220507 (Red Hat 12.1.1-1) on x86-64. Compile the attached
program t.i with 'gcc -fanalyzer -O2 -S t.i'. It outputs a false alarm as shown
at the end of this comment. If I replace lines 12046-12049:

   if ((ent->v.file.fp = fopen (ent->v.file.name, "r")) == 
  ((void *)0)
  )
 open_fatal (ent->v.file.name);

with the following (which is equivalent, since ent->v.file.fp is NULL before
the code is executed):

  FILE *fp = fopen (ent->v.file.name, "r");
  if (!fp)
open_fatal (ent->v.file.name);
  ent->v.file.fp = fp;

then the first diagnostic, which is a false positive, goes away.

Here is the diagnostic output, the first of which is the false positive.

t.i: In function ‘read_next_name’:
t.i:12046:7: warning: leak of FILE ‘fopen(*ent.v.file.name, "r")’
[CWE-775] [-Wanalyzer-file-leak]
12046 |if ((ent->v.file.fp = fopen (ent->v.file.name, "r")) ==
  |   ^
  ‘name_scan’: events 1-2
|
|13033 | name_scan (const char *file_name)
|  | ^
|  | |
|  | (1) entry to ‘name_scan’
|..
|13039 |   struct name *cursor = namelist_match (file_name,
length);
|  |
~~
|  | |
|  | (2) calling ‘namelist_match’
from ‘name_scan’
|
+--> ‘namelist_match’: events 3-5
   |
   |12316 | namelist_match (char const *file_name, size_t
length)
   |  | ^~
   |  | |
   |  | (3) entry to ‘namelist_match’
   |..
   |12320 |   for (p = namelist; p; p = p->next)
   |  |  ~
   |  |  |
   |  |  (4) following ‘true’ branch
(when ‘p’ is non-NULL)...
   |12321 | {
   |12322 |   if (p->name[0]
   |  |   ~~~
   |  ||
   |  |(5) ...to here
   |
<--+
|
  ‘name_scan’: events 6-11
|
|13039 |   struct name *cursor = namelist_match (file_name,
length);
|  |
^~
|  | |
|  | (6) returning to ‘name_scan’
from ‘namelist_match’
|13040 |   if (cursor)
|  |  ~   
|  |  |
|  |  (7) following ‘false’ branch (when ‘cursor’ is
NULL)...
|..
|13048 |   if (same_order_option && namelist &&
namelist->found_count)
|  |  ~~  
|  |  ||
|  |  |(8) ...to here
|  |  (9) following ‘true’ branch...
|13049 |  {
|13050 |name_gather ();
|  |~~
|  ||
|  |(10) ...to here
|  |(11) calling ‘name_gather’ from ‘name_scan’
|
+--> ‘name_gather’: events 12-13
   |
   |12170 | name_gather (void)
   |  | ^~~
   |  | |
   |  | (12) entry to ‘name_gather’
   |..
   |12179 |   if (same_order_option)
   |  |  ~
   |  |  |
   |  |  (13) following ‘true’ branch...
   |
 ‘name_gather’: event 14
   |
   |cc1:
   | (14): ...to here
   |
 ‘name_gather’: event 15
   |
   |12183 |   while ((ep = 

[Bug middle-end/106427] New: -Wuse-after-free=3 false alarm about int (not pointer) variable

2022-07-24 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106427

Bug ID: 106427
   Summary: -Wuse-after-free=3 false alarm about int (not pointer)
variable
   Product: gcc
   Version: 12.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: middle-end
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 53341
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53341=edit
Compile with '-O2 -S -Wuse-after-free=3' to demonstrate the bug

I ran into this problem when building GNU Tar. Compile the attached program u.i
with "gcc -O2 -S -Wuse-after-free=3 u.i", using GCC 12.1.1 20220507 (Red Hat
12.1.1-1) on x86-64. The output (shown below) is a false alarm, because the
variable 'stop' is of type 'int', and is not a pointer. Apparently GCC is
confused by the assignment statement 'stop = p == end;' and thinks that
accessing 'stop' later implies accessing a freed pointer.

u.i: In function ‘coalesce_segment’:
u.i:6486:18: warning: pointer ‘p’ used after ‘free’ [-Wuse-after-free]
 6486 |   for (stop = 0; !stop;)
  |  ^
In function ‘wsnode_free’,
inlined from ‘coalesce_segment’ at u.i:6499:4:
u.i:6316:3: note: call to ‘free’ here
 6316 |   free (p);
  |   ^~~~

[Bug analyzer/105961] -Wanalyzer-use-of-uninitialized-value false positive after "= {0}"

2022-06-13 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105961

--- Comment #2 from eggert at cs dot ucla.edu ---
Created attachment 53131
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53131=edit
reproducer for the bug (compressed with xz)

The uncompressed t.i was too large for bugzilla, so here's the same file,
compressed with xz.

[Bug analyzer/105961] New: -Wanalyzer-use-of-uninitialized-value false positive after "= {0}"

2022-06-13 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105961

Bug ID: 105961
   Summary: -Wanalyzer-use-of-uninitialized-value false positive
after "= {0}"
   Product: gcc
   Version: 12.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

This is gcc (GCC) 12.1.1 20220507 (Red Hat 12.1.1-1) on x86-64. I do not
observe the bug with gcc-12 (Ubuntu 12-20220319-1ubuntu1) 12.0.1 20220319
(experimental) [master r12-7719-g8ca61ad148f] on x86-64.

Compile the attached program (derived from bleeding-edge Emacs) with:

gcc -O2 -S -fanalyzer t.i

GCC complains:

In function ‘dump_mmap_release’,
inlined from ‘pdumper_load’ at t.i:50527:5:
t.i:49512:10: warning: use of uninitialized value ‘sections[i].release’
[CWE-457] [-Wanalyzer-use-of-uninitialized-value]
49512 |   if (map->release)
  |   ~~~^
  ‘pdumper_load’: events 1-9
|
|50318 | pdumper_load (const char *dump_filename, char *argv0)
|  | ^~~~
|  | |
|  | (1) entry to ‘pdumper_load’
|..
|50331 |   struct dump_memory_map sections[NUMBER_DUMP_SECTIONS] = { 0 };
|  |  
|  |  |
|  |  (2) region created on stack here
|..


The region is obviously initialized, via the "= { 0 }" at the end. The
following change pacifies GCC, but should not be necessary.

--- t.i 2022-06-13 13:06:59.0 -0700
+++ u.i 2022-06-13 13:09:18.0 -0700
@@ -50329,6 +50329,7 @@
   struct dump_header header_buf = { 0 };
   struct dump_header *header = _buf;
   struct dump_memory_map sections[NUMBER_DUMP_SECTIONS] = { 0 };
+  memset (sections, 0, sizeof sections);

   const struct timespec start_time = current_timespec ();
   char *dump_filename_copy;

[Bug analyzer/105784] New: -Wanalyzer-use-of-uninitialized-value false positive on partly initialized array

2022-05-30 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105784

Bug ID: 105784
   Summary: -Wanalyzer-use-of-uninitialized-value false positive
on partly initialized array
   Product: gcc
   Version: 12.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 53056
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53056=edit
False positive with -O2 -fanalyzer -Wanalyzer-use-of-uninitialized-value

I found this bug with GCC 12.1.1 20220507 (Red Hat 12.1.1-1) on x86-64. Compile
the attached program x.i (which is simplified from GNU Emacs master) with:

gcc -O2 -fanalyzer -Wanalyzer-use-of-uninitialized-value -S x.i

The GCC output is as follows. This is a false positive, since *src must point
into the initialized part of the array.

x.i: In function ‘ccl_driver’:
x.i:13:11: warning: use of uninitialized value ‘*src’ [CWE-457]
[-Wanalyzer-use-of-uninitialized-value]
   13 | i = *src++;
  | ~~^~~~
  ‘Fccl_execute_on_string’: events 1-5
|
|   19 | Fccl_execute_on_string (char *str, long str_bytes)
|  | ^~
|  | |
|  | (1) entry to ‘Fccl_execute_on_string’
|..
|   25 |   int source[1024];
|  |   ~~
|  |   |
|  |   (2) region created on stack here
|..
|   28 |   while (src_size < 1024 && p < endp)
|  |  ~~~
|  |  |
|  |  (3) following ‘false’ branch...
|..
|   31 |   ccl_driver (source, src_size);
|  |   ~
|  |   |
|  |   (4) ...to here
|  |   (5) calling ‘ccl_driver’ from ‘Fccl_execute_on_string’
|
+--> ‘ccl_driver’: events 6-11
   |
   |5 | ccl_driver (int *source, int src_size)
   |  | ^~
   |  | |
   |  | (6) entry to ‘ccl_driver’
   |..
   |   10 |   while (!quit_flag)
   |  |  ~~
   |  |  |
   |  |  (7) following ‘false’ branch...
   |   11 | {
   |   12 |   if (src < src_end)
   |  |  ~
   |  |  |
   |  |  (8) ...to here
   |  |  (9) following ‘true’ branch (when ‘src <
src_end’)...
   |   13 | i = *src++;
   |  | ~~
   |  |   | |
   |  |   | (10) ...to here
   |  |   (11) use of uninitialized value ‘*src’ here
   |

[Bug analyzer/105755] New: -Wanalyzer-null-dereference regression compiling Emacs

2022-05-27 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105755

Bug ID: 105755
   Summary: -Wanalyzer-null-dereference regression compiling Emacs
   Product: gcc
   Version: 12.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 53047
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53047=edit
compile with 'gcc -fanalyzer -O2 -S' to see the false positive

GCC 12.1.1 20220507 (Red Hat 12.1.1-1) on x86-64 has a false positive compiling
the attached program w.i, which is a stripped-down version of GNU Emacs master.
Compile it this way:

gcc -fanalyzer -O2 -S w.i

and it generates the following incorrect output. GCC 11.2 compiles the code
cleanly so this is a regression.

In function ‘PSEUDOVECTORP’,
inlined from ‘SUB_CHAR_TABLE_P’ at w.i:154:10,
inlined from ‘CHAR_TABLE_REF_ASCII’ at w.i:169:28:
w.i:53:56: warning: dereference of NULL ‘*tbl.ascii’ [CWE-476]
[-Wanalyzer-null-dereference]
   52 |   && union vectorlike_header *)
  | 
   53 | ((char *) XLP ((a)) - Lisp_Vectorlike))->size
  | ~~~^~
  ‘word_boundary_p’: events 1-2
|
|  187 | word_boundary_p (Lisp_Object char_script_table, int c1, int c2)
|  | ^~~
|  | |
|  | (1) entry to ‘word_boundary_p’
|  188 | {
|  189 |   return EQ (CHAR_TABLE_REF (char_script_table, c1),
|  |  ~~~
|  |  |
|  |  (2) calling ‘CHAR_TABLE_REF’ from ‘word_boundary_p’
|  190 |  CHAR_TABLE_REF (char_script_table, c2));
|  |  ~~~
|
+--> ‘CHAR_TABLE_REF’: events 3-6
   |
   |  179 | CHAR_TABLE_REF (Lisp_Object ct, int idx)
   |  | ^~
   |  | |
   |  | (3) entry to ‘CHAR_TABLE_REF’
   |  180 | {
   |  181 |   return (ASCII_CHAR_P (idx)
   |  |  ~~~
   |  182 |   ? CHAR_TABLE_REF_ASCII (ct, idx)
   |  |   
   |  | |
   |  | (5) ...to here
   |  | (6) calling ‘CHAR_TABLE_REF_ASCII’ from
‘CHAR_TABLE_REF’
   |  183 |   : char_table_ref (ct, idx));
   |  |   ~~~
   |  |   |
   |  |   (4) following ‘true’ branch...
   |
   +--> ‘CHAR_TABLE_REF_ASCII’: events 7-15
  |
  |  164 | CHAR_TABLE_REF_ASCII (Lisp_Object ct, ptrdiff_t idx)
  |  | ^~~~
  |  | |
  |  | (7) entry to ‘CHAR_TABLE_REF_ASCII’
  |..
  |  169 |   Lisp_Object val = (! SUB_CHAR_TABLE_P
(tbl->ascii) ? tbl->ascii
  |  |
~
  |  170 |  : XSUB_CHAR_TABLE
(tbl->ascii)->contents[idx]);
  |  | 
~~
  |  |  |
  |  |  (8) following ‘false’
branch...
  |  171 |   if (NILP (val))
  |  |  ~
  |  |  |
  |  |  (9) ...to here
  |  |  (10) following ‘true’ branch...
  |  172 | val = tbl->defalt;
  |  | ~
  |  | |
  |  | (11) ...to here
  |  173 |   if (!NILP (val) || NILP (tbl->parent))
  |  |  ~~
  |  |  ||  |
  |  |  ||  (13) ...to here
  |  |  |(14) following ‘true’
branch...
  |  |  (12) following ‘false’ branch (when ‘val’
is NULL)...
  |  174 | return val;
  |  |~~~
  |  ||
  |  |(15) ...to here
  |
   <--+
   |
 ‘CHAR_TABLE_REF’: event 16
   |
   |  182 |   ? CHAR_TABLE_REF_ASCII (ct, idx)
   |  | ^~
  

[Bug c/44677] Warn for variables incremented but not used

2022-04-08 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=44677

eggert at cs dot ucla.edu changed:

   What|Removed |Added

 CC||eggert at cs dot ucla.edu

--- Comment #13 from eggert at cs dot ucla.edu ---
I ran into this issue today on Emacs master, with both += and |=. Clang
correctly diagnosed unused local variables, but GCC did not.

It would be nice if GCC could do at least as well as Clang does.

Here are references to patches I installed into Emacs to fix these issues that
Clang found but GCC did not:

https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=d9bffa1f3b121085fd8f954eb9446a4a5241c062
https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=68bc1446855c86b96d5bc22f819e63358ab250ac

[Bug sanitizer/104262] -fsanitize=address false alarm with aligned_alloc

2022-01-27 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104262

--- Comment #4 from eggert at cs dot ucla.edu ---
Thanks for looking into the problem. DR#460 says that the C2x committee adopted
wording based on N2072, which which made the point that non-integral multiples
of alignment are useful - for the same reasons that prompted my bug report.
This reflects longstanding wording in the C standard that, for example, 'malloc
(sizeof (double) + 1)' yields a pointer suitably aligned for 'double'. So this
is indeed a bug in gcc's -fsanitize=address option.

> changes against the sanitizer libs need to go against the
> compiler-rt upstream and only then can be cherry-picked from there.
As I understand it, GCC has local patches so that its libsanitizer differs from
upstream, and this patch could be added to that difference set if necessary.
However, you're right that it's better to have upstream fix it, so that the fix
is everywhere. I filed a bug report upstream here:

https://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20220124/1001910.html

and I hope they act on it.

[Bug sanitizer/104262] New: -fsanitize=address false alarm with aligned_alloc

2022-01-27 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104262

Bug ID: 104262
   Summary: -fsanitize=address false alarm with aligned_alloc
   Product: gcc
   Version: 11.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: sanitizer
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at 
gcc dot gnu.org
  Target Milestone: ---

Created attachment 52304
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52304=edit
Patch for -fsanitize=address aligned_alloc bug

The following program (adapted from an experimental version of GNU Coreutils)
strictly conforms to C11 and shows a useful pattern of allocating a struct with
a flexible array member:

  #include 
  #include 
  #include 

  struct namelist
  {
struct namelist *next;
char name[];
  } *p;

  int
  main (void)
  {
p = aligned_alloc (alignof (struct namelist),
   offsetof (struct namelist, name) + 3);
if (!p)
  return 1;
p->next = 0;
p->name[0] = 'a';
p->name[1] = 'b';
p->name[2] = 0;
return 0;
  }


However, when I compile it with gcc 11.2.1 20211203 (Red Hat 11.2.1-7) using
the command 'gcc -fsanitize=address' it crashes, with the following diagnostic:

=
==6049==ERROR: AddressSanitizer: invalid alignment requested in aligned_alloc:
8, alignment must be a power of two and the requested size 0xb must be a
multiple of alignment (thread T0)
#0 0x7fbf0f10b32f in aligned_alloc (/lib64/libasan.so.6+0xaf32f)
#1 0x401198 in main (/home/eggert/junk/a.out+0x401198)
#2 0x7fbf0ee7f55f in __libc_start_call_main
../sysdeps/nptl/libc_start_call_main.h:58

==6049==HINT: if you don't care about these errors you may set
allocator_may_return_null=1
SUMMARY: AddressSanitizer: invalid-aligned-alloc-alignment
(/lib64/libasan.so.6+0xaf32f) in aligned_alloc
==6049==ABORTING


Proposed (untested) patch attached. Unfortunately I'm not plugged into the
relationship between GCC and Clang compiler-rt, so I don't know how you manage
patches to this part of the GCC source code or do testcases or cleanups etc.
However, please install something like this patch into GCC's copy of the
AddressSanitizer library. Thanks.

[Bug tree-optimization/104060] New: -Wmaybe-uninitialized false alarm on address of local array

2022-01-16 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104060

Bug ID: 104060
   Summary: -Wmaybe-uninitialized false alarm on address of local
array
   Product: gcc
   Version: 11.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 52209
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52209=edit
compile with 'gcc -Wuninitialized' to see the false alarm

I ran into this problem when compiling an experimental version of GNU coreutils
with gcc 11.2.1 20211203 (Red Hat 11.2.1-7), x86-64.

This is a regression, since gcc 8.5.0 20210514 (Red Hat 8.5.0-4) does not have
the problem.

Compile the attached program with 'gcc -Wuninitialized -S
false-alarm-uninit.c'. There should be no output, but GCC outputs the
following. The diagnostic is incorrect, as bin_buffer_unaligned is an array
that is never read from or written to. Apparently GCC is getting confused
because the array's address is taken (but that address is never dereferenced).

false-alarm-uninit.c: In function ‘digest_check’:
false-alarm-uninit.c:13:31: warning: ‘bin_buffer_unaligned’ may be used
uninitialized [-Wmaybe-uninitialized]
   13 |   unsigned char *bin_buffer = ptr_align (bin_buffer_unaligned, 1024);
  |   ^~
false-alarm-uninit.c:2:1: note: by argument 1 of type ‘const void *’ to
‘ptr_align’ declared here
2 | ptr_align (void const *ptr, unsigned long alignment)
  | ^
false-alarm-uninit.c:12:17: note: ‘bin_buffer_unaligned’ declared here
   12 |   unsigned char bin_buffer_unaligned[1];
  | ^~~~

[Bug tree-optimization/101912] -Wmaybe-uninitialized false alarm in tzdb localtime.c

2021-11-30 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101912

--- Comment #4 from eggert at cs dot ucla.edu ---
(In reply to Aldy Hernandez from comment #3)
> >   && !(leapcnt == 0
> >|| (prevcorr < corr
> >? corr == prevcorr + 1
> >: (corr == prevcorr
> >   || corr == prevcorr - 1)
> > 
> 
> I guess the question is whether language rules allow us to read prevcorr
> when leapcnt== 0?

The C language rules do not allow that. When leapcnt is zero, behavior must be
as if the prevcorr expression is not evaluated.

Although the compiler can generate machine code that evaluates prevcorr at the
machine level (so long as the observable behavior is the same, which is the
case as prevcorr is not volatile and no untoward behavior can result from
evaluating the prevcorr expression), it's incorrect if the compiler warns the
programmer that prevcorr is used uninitialized.

[Bug analyzer/101713] -Wanalyzer-malloc-leak false positive with GNU coreutils hash table code

2021-11-17 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101713

--- Comment #2 from eggert at cs dot ucla.edu ---
(In reply to David Malcolm from comment #1)

> Am I right in thinking that there's a cast somewhere inside the hash table
> code that at some point casts away the const from the pointer and frees it?

Yes there's a cast to void *, but no it doesn't free the storage. Instead, the
caller later is supposed to take ownership of the storage if it removes the
item from the hashtable, e.g., the caller can later do this:

   void *entry = hash_remove (pattern);
   free (entry);

where ENTRY will be the same pointer as STR in the sample code I gave earlier.
This means there's no leak in addpat per se.

[Bug analyzer/102692] -Wanalyzer-null-dereference false alarm with (!p || q || !p->next)

2021-10-11 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102692

--- Comment #1 from eggert at cs dot ucla.edu ---
Sorry, forgot to mention the incorrect GCC output. Here it is:
-
analyzer-null-dereference-simple.i: In function ‘fix_overlays_before’:
analyzer-null-dereference-simple.i:79:35: warning: dereference of NULL ‘tail’
[CWE-476] [-Wanalyzer-null-dereference]
   79 |   if (!tail || end < prev || !tail->next)
  |   ^~
  ‘fix_overlays_before’: events 1-5
|
|   72 |   while (tail
|  |  
|   73 |  && (tem = make_lisp_ptr (tail, 5),
|  |  ^~
|  |  |
|  |  (1) following ‘false’ branch (when ‘tail’ is NULL)...
|   74 |  (end = marker_position (XOVERLAY (tem)->end)) >=
pos))
|  |  ~
|..
|   79 |   if (!tail || end < prev || !tail->next)
|  |  ~~   ~~
|  |  ||   |
|  |  ||   (4) ...to here
|  |  |(2) ...to here  (5) dereference of NULL ‘tail’
|  |  (3) following ‘false’ branch...
|

[Bug analyzer/102671] -Wanalyzer-null-dereference false positive when compiling GNU Emacs

2021-10-11 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102671

--- Comment #2 from eggert at cs dot ucla.edu ---
I have filed what may be a related bug as GCC bug 102692.

[Bug analyzer/102692] New: -Wanalyzer-null-dereference false alarm with (!p || q || !p->next)

2021-10-11 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102692

Bug ID: 102692
   Summary: -Wanalyzer-null-dereference false alarm with (!p || q
|| !p->next)
   Product: gcc
   Version: 11.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 51588
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51588=edit
compile on x86-64 with "gcc -fanalyzer -O2 -S
analyzer-null-dereference-simple.i"

I ran into this problem when compiling GNU Emacs with gcc 11.2.1 20210728 (Red
Hat 11.2.1-1) on x86-64. Compile the attached simplified version with:

gcc -fanalyzer -O2 -S analyzer-null-dereference-simple.i

and the output will be as at the end of this description. This output is bogus
since it complains that 'tail' might be null in (!tail || end < prev ||
!tail->next) which means that tail->next might dereference a null pointer. But
the tail->next expression is obviously unreachable if 'tail' is null.

Although this bug might be related to GCC bug 102671, I'm filing it separately
as it has a different feel.

[Bug analyzer/102671] -Wanalyzer-null-dereference false positive when compiling GNU Emacs

2021-10-10 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102671

--- Comment #1 from eggert at cs dot ucla.edu ---
Created attachment 51582
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51582=edit
2nd test case illustrating the bug

I'm attaching a second test case, also taken from GNU Emacs, illustrating the
same bug or at least something similar. Compile it on the same platform with:

gcc -fanalyzer -O2 -S analyzer-null-dereference-2.i

and the output will be the following. The false alarm is incorrect here, too. I
plan to modify Emacs to disable the warnings in the two source-code files that
are generating these false alarms.

analyzer-null-dereference-2.i: In function 'Ftime_convert':
analyzer-null-dereference-2.i:36:13: warning: dereference of NULL 'time'
[CWE-476] [-Wanalyzer-null-dereference]
   36 |   return ((a->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
  |~^~
  'Ftime_convert': events 1-4
|
|   72 | Ftime_convert (struct lisp *time)
|  | ^
|  | |
|  | (1) entry to 'Ftime_convert'
|   73 | {
|   74 |   decode_time_components (time ? XCDR (time) : time);
|  |   ~~
|  |   |
|  |   (2) following 'false' branch (when 'time' is NULL)...
|  |   (3) ...to here
|  |   (4) calling 'decode_time_components' from 'Ftime_convert'
|
+--> 'decode_time_components': events 5-7
   |
   |   43 |   if (! VECTORLIKEP (a))
   |  |  ~
   |  |  |
   |  |  (6) following 'true' branch...
   |..
   |   65 | decode_time_components (struct lisp *low)
   |  | ^~
   |  | |
   |  | (5) entry to 'decode_time_components'
   |..
   |   69 | }
   |  | ~
   |  | |
   |  | (7) ...to here
   |
<--+
|
  'Ftime_convert': events 8-11
|
|   36 |   return ((a->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
|  |~~~
|  | |
|  | (10) ...to here
|  | (11) dereference of NULL 'time'
|..
|   43 |   if (! VECTORLIKEP (a))
|  |  ~
|  |  |
|  |  (9) following 'false' branch...
|..
|   74 |   decode_time_components (time ? XCDR (time) : time);
|  |   ^~
|  |   |
|  |   (8) returning to 'Ftime_convert' from 'decode_time_components'
|

[Bug analyzer/102671] New: -Wanalyzer-null-dereference false positive when compiling GNU Emacs

2021-10-09 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102671

Bug ID: 102671
   Summary: -Wanalyzer-null-dereference false positive when
compiling GNU Emacs
   Product: gcc
   Version: 11.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 51577
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51577=edit
Compile with -fanalyzer -O2 -S on x86-64 to illustrate the bug

I ran into this problem when compiling GNU Emacs with gcc (GCC) 11.2.1 20210728
(Red Hat 11.2.1-1) on x86-64. Compile with:

gcc -fanalyzer -O2 -S analyzer-null-defererence-bug.i

and the output will be the diagnostic at the end of this bug report, which is a
false alarm. Removing the unrelated function wset_buffer suppresses the false
alarm, which suggests that the analysis of wset_buffer is somehow messing up
the analysis of delete_all_child_windows.

I do not observe this problem when compiling with gcc (Ubuntu 10.3.0-1ubuntu1)
10.3.0.


analyzer-null-defererence-bug.i: In function 'PSEUDOVECTORP.part.0':
analyzer-null-defererence-bug.i:23:13: warning: dereference of NULL 'a'
[CWE-476] [-Wanalyzer-null-dereference]
   23 |   return ((a->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
  |~^~
  'delete_all_child_windows': events 1-4
|
|  155 | delete_all_child_windows (struct lisp *window)
|  | ^~~~
|  | |
|  | (1) entry to 'delete_all_child_windows'
|..
|  158 |   if (!NILP (w->next))
|  |  ~
|  |  |
|  |  (2) following 'true' branch...
|  159 | delete_all_child_windows (w->next);
|  | ~~
|  | |
|  | (3) ...to here
|  | (4) calling 'delete_all_child_windows' from
'delete_all_child_windows'
|
+--> 'delete_all_child_windows': events 5-8
   |
   |  155 | delete_all_child_windows (struct lisp *window)
   |  | ^~~~
   |  | |
   |  | (5) entry to 'delete_all_child_windows'
   |..
   |  158 |   if (!NILP (w->next))
   |  |  ~
   |  |  |
   |  |  (6) following 'true' branch...
   |  159 | delete_all_child_windows (w->next);
   |  | ~~
   |  | |
   |  | (7) ...to here
   |  | (8) calling 'delete_all_child_windows' from
'delete_all_child_windows'
   |
   +--> 'delete_all_child_windows': events 9-14
  |
  |  155 | delete_all_child_windows (struct lisp *window)
  |  | ^~~~
  |  | |
  |  | (9) entry to 'delete_all_child_windows'
  |..
  |  158 |   if (!NILP (w->next))
  |  |  ~
  |  |  |
  |  |  (10) following 'false' branch...
  |  159 | delete_all_child_windows (w->next);
  |  160 |   if (WINDOWP (w->contents))
  |  |  ~~
  |  |  ||
  |  |  |(11) ...to here
  |  |  (12) following 'true' branch...
  |  161 | {
  |  162 |   delete_all_child_windows (w->contents);
  |  |   ~~
  |  |   |
  |  |   (13) ...to here
  |  |   (14) calling 'delete_all_child_windows' from
'delete_all_child_windows'
  |
  +--> 'delete_all_child_windows': events 15-19
 |
 |  155 | delete_all_child_windows (struct lisp
*window)
 |  | ^~~~
 |  | |
 |  | (15) entry to 'delete_all_child_windows'
 |..
 |  158 |   if (!NILP (w->next))
 |  |  ~
 |  |  |
 |  |  (16) following 'false' branch...
 |  159 | delete_all_child_windows (w->next);
 |  160 |   if (WINDOWP (w->contents))
 |  |  ~~
 |  |  ||
 |  |  |(17) ...to here
 |  |  (18) following 'false' branch...
 |..
 |  

[Bug c/102578] false alarm on noreturn via static function

2021-10-03 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102578

--- Comment #2 from eggert at cs dot ucla.edu ---
Created attachment 51539
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51539=edit
false alarm with 'gcc -O2 -S -Wreturn-type'

Attached is the third and final example I got from Coreutils today. When I
compile it it with 'gcc -O2 -S -Wreturn-type' I get the following false alarm:

noreturn2.c: In function ‘find_int’:
noreturn2.c:15:1: warning: control reaches end of non-void function
[-Wreturn-type]
   15 | }
  | ^

[Bug c/102578] false alarm on noreturn via static function

2021-10-03 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102578

--- Comment #1 from eggert at cs dot ucla.edu ---
Created attachment 51538
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51538=edit
false alarm with 'gcc -O2 -S -Wimplicit-fallthrough=5'

I'm adding another example of the problem, taken from a different part of GNU
Coreutils. Compile this with 'gcc -O2 -S -Wimplicit-fallthrough=5' to see the
following false alarm:

noreturn1.c: In function 'check':
noreturn1.c:16:7: warning: this statement may fall through
[-Wimplicit-fallthrough=]
   16 |   async_safe_die ();
  |   ^
noreturn1.c:18:5: note: here
   18 | default:
  | ^~~

[Bug c/102578] New: false alarm on noreturn via static function

2021-10-03 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102578

Bug ID: 102578
   Summary: false alarm on noreturn via static function
   Product: gcc
   Version: 11.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 51537
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51537=edit
False alarm with 'gcc -O2 -S'

I ran into this problem when compiling GNU Coreutils and simplified it to the
attached testcase noreturn.c. The shell command 'gcc -O2 -S noreturn.c' outputs
this:

noreturn.c: In function 'xalloc_die':
noreturn.c:13:1: warning: 'noreturn' function does return
   13 | }
  | ^

This is a false alarm because xalloc_die calls the static function
cleanup_fatal which calls 'exit'.

Although I can pacify GCC by declaring cleanup_fatal to be _Noreturn, I
shouldn't have to complicate the source code for a static function when GCC can
(and already does) figure this stuff out automatically.

This is GCC 11.2.1 20210728 (Red Hat 11.2.1-1) x86-64.

[Bug target/99591] Improving __builtin_add_overflow performance on x86-64

2021-09-01 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99591

eggert at cs dot ucla.edu changed:

   What|Removed |Added

 CC||eggert at cs dot ucla.edu

--- Comment #3 from eggert at cs dot ucla.edu ---
(In reply to Andrew Pinski from comment #2)
> (In reply to Andrew Pinski from comment #1)
> > Looks fixed for GCC 11+.
It doesn't appear to be fixed in GCC 11.2.1 20210728 (Red Hat 11.2.1-1). For
signed1_overflow I get the same suboptimal machine code described in comment
#0. For signed2_overflow I get:

signed2_overflow:
movswl  %si, %esi
movswl  %di, %edi
addw%si, %di
seto%al
ret

Although this is better than the machine code described in comment #0 it's
still clearly suboptimal, as the two movswl instructions are redundant and both
can be omitted.

[Bug middle-end/101913] -Wstrict-overflow -O3 false alarm on tzdb localtime.c

2021-08-14 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101913

--- Comment #3 from eggert at cs dot ucla.edu ---
(In reply to Andrew Pinski from comment #1)
> >-1L << 63 is LONG_MIN
> No it is undefined and has an overflow bit on it.
> You want (long)(-1UL << 63) for it be correct.
> But the warning is still there.

I updated the attachment to avoid any undefined behavior, by replacing -1L<<63
with -1-9223372036854775807L. As you say, the bug is still there.

> I thought -fsanitize=undefined enabled -fwrapv too ...

It doesn't. (Perhaps you meant -ftrapv?)

[Bug middle-end/101913] -Wstrict-overflow -O3 false alarm on tzdb localtime.c

2021-08-14 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101913

eggert at cs dot ucla.edu changed:

   What|Removed |Added

  Attachment #51304|0   |1
is obsolete||

--- Comment #2 from eggert at cs dot ucla.edu ---
Created attachment 51305
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51305=edit
-Wstrict-overflow -O3 false alarm example (v2)

This updates the example by replacing -1L<<63 with -1-9223372036854775807L, to
avoid any undefined behavior in evaluating that constant expression.

[Bug c/101913] New: -Wstrict-overflow -O3 false alarm on tzdb localtime.c

2021-08-14 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101913

Bug ID: 101913
   Summary: -Wstrict-overflow -O3 false alarm on tzdb localtime.c
   Product: gcc
   Version: 11.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 51304
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51304=edit
-Wstrict-overflow -O3 false alarms

I ran into this problem when compiling tzdb localtime.c with gcc (GCC) 11.2.1
20210728 (Red Hat 11.2.1-1) on x86-64. To reproduce, compile the attached
program v.i with:

gcc -Wstrict-overflow -O3 -fsanitize=undefined -S v.i

The output is:

v.i: In function ‘tzloadbody’:
v.i:22:1: warning: assuming signed overflow does not occur when simplifying
con\
ditional to constant [-Wstrict-overflow]
   22 | tzloadbody (struct state *sp, int leapcnt0, int timecnt0)
  | ^~
v.i:29:25: warning: assuming signed overflow does not occur when simplifying
co\
nditional to constant [-Wstrict-overflow]
   29 |   sp->types[i] = at <= 0xu;
  |  ~~~^~

1. These diagnostics make no sense, since none of the underlined code involves
any operations that can overflow.

2. I looked through the code carefully, and none of the arithmetic operations
can possibly overflow. In (result << 8), 'result' is at most 2**32 - 1 and this
fits comfortably into 'long'. -1L << 63 is LONG_MIN. "++i" is executed only
when i is less than some other int. timecnt++ and leapcnt++ are executed at
most INT_MAX times. prevcorr + 1 is evaluated only when prevcorr < corr, and
prevcorr - 1 is evaluated only when prevcorr > corr.

3. The diagnostics vanish if you change MYSTERY from 5 to 4 in the first line.
This suggests that GCC is somehow getting confused about whether 'long' has 8
bytes (which it does on this platform) or 4 bytes.

[Bug tree-optimization/101912] New: -Wmaybe-uninitialized false alarm in tzdb localtime.c

2021-08-14 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101912

Bug ID: 101912
   Summary: -Wmaybe-uninitialized false alarm in tzdb localtime.c
   Product: gcc
   Version: 11.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 51303
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51303=edit
-Wuninitialized false alarm

This is a simplified version of a problem I found while compiling tzdb's
localtime.c with gcc (GCC) 11.2.1 20210728 (Red Hat 11.2.1-1) on x86-64.
Compile the attached program w.i with:

gcc -Wmaybe-uninitialized -O2 -S w.i

The output is:

w.i: In function ‘tzloadbody’:
w.i:17:27: warning: ‘prevcorr’ may be used uninitialized in this function
[-Wmaybe-uninitialized]
   16 |: (corr == prevcorr
  |  ~
   17 |   || corr == prevcorr - 1)
  |   ^~~~


This is a false alarm, since the underlined code is executed only when leapcnt
is nonzero, and leapcnt is set to a nonzero value only after prevcorr is
initialized.

[Bug analyzer/101837] New: ICE with -O3 -fsanitize=undefined -fanalyzer

2021-08-09 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101837

Bug ID: 101837
   Summary: ICE with -O3 -fsanitize=undefined -fanalyzer
   Product: gcc
   Version: 11.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 51283
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51283=edit
Compile with "-O3 -fsanitize=undefined -fanalyzer -S" to reproduce the ICE

While building the time zone code I got an internal compiler error. This is
with cc (GCC) 11.2.1 20210728 (Red Hat 11.2.1-1) on Fedora 34 x86-64. Compile
the attached program u.c with:

cc -O3 -fsanitize=undefined -fanalyzer -S u.i

I briefly attempted to simplify u.c but the simplifications made the compiler
error go away.

[Bug middle-end/101829] New: problems with inline + __attribute__ ((malloc (deallocator)))

2021-08-09 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101829

Bug ID: 101829
   Summary: problems with inline + __attribute__ ((malloc
(deallocator)))
   Product: gcc
   Version: 11.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: middle-end
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

We've recently started using __attribute__ ((malloc (deallocator))) with Gnulib
and ran into the problem that the GCC documentation in doc/extend.texi says
this:

"Since inlining one of the associated functions but not the other could result
in apparent mismatches, this form of attribute @code{malloc} is not accepted on
inline functions."

This has caused problems for us, as many of our functions are naturally inline
and are allocators or deallocators. As Bruno Haible wrote in
:

"The GCC documentation [1] says that the attribute 'malloc (deallocator, 1)'
does not work on inline functions. IMO, this restriction is not tenable in the
long run (because the semantics of a function don't depend on whether it is
inline or not, and because in C++ the majority of all functions is inline)."


We have resorted to merely adding comments to the functions in question. It
would be better if we could add the attributes, and then GCC can ignore them
when applied to inline functions. Alternatively, GCC could refuse to inline
such functions. Either would be preferable to the current situation.

[Bug tree-optimization/101770] New: -Wmaybe-uninitialized false alarm with only locals in GNU diffutils

2021-08-03 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101770

Bug ID: 101770
   Summary: -Wmaybe-uninitialized false alarm with only locals in
GNU diffutils
   Product: gcc
   Version: 11.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 51256
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51256=edit
False alarm with gcc -O2 -Wmaybe-uninitialized and only locals

I found this problem while compiling sdiff.c from GNU diffutils. The attached
is is a simplified version. It appears to be distinct from GCC bug 101768 since
it involves only local variables.

Compile it this way:

gcc -O2 -Wmaybe-uninitialized -S w.i

The output is:

w.i: In function ‘edit’:
w.i:50:18: warning: ‘cmd1’ may be used uninitialized in this function
[-Wmaybe-uninitialized]
   50 |   return !cmd1;
  |  ^

This is a false alarm, because line 50 can be reached only if cmd0=='e', and if
cmd0=='e' then  the previous switch statement (inside the while loop - line 27)
guarantees that cmd1 has been initialized.

I briefly tried to simplify the example further, but failed. For example, if I
remove line 16 ("case '2':") the false alarm goes away.

This is with gcc (GCC) 11.2.1 20210728 (Red Hat 11.2.1-1) on x86-64.

[Bug tree-optimization/101768] New: -Wmaybe-uninitialized false alarm with 'switch' instead of 'if'

2021-08-03 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101768

Bug ID: 101768
   Summary: -Wmaybe-uninitialized false alarm with 'switch'
instead of 'if'
   Product: gcc
   Version: 11.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 51255
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51255=edit
False alarm with gcc -O2 -Wmaybe-uninitialized

The attached program is a greatly-simplified version of GNU diffutils' cmp
program. Compiling it this way:

gcc -O2 -Wmaybe-uninitialized -S u.i

causes gcc to emit the bogus diagnostic:

u.i: In function ‘cmp’:
u.i:21:11: warning: ‘offset_width’ may be used uninitialized in this function
[-Wmaybe-uninitialized]
   21 |   foo (offset_width);
  |   ^~

I tried simplifying it further (removing the 'main' function, turning the
switch into an if, etc.) but the warning went away with the further
simplifications.

This is with gcc (GCC) 11.2.1 20210728 (Red Hat 11.2.1-1) on x86-64.

[Bug analyzer/101713] New: -Wanalyzer-malloc-leak false positive with GNU coreutils hash table code

2021-08-01 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101713

Bug ID: 101713
   Summary: -Wanalyzer-malloc-leak false positive with GNU
coreutils hash table code
   Product: gcc
   Version: 11.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Because of GCC bug 94458 we've been disabling -Wanalyzer-malloc-leak when
compiling Gnulib-based code such as GNU coreutils. Since GCC bug 94458 is fixed
I thought I'd try enabling that warning. I simplified the first false positive
I ran into (in gnulib/lib/exclude.c) to the following:

void free (void *);
char *xstrdup (char const *)
  __attribute__ ((__malloc__)) __attribute__ ((__malloc__ (free, 1)))
  __attribute__ ((__returns_nonnull__));
void *hash_insert (void const *entry);

void
addpat (char *pattern)
{
  char *str = xstrdup (pattern);
  hash_insert (str);
}

For this example, the command 'gcc -fanalyzer -Wanalyzer-too-complex -O2 -S
t1.i' outputs the following diagnostic, which is a false alarm because 'str'
has been put into a hash table and has not leaked. Omitting the 'const' from
the declaration of the 'entry' formal parameter makes the false alarm go away,
but we shouldn't have to omit the 'const'. For now, I think we'll continue to
disable -Wanalyzer-too-complex in Gnulib-derived code.

t1.i: In function ‘addpat’:
t1.i:12:1: warning: leak of ‘str’ [CWE-401] [-Wanalyzer-malloc-leak]
   12 | }
  | ^
  ‘addpat’: events 1-2
|
|   10 |   char *str = xstrdup (pattern);
|  |   ^
|  |   |
|  |   (1) allocated here
|   11 |   hash_insert (str);
|   12 | }
|  | ~
|  | |
|  | (2) ‘str’ leaks here; was allocated at (1)
|

[Bug tree-optimization/101494] New: -Wmaybe-uninitialized false alarm with memrchr of size 0

2021-07-17 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101494

Bug ID: 101494
   Summary: -Wmaybe-uninitialized false alarm with memrchr of size
0
   Product: gcc
   Version: 11.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

I ran into this problem when compiling Gnulib tests on gcc (GCC) 11.1.1
20210531 (Red Hat 11.1.1-3) on x86-64. Here is a stripped down program
illustrating the bug:

void *malloc (unsigned long)
  __attribute__((__malloc__)) __attribute__((__alloc_size__ (1)));

void *memrchr (const void *, int, unsigned long)
  __attribute__((__access__ (__read_only__, 1, 3)));

int
main (void)
{
  char *input = malloc (1);
  if (!input)
return 1;
  *input = 0;
  return !!memrchr (input, 'a', 0);
}


The following command:

gcc -Wmaybe-uninitialized -O2 -S w.i

outputs:
w.i: In function 'main':
w.i:14:12: warning: 'input' may be used uninitialized [-Wmaybe-uninitialized]
   14 |   return !!memrchr (input, 'a', 0);
  |^~~
w.i:4:7: note: in a call to 'memrchr' declared with attribute 'access
(read_onl\
y, 1, 3)' here
4 | void *memrchr (const void *, int, unsigned long)
  |   ^~~

This warning is bogus, as 'input' is initialized; and even if "input = 0;" were
removed the call to memrchr would still be valid as the size argument is 0.

[Bug middle-end/93644] [10/11 Regression] spurious -Wreturn-local-addr with PHI of PHI

2020-12-16 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644

--- Comment #12 from eggert at cs dot ucla.edu ---
There are really two bugs here:

(A) GCC emits the false alarm.

(B) there's no way to shut off the false alarm, not even with '# pragma GCC
diagnostic ignored "-Wreturn-local-addr"'.

Although this bug report's replies have been about (A), even fixing (B) would
be a real help with Gnulib.

Should I file a separate bug report for (B)? I assume (B)'s easier to fix.

[Bug middle-end/93644] [10/11 Regression] spurious -Wreturn-local-addr with PHI of PHI

2020-12-16 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644

--- Comment #11 from eggert at cs dot ucla.edu ---
Created attachment 49783
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49783=edit
another instance of a -Wreturn-local-addr false alarm

I ran into a different instance of the bug today, while working on another
Gnulib source file lib/canonicalize.c. A stripped-down test case attached. To
reproduce the problem:

$ gcc -O2 -S return-local-addr.i 
return-local-addr.i: In function ‘canonicalize_filename_mode’:
cc1: warning: function may return address of local variable
[-Wreturn-local-addr]
return-local-addr.i:28:25: note: declared here
   28 |   struct scratch_buffer rname_buffer;
  | ^~~~

This is with GCC 10.2.1 20201125 (Red Hat 10.2.1-9) on x86-64.

[Bug preprocessor/98021] #warning issues redundant diagnostic lines

2020-11-28 Thread eggert at cs dot ucla.edu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98021

--- Comment #15 from eggert at cs dot ucla.edu ---
(In reply to Andreas Schwab from comment #14)
> I don't follow.  It works exactly the same way.

Let me try to explain further. In my comment #11, the first directive:

#warning "You are too close to the curb"

generates this diagnostic:

In file included from foo.c:1:
bar.h:1:2: warning: #warning "You are too close to the curb" [-Wcpp]
1 | #warning "You are too close to the curb"
  |  ^~~

which contains "You are too close to the curb" twice. In contrast, the second
directive

#warning "Tomorrow is the deadline for paying taxes"

generates only this diagnostic:

In file included from foo.c:1:
baz.h:100:2: warning: #warning "Tomorrow is the deadline for paying taxes"
[-Wcpp]

and this contains "Tomorrow is the deadline for paying taxes" only once, which
is the win I'm suggesting. GCC treats the two #warning directives differently,
and does so because of the intervening #line directive.

  1   2   >