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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
           Keywords|                            |diagnostic
   Last reconfirmed|                            |2021-10-27
     Ever confirmed|0                           |1
            Summary|-Waddress with nested       |confusing location in
                   |structures: Incorrect "the  |-Waddress for a
                   |comparison will always      |subexpression of a ternary
                   |evaluate as 'true'"         |expression
                 CC|                            |msebor at gcc dot gnu.org

--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
The warning is intended: it points out that the second operand of the
conditional expression is necessarily true:

  if ( !(pa ? &pa->c : NULL) )
              ^^^^^^

There's no point in testing the address of a member for equality to null
because  the member of no object can reside at that address.  The above can be
simplified to

  if (!pa)

Below are a couple of small examples to illustrate.

I confirm this as a report of the underlining being confusing.  In the message
on Godbolt:

   20 |     if ( !(pa ? &pa->c : NULL) ) // Macro expanded, just to check. 
Still wrong.
      |          ^

and in the first message below it could stand to be improved to point to the
second operand rather than the first (as I did above).

I also note that the C front end diagnoses both expressions as expected but the
C++ front end only the latter one.  That seems like an omission to me that
should be fixed.

$ cat a.c && gcc -S -Wall a.cstruct A { int i; };

int f (struct A *p)
{
  if (p ? &p->i : 0)   // -Waddress
    return 0;
  return 1;
}

int g (struct A *p)
{
  if (&p->i)           // -Waddress
    return 0;
  return 1;
}

a.c: In function ‘f’:
a.c:5:7: warning: the comparison will always evaluate as ‘true’ for the address
of ‘i’ will never be NULL [-Waddress]
    5 |   if (p ? &p->i : 0)   // -Waddress
      |       ^
a.c:1:16: note: ‘i’ declared here
    1 | struct A { int i; };
      |                ^
a.c: In function ‘g’:
a.c:12:7: warning: the comparison will always evaluate as ‘true’ for the
address of ‘i’ will never be NULL [-Waddress]
   12 |   if (&p->i)           // -Waddress
      |       ^
a.c:1:16: note: ‘i’ declared here
    1 | struct A { int i; };
      |                ^

When reporting bugs, please be sure to include the full test case and its
output as requested at https://gcc.gnu.org/bugs/#need.  Links to external sites
are not a substitute.  They might stop working, or the compiler used there
might become out of date, leaving us with insufficient detail to analyze the
report.

Reply via email to