Bug 96507 - missing -Waddress for member references
Summary: missing -Waddress for member references
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: unknown
: P3 normal
Target Milestone: 12.0
Assignee: Martin Sebor
URL:
Keywords: diagnostic, patch
Depends on:
Blocks: Waddress
  Show dependency treegraph
 
Reported: 2020-08-06 16:43 UTC by Federico Kircheis
Modified: 2021-11-23 22:42 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-11-22 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Federico Kircheis 2020-08-06 16:43:59 UTC
This is a feature request.


I'm compiling the code with "-Wall -Wextra -pedantic"

----
#include <utility>

void foo(){}

int main(){
    void(&f)() = foo;
    static_assert(!std::is_pointer<decltype(f)>::value, "should not be a pointer");
    return f != 0;
}
----

gcc correctly triggers the warning "warning: the address of 'void foo()' will never be NULL [-Waddress]" (nitpick nullptr in the error message would be better than NULL).

Also for following example gcc emits the desired diagnostic

----
#include <utility>

void foo(){}

using fun = void();

fun& get_fun();

int main(){
    fun& f = get_fun();
    static_assert(!std::is_pointer<decltype(f)>::value, "should not be a pointer");
    return f != 0;
}
----

But if the function reference is inside a struct:

----
#include <utility>

void foo(){}

using fun = void();

struct s{
    fun& f;
};

s get_fun();

int main(){
    s ss = get_fun();
    static_assert(!std::is_pointer<decltype(ss.f)>::value, "should not be a pointer");
    return ss.f != 0;
}
----


then gcc does not emit any diagnostic (notice: it does if it can inline get_fun()), even if "knows" that it cannot be null, as the static_assert does not fire.

As reference: https://godbolt.org/z/vqohqM
Comment 1 Martin Sebor 2021-11-22 17:05:42 UTC
Confirmed with GCC 12.  Since the warning is issued for non-member references (the first case below) but not for members (the second case) I would consider this a bug rather than an enhancement request.

$ cat pr96507.C && gcc -S -Wall pr96507.C
typedef void F ();

extern F &fr;
extern int &ir;

bool gfun ()
{
  return &fr != 0;   // -Waddress (expected)
}

bool gvar ()
{
  return &ir != 0;   // -Waddress (expected)
}


struct S
{
  F &fr;
  int &ir;
};

extern S s;

bool hfun ()
{
  return &s.fr != 0; // missing warning
}

bool hvar ()
{
  return &s.ir != 0; // missing warning
}

pr96507.C: In function ‘bool gfun()’:
pr96507.C:8:14: warning: the compiler can assume that the address of ‘fr’ will never be NULL [-Waddress]
    8 |   return &fr != 0;   // -Waddress (expected)
      |          ~~~~^~~~
pr96507.C:3:11: note: ‘fr’ declared here
    3 | extern F &fr;
      |           ^~
pr96507.C: In function ‘bool gvar()’:
pr96507.C:13:14: warning: the compiler can assume that the address of ‘ir’ will never be NULL [-Waddress]
   13 |   return &ir != 0;   // -Waddress (expected)
      |          ~~~~^~~~
pr96507.C:4:13: note: ‘ir’ declared here
    4 | extern int &ir;
      |             ^~
Comment 3 GCC Commits 2021-11-23 22:37:19 UTC
The master branch has been updated by Martin Sebor <msebor@gcc.gnu.org>:

https://gcc.gnu.org/g:2dd56aed3e4e1938a9020ab2fe6a410e1a1c2eb3

commit r12-5484-g2dd56aed3e4e1938a9020ab2fe6a410e1a1c2eb3
Author: Martin Sebor <msebor@redhat.com>
Date:   Tue Nov 23 15:35:31 2021 -0700

    Issue -Waddress also for reference members [PR96507].
    
    Resolves:
    PR c++/96507 - missing -Waddress for member references
    
    gcc/cp/ChangeLog:
    
            PR c++/96507
            * typeck.c (warn_for_null_address): Handle reference members.
    
    gcc/testsuite/ChangeLog:
    
            PR c++/96507
            * g++.dg/warn/Waddress-8.C: New test.
Comment 4 Martin Sebor 2021-11-23 22:42:21 UTC
Fixed in GCC 12.