This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/88367] New: [9 Regression] -fno-delete-null-pointer-checks doesn't work properly
- From: "pbutsykin at virtuozzo dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 05 Dec 2018 12:02:45 +0000
- Subject: [Bug c/88367] New: [9 Regression] -fno-delete-null-pointer-checks doesn't work properly
- Auto-submitted: auto-generated
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