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

            Bug ID: 83555
           Summary: Unnecessary null check when static_cast is used with
                    references.
           Product: gcc
           Version: 7.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: maxim.yegorushkin at gmail dot com
  Target Milestone: ---

When the following code is compiled with `g++ --std=c++14 -O3`:

    struct A { int a; };
    struct B { int b; };
    struct C : A, B { int c; };

    C* f(B* b) { return static_cast<C*>(b); }
    C* g(B* b) { return &static_cast<C&>(*b); }

It generates the following x86-64 code:

    f(B*):
            leaq    -4(%rdi), %rax
            testq   %rdi, %rdi
            movl    $0, %edx
            cmove   %rdx, %rax
            ret
    g(B*):
            leaq    -4(%rdi), %rax
            testq   %rdi, %rdi
            movl    $0, %edx
            cmove   %rdx, %rax
            ret

Function f contains the check for null pointer as expected because static_cast
is required to preserve it. Whereas function g contains the unnecessary check
for null because the reference cannot be null.

I also tried compiling the code with clang-5.0.0 and it correctly omits the
null check in function g generating the expected assembly:

    g(B*):
            leaq    -4(%rdi), %rax
            retq

Why does g++ generate that unnecessary null check in function g please, even
when compiled with -fno-delete-null-pointer-checks?

Reply via email to