This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c/88367] New: [9 Regression] -fno-delete-null-pointer-checks doesn't work properly


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

            Bug ID: 88367
           Summary: [9 Regression] -fno-delete-null-pointer-checks doesn't
                    work properly
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: pbutsykin at virtuozzo dot com
  Target Milestone: ---

For some reason gcc9 began to delete NULL pointer checks even with
-fno-delete-null-pointer-checks option (which should prohibit doing so).

There is the following function:
static long kmapset_cmp(struct kmapset_map *map_a, struct kmapset_map *map_b)
{
        struct kmapset_link *link_a, *link_b;

        if (map_a->hash != map_b->hash)
                return map_a->hash - map_b->hash;

        if (map_a->size != map_b->size)
                return map_a->size - map_b->size;

        link_a = hlist_entry(map_a->links.first,
                        struct kmapset_link, map_link);
        link_b = hlist_entry(map_b->links.first,
                        struct kmapset_link, map_link);
        while (&link_a->map_link) {
                if (link_a->key != link_b->key)
                        return (long)link_a->key - (long)link_b->key;
                if (link_a->value != link_b->value)
                        return link_a->value - link_b->value;
                link_a = list_entry(link_a->map_link.next,
                                struct kmapset_link, map_link);
                link_b = list_entry(link_b->map_link.next,
                                struct kmapset_link, map_link);
        }

        return map_a->default_value - map_b->default_value;
}
Full source:
https://github.com/OpenVZ/vzkernel/blob/branch-rh7-3.10.0-123.1.2-ovz/lib/kmapset.c

The problem is that gcc9 removes while condition 'while (&link_a->map_link)'
even with -fno-delete-null-pointer-checks option. There is undefined behavior
with taking the address from lvalue which doesn't designate an object. In the
case when map_a->links.first is NULL, then link_a will be equal to (NULL - 24)
and expression &((struct kmapset_link *)(NULL - 24))->map_link will refer to
NULL. Ok, it's undefined behavior and the compiler can remove this check, but
shouldn't -fno-delete-null-pointer-checks prevent this? GCC8 with
-fno-delete-null-pointer-checks don't remove this check.
GCC9 was built on this commit:
commit 3d4762327aed5cf6cafbaa7a52166df4ef92eb82
Author: rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Tue Dec 4 11:26:14 2018 +0000

    2018-12-04  Richard Biener  <rguenther@suse.de>

        PR tree-optimization/88301
        * tree-vrp.c (register_edge_assert_for_2): Fix sign-conversion
        issues in last commit.

The assembly code generated by gcc9 - https://pastebin.com/dkuEuyLQ
ffffffff81b4bd9c:   48 8b 48 f0             mov    rcx,QWORD PTR 
[rax-0x10]  //BUG: unable to handle kernel paging request at fffffffffffffff0
(this is link_a->key)

All gcc flags that are used - https://pastebin.com/6AbyEXgF

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]