The following with -std=c++20 -Waddress: #include <iostream> template<const char* ARG = nullptr> void test() { if constexpr(ARG == nullptr) { std::cout << "Nullptr!!" << std::endl; } else { std::cout << ARG << "heh" << std::endl; } } const char CONSTSTR[] = {'\n', '\t', ' ', '\0'}; int main() { test(); test<CONSTSTR>(); } gives a spurious/pointless warning: <source>: In instantiation of 'void test() [with const char* ARG = (& CONSTSTR)]': <source>:16:19: required from here <source>:5:22: warning: the address of 'CONSTSTR' will never be NULL [-Waddress] 5 | if constexpr(ARG == nullptr) { | ~~~~^~~~~~~~~~ <source>:12:12: note: 'CONSTSTR' declared here 12 | const char CONSTSTR[] = {'\n', '\t', ' ', '\0'}; | ^~~~~~~~ ASM generation compiler returned: 0 <source>: In instantiation of 'void test() [with const char* ARG = (& CONSTSTR)]': <source>:16:19: required from here <source>:5:22: warning: the address of 'CONSTSTR' will never be NULL [-Waddress] 5 | if constexpr(ARG == nullptr) { | ~~~~^~~~~~~~~~ <source>:12:12: note: 'CONSTSTR' declared here 12 | const char CONSTSTR[] = {'\n', '\t', ' ', '\0'}; Clang doesn't produce a warning for this case. Potentially very similar to: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94554
Confirmed, yes this warning should not happen even if it was not inside constexpr.
We diagnose only after template substitution where we cannot distinguish literal if (nullptr == nullptr) from if (ARG == nullptr) I think. I guess reporters reasoning is that ARG is defaulted to nullptr and that's the reason the diagnostic is unwanted?
> I guess reporters reasoning is that ARG is defaulted to nullptr and that's the reason the diagnostic is unwanted? I don't think it has any todo with whether nullptr is the default value for ARG or not. Even if it's not the default value, it is a valid one the API's user might explicitly pass to ARG. My point rather is that, at least the way I understood it, `if constexpr` is meant to implement conditional behavior based on a template argument. And it is obvious that one of the if-branches is going to be comparing ARG to whatever was passed in for it. So the compiler warning about this didn't make much sense for me here. Of course I could use template specialization to get rid of the warning, but what if the function body is very long and only a tiny fraction of it needs special handling for ARG? Then I would be copying the function body multiple times for all specializations.
The master branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:6e4d5300c1f62c3f0cd1bf859b0ee6bb4e31e434 commit r13-1218-g6e4d5300c1f62c3f0cd1bf859b0ee6bb4e31e434 Author: Jason Merrill <jason@redhat.com> Date: Wed Jun 22 23:50:23 2022 -0400 c++: -Waddress and value-dependent expr [PR105885] We already suppress various warnings for code that would be tautological if written directly, but not when it's the result of template substitution. It seems we need to do this for -Waddress as well. PR c++/105885 gcc/cp/ChangeLog: * pt.cc (tsubst_copy_and_build): Also suppress -Waddress for comparison of dependent operands. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/constexpr-if37.C: New test.
The releases/gcc-12 branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:b96b64bec37c3dddf1f0f93c27ceb4fd5685c70a commit r12-8510-gb96b64bec37c3dddf1f0f93c27ceb4fd5685c70a Author: Jason Merrill <jason@redhat.com> Date: Wed Jun 22 23:50:23 2022 -0400 c++: -Waddress and value-dependent expr [PR105885] We already suppress various warnings for code that would be tautological if written directly, but not when it's the result of template substitution. It seems we need to do this for -Waddress as well. PR c++/105885 gcc/cp/ChangeLog: * pt.cc (tsubst_copy_and_build): Also suppress -Waddress for comparison of dependent operands. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/constexpr-if37.C: New test.
Fixed for 12.2/13.