https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104475

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |msebor at gcc dot gnu.org
   Last reconfirmed|                            |2022-02-09
             Blocks|                            |88443
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1

--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
Both warnings trigger for the same reason.  The second one is for the
__atomic_or_fetch_4() call in basic block 4 below with the invalid pointer as
the first argument (184B).

  <bb 2> [local count: 1073741824]:
  _1 = this_10(D)->d;
  _2 = &_1->m_mutex;                              <<< address of a member can
never be null
  MEM[(struct __as_base  &)&lock] ={v} {CLOBBER};
  if (_2 != 0B)                                   <<< must be true
    goto <bb 5>; [90.00%]
  else
    goto <bb 3>; [10.00%]                          <<< never taken

  <bb 3> [local count: 107374184]:
  if (enable_12(D) != 0)
    goto <bb 4>; [50.00%]
  else
    goto <bb 18>; [50.00%]

  <bb 4> [local count: 53687092]:
  __atomic_or_fetch_4 (184B, 64, 0); [tail call]   <<< warning here
  goto <bb 11>; [100.00%]

The call is emitted as a result of the test in bb 2.  That in turn is the
result of the test for null in the QMutexLocker ctor:

    inline explicit QMutexLocker(Mutex *mutex) noexcept
    {
        m = mutex;
        if (__builtin_expect(!!(mutex), true)) {
            mutex->lock();
            isLocked = true;
        }
    }

The test should be pointless in setThrottled() where the ctor is invoked
because the address of no member can be null:

void QFutureInterfaceBase::setThrottled(bool enable)
{
    QMutexLocker lock(&d->m_mutex);
    if (enable) {
        switch_on(d->state, Throttled);

The invalid call first appears in the dom2 dump so I'm guessing it's the result
of the prior thread1 pass.

The test (and the warning) can be avoided by asserting that in setThrottled()
like so:

    if (!d) __builtin_unreachable ();
    QMutexLocker lock(&d->m_mutex);

GCC folds equality tests involving the addresses of members, except for the
first one when it involves a pointer access (below), presumably out of an
overabundance of caution, in case the pointer is null (GCC 4.1 eliminated all
tests but that's changed since then).  The warning GCC issues indicates it
considers the address to be nonnull regardless (that's new in GCC 12).

$ cat t.c && gcc -O2 -S -Wall -march=haswell -fdump-tree-optimized=/dev/stdout
t.c
struct A { int x, y; };

void f (struct A *p)
{
  if (!&p->y)              // -Waddress
    __builtin_abort ();    // eliminated
}

void g (struct A *p)
{
  if (!&p->x)              // -Waddress
    __builtin_abort ();    // not eliminated
}
t.c: In function ‘f’:
t.c:5:7: warning: the comparison will always evaluate as ‘true’ for the address
of ‘y’ will never be NULL [-Waddress]
    5 |   if (!&p->y)              // -Waddress
      |       ^
t.c:1:19: note: ‘y’ declared here
    1 | struct A { int x, y; };
      |                   ^
t.c: In function ‘g’:
t.c:11:7: warning: the comparison will always evaluate as ‘true’ for the
address of ‘x’ will never be NULL [-Waddress]
   11 |   if (!&p->x)              // -Waddress
      |       ^
t.c:1:16: note: ‘x’ declared here
    1 | struct A { int x, y; };
      |                ^

;; Function f (f, funcdef_no=0, decl_uid=2479, cgraph_uid=1, symbol_order=0)

void f (struct A * p)
{
  <bb 2> [local count: 1073741824]:
  return;

}



;; Function g (g, funcdef_no=1, decl_uid=2482, cgraph_uid=2, symbol_order=1)

void g (struct A * p)
{
  int * _1;

  <bb 2> [local count: 1073741824]:
  _1 = &p_2(D)->x;
  if (_1 == 0B)
    goto <bb 3>; [0.00%]
  else
    goto <bb 4>; [100.00%]

  <bb 3> [count: 0]:
  __builtin_abort ();

  <bb 4> [local count: 1073741824]:
  return;

}


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88443
[Bug 88443] [meta-bug] bogus/missing -Wstringop-overflow warnings

Reply via email to