public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/95663] New: static_cast checks for null even when the pointer is dereferenced
@ 2020-06-13 10:52 jzwinck at gmail dot com
  2020-06-15  6:47 ` [Bug tree-optimization/95663] " rguenth at gcc dot gnu.org
                   ` (21 more replies)
  0 siblings, 22 replies; 23+ messages in thread
From: jzwinck at gmail dot com @ 2020-06-13 10:52 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 95663
           Summary: static_cast checks for null even when the pointer is
                    dereferenced
           Product: gcc
           Version: 10.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jzwinck at gmail dot com
  Target Milestone: ---

Consider this C++ code:

    struct Base1
    {
        int x;
    };

    struct Base2
    {
        int y;
    };

    struct Derived : Base1, Base2
    {
        int get_y() const { return y; }
    };

    int field(Base2* base)
    {
        return static_cast<Derived*>(base)->y;
    }

    int getter(Base2* base)
    {
        return static_cast<Derived*>(base)->get_y();
    }

Both field() and getter() produce this with -O2 or -O3:

    test    rdi, rdi
    je      .L2
    mov     eax, DWORD PTR [rdi]
    ret
    .L2:
    mov     eax, DWORD PTR ds:4
    ud2

That's fair, it traps if we dereference a null pointer.  But I need the best
performance and don't want the null check, so I add
-fno-isolate-erroneous-paths-dereference and see:

    lea     rax, [rdi-4]
    test    rdi, rdi
    cmovne  rdi, rax
    mov     eax, DWORD PTR [rdi+4]
    ret

If I read that correctly, it checks if the pointer is null so it can
dereference 0x4 instead of 0x0.  That's hardly an improvement over the naive
and optimal code:

    mov     eax, DWORD PTR [rdi]
    ret

Which is what Clang generates for field() in all versions through 10, and for
getter() up to 3.6 (3.7 through 10 generate a cmovne like GCC with no-isolate).

I tried adding __attribute__((nonnull)) to the function declarations, but it
didn't help.

Live demo: https://godbolt.org/z/XnhZoz

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2022-01-03  9:54 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-13 10:52 [Bug c++/95663] New: static_cast checks for null even when the pointer is dereferenced jzwinck at gmail dot com
2020-06-15  6:47 ` [Bug tree-optimization/95663] " rguenth at gcc dot gnu.org
2020-06-15 10:04 ` redi at gcc dot gnu.org
2020-06-15 10:09 ` redi at gcc dot gnu.org
2020-06-15 11:46 ` jzwinck at gmail dot com
2020-06-15 12:50 ` rguenther at suse dot de
2020-06-15 12:53 ` redi at gcc dot gnu.org
2020-06-15 12:54 ` redi at gcc dot gnu.org
2020-06-15 13:03 ` rguenther at suse dot de
2020-06-15 13:32 ` jakub at gcc dot gnu.org
2020-06-26 22:18 ` law at redhat dot com
2020-06-27  0:20 ` jzwinck at gmail dot com
2020-06-27 11:49 ` glisse at gcc dot gnu.org
2020-06-27 15:36 ` law at redhat dot com
2020-06-27 15:40 ` law at redhat dot com
2020-06-27 15:57 ` jakub at gcc dot gnu.org
2021-01-07 13:13 ` redi at gcc dot gnu.org
2021-01-07 13:14 ` redi at gcc dot gnu.org
2021-01-07 20:00 ` law at redhat dot com
2021-12-13 11:05 ` hubicka at gcc dot gnu.org
2021-12-13 11:10 ` hubicka at gcc dot gnu.org
2021-12-13 15:51 ` law at gcc dot gnu.org
2022-01-03  9:54 ` rguenther at suse dot de

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).