gcc -Waddress got a little bit worse between gcc 4.0.4 and gcc 4.1.2. It would be useful to get this warning, especially for C++ inline methods. mec@hollerith:~/exp-address$ cat z2.cc extern bool Alpha(); inline bool Beta(bool b) { return b; } class MyClass { public: static bool MyMethod(bool b) { return b; } }; bool Gamma() { if (Alpha) { if (Beta) { if (MyClass::MyMethod) { return true; } } } return false; } mec@hollerith:~/exp-address$ /home/mec/gcc-4.0.4/install/bin/g++ -Wall -O2 -S z2.cc z2.cc: In function 'bool Gamma()': z2.cc:6: warning: the address of 'bool Alpha()', will always evaluate as 'true' z2.cc:7: warning: the address of 'bool Beta(bool)', will always evaluate as 'true' z2.cc:8: warning: the address of 'static bool MyClass::MyMethod(bool)', will always evaluate as 'true' mec@hollerith:~/exp-address$ /home/mec/gcc-4.1.2/install/bin/g++ -Wall -O2 -S z2.cc z2.cc: In function 'bool Gamma()': z2.cc:6: warning: the address of 'bool Alpha()', will always evaluate as 'true' mec@hollerith:~/exp-address$ /home/mec/gcc-4.2.2/install/bin/g++ -Wall -O2 -S z2.cc z2.cc: In function 'bool Gamma()': z2.cc:6: warning: the address of 'bool Alpha()' will always evaluate as 'true' mec@hollerith:~/exp-address$ /home/mec/gcc-4.3-20071019/install/bin/g++ -Wall -O2 -S z2.cc z2.cc: In function 'bool Gamma()': z2.cc:6: warning: the address of 'bool Alpha()' will always evaluate as 'true' mec@hollerith:~/exp-address$
I am not sure if this is actually a bug, since I think functions with weak linkage can actually have a null-address if they are not instantiated. Nonetheless, a regression hunt identifies this patch as the cause: r104103 | mmitchel | 2005-09-09 20:56:16 +0200 (Fri, 09 Sep 2005) | 15 lines PR c++/22252 * decl.c (start_preparsed_function): Do not pay attention to #pragma interface for implicitly-defined methods. * decl2.c (cp_finish_file): Do not complain about uses of inline functions that have bodies, even if we decided not to emit the body in this translation unit. * semantics.c (note_decl_for_pch): Do not mess with linkage. (expand_or_defer_fn): Make inline, non-template functions COMDAT at this point. PR c++/22252 * g++.dg/ext/interface1.C: New test. * g++.dg/ext/interface1.h: Likewise. * g++.dg/ext/interface1a.cc: Likewise.
Is this really a bug or not?
Subject: Re: gcc -Waddress lost some useful warnings Yes, I think this is a bug, because the behavior of gcc doesn't match its documentation. First, I think the C++ standard forbids a function from having a null address: [conv.ptr] 4.10 -1- A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evalutes to zero. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of pointer to object or pointer to function type. Even if you break this to allow for weak pointers to functions, the documentation for -Waddress says: http://gcc.gnu.org/onlinedocs/gcc-4.4.1/gcc/Warning-Options.html#Warning-Options "Warn about suspicious uses of memory addresses. These include the address of a function in a conditional expression such as void func(void); if (func) ... such uses typically indicate a programmer error: the address of a function always evaluates to true, so their use in a conditional usually indicate that the programmer forgot the parentheses in a function call ...". This documentation repeats the claim that "the address of a function is always true". More than that: "warnings are diagnostic messages that report constructions which are not inherently erroneous but which are risky or suggest there may have been an error". By enabling -Waddress, I believe the user intends to report all instances of "if (func)" with the expectation that most of them are mistaken versions of "if (func())" or "if (func(some_parameters ...))". If the user is building (non-standard) code where the addresses of some functions may be null and "if (func)" is likely the intended meaning, then they can decline to turn on -Waddress. If such code is common, you may want to re-think the inclusion of -Waddress in -Wall. As it is, -Waddress sometimes prints the message that it is documented to print, and sometimes does not.
OK, but I don't think anyone is going to step up soon to implement this, so feel free to give it a try yourself.
(In reply to comment #3) > First, I think the C++ standard forbids a function from having a null > address: But GCC extensions allow it, see the weakref attribute: http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#index-g_t_0040code_007bweakref_007d-attribute-2648 That's used (among other places) by GCC's pthreads abstraction layer to declare a weak alias to pthread_create, which has a null address unless libpthread is linked to. Testing whether the address is null (i.. whether the application was linked to libpthread) is used for important optimisations.
... That's not an argument against improving the warning though. GCC's uses occur in system headers so warnings are suppressed, and could be worked around anyway with further extensions such as #pragma GCC diagnostic
(In reply to comment #6) > ... That's not an argument against improving the warning though. GCC's uses > occur in system headers so warnings are suppressed, and could be worked around > anyway with further extensions such as #pragma GCC diagnostic Or even better, only skip the warning for functions marked as weakref, which I guess is a very small subset. I think a patch that did that would be accepted. Unfortunately, Michael, I don't think there is anyone with enough free time to work on this, so if you submitted a patch, that would be great! Thanks.
With pr102103 resolved, let me handle this.
As noted in comment 1, this is a regression. Patch: https://gcc.gnu.org/pipermail/gcc-patches/2021-October/580899.html
The master branch has been updated by Martin Sebor <msebor@gcc.gnu.org>: https://gcc.gnu.org/g:16137fbb9256ef365dd498d39024eb33de1a4cd8 commit r12-5410-g16137fbb9256ef365dd498d39024eb33de1a4cd8 Author: Martin Sebor <msebor@redhat.com> Date: Fri Nov 19 09:44:31 2021 -0700 Restore ancient -Waddress for weak symbols [PR33925]. Resolves: PR c/33925 - gcc -Waddress lost some useful warnings PR c/102867 - -Waddress from macro expansion in readelf.c gcc/c-family/ChangeLog: PR c++/33925 PR c/102867 * c-common.c (decl_with_nonnull_addr_p): Call maybe_nonzero_address and improve handling tof defined symbols. gcc/c/ChangeLog: PR c++/33925 PR c/102867 * c-typeck.c (maybe_warn_for_null_address): Suppress warnings for code resulting from macro expansion. gcc/cp/ChangeLog: PR c++/33925 PR c/102867 * typeck.c (warn_for_null_address): Suppress warnings for code resulting from macro expansion. gcc/ChangeLog: PR c++/33925 PR c/102867 * doc/invoke.texi (-Waddress): Update. gcc/testsuite/ChangeLog: PR c++/33925 PR c/102867 * g++.dg/warn/Walways-true-2.C: Adjust to avoid a valid warning. * c-c++-common/Waddress-5.c: New test. * c-c++-common/Waddress-6.c: New test. * g++.dg/warn/Waddress-7.C: New test. * gcc.dg/Walways-true-2.c: Adjust to avoid a valid warning. * gcc.dg/weak/weak-3.c: Expect a warning.
Fixed in GCC 12.
I'm not planning to backport the GCC 12 changes.