Bug 105585 - [12/13 Regression] Spurious stringop-overflow warning with <atomic> since r12-4725-g88b504b7a8c5affb
Summary: [12/13 Regression] Spurious stringop-overflow warning with <atomic> since r12...
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 12.1.0
: P3 normal
Target Milestone: 12.2
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: Wstringop-overflow
  Show dependency treegraph
 
Reported: 2022-05-12 16:58 UTC by Ed Catmur
Modified: 2022-10-27 03:03 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2022-05-13 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ed Catmur 2022-05-12 16:58:07 UTC
Reduced (from code in abseil-cpp):

#include <atomic>
struct S {
  int i;
  std::atomic<int> a;
};
S* q();
void f();
void g(bool b) {
  auto p = b ? q() : nullptr;
  ++p->a;
  if (p)
    f();
}

In file included from atomic:41,
                 from <source>:1:
In member function 'std::__atomic_base<_IntTp>::__int_type std::__atomic_base<_IntTp>::operator++() [with _ITp = int]',
    inlined from 'void g(bool)' at <source>:10:3:
bits/atomic_base.h:385:34: warning: 'unsigned int __atomic_add_fetch_4(volatile void*, unsigned int, int)' writing 4 bytes into a region of size 0 overflows the destination [-Wstringop-overflow=]
  385 |       { return __atomic_add_fetch(&_M_i, 1, int(memory_order_seq_cst)); }
      |                ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Comment 1 Ed Catmur 2022-05-12 16:59:57 UTC
Flags: -O1 -Wstringop-overflow=1
https://godbolt.org/z/8r8roz7Pa
Comment 2 Ed Catmur 2022-05-12 17:50:32 UTC
Affected code: https://github.com/abseil/abseil-cpp/issues/1175
The proposed patch to abseil-cpp corresponds to adding an assumption that `b` is true above.
Comment 3 Martin Liška 2022-05-13 12:02:19 UTC
Started with r12-4725-g88b504b7a8c5affb.
Comment 4 Martin Sebor 2022-05-17 14:15:30 UTC
The warning is caused by the if statement: if p is null, accessing the p->a member is undefined.  It triggers because the GCC optimizer splits the code into two branches: one with a nonnull p and another with a null p.  The second one triggers the warning.

If p can be null then moving the increment to the body of the if statement avoids the undefined behavior (and the warning).  If p cannot be null then making the if statement unconditional also avoids the warning.