https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105569
Bug ID: 105569
Summary: -Waddress warns on dynamic_cast
Product: gcc
Version: 12.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: anton.reinhard at protonmail dot com
Target Milestone: ---
compiling with -Waddress yields a useless warning compiling the following code:
Compiler version:
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/12.1.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure
--enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-bootstrap
--prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man
--infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/
--with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit
--enable-cet=auto --enable-checking=release --enable-clocale=gnu
--enable-default-pie --enable-default-ssp --enable-gnu-indirect-function
--enable-gnu-unique-object --enable-linker-build-id --enable-lto
--enable-multilib --enable-plugin --enable-shared --enable-threads=posix
--disable-libssp --disable-libstdcxx-pch --disable-werror
--with-build-config=bootstrap-lto --enable-link-serialization=1
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.1.0 (GCC)
Compiled using:
$ g++ warn.cpp -Waddress
warn.cpp: In function ‘int main()’:
warn.cpp:12:22: warning: comparing the result of pointer addition ‘(((A*)ref) +
((sizetype)(*(long int*)((& ref)->B::_vptr.B + -24))))’ and NULL [-Waddress]
12 | bool b = nullptr == dynamic_cast<A*>(&ref);
| ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
The file warn.cpp:
class A {};
class B : public virtual A {};
class C : public A {};
int main() {
B* object = new B();
B &ref = *object;
// -Waddress warns here
bool b = nullptr == dynamic_cast<A*>(&ref);
// -Waddress doesn't warn anymore
auto ptr = dynamic_cast<A*>(&ref);
bool b2 = ptr == nullptr;
C* cobject = new C();
C &cref = *cobject;
// -Waddress also doesn't warn anymore
bool b3 = nullptr == dynamic_cast<A*>(&cref);
}
The warning:
warn.cpp: In function ‘int main()’:
warn.cpp:12:22: warning: comparing the result of pointer addition ‘(((A*)ref) +
((sizetype)(*(long int*)((& ref)->B::_vptr.B + -24))))’ and NULL [-Waddress]
12 | bool b = nullptr == dynamic_cast<A*>(&ref);
| ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
However, dynamic_cast should return nullptr if the cast failed, so this warning
seems invalid to me. I don't know if just the warning is in error or if the
produced code is buggy.
It only happens when the derived class inherits with virtual (see class C)
It doesn't warn in versions previous to gcc-12, or in any clang versions I've
tried which makes me think it's a bug and not me making a mistake.