NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
toolchain/60289: NetBSD 11 gcc mis-optimises some NULL checks
>Number: 60289
>Category: toolchain
>Synopsis: NetBSD 11 gcc mis-optimises some NULL checks
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: toolchain-manager
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat May 23 18:45:00 +0000 2026
>Originator: Manuel Bouyer
>Release: NetBSD 11.0_RC4
>Organization:
>Environment:
System: NetBSD armandeche.soc.lip6.fr 10.1_STABLE NetBSD 10.1_STABLE (GENERIC_CAN) #36: Mon Oct 13 12:20:13 CEST 2025 bouyer%armandeche.soc.lip6.fr@localhost:/local/armandeche1/tmp/build/amd64/obj/local/armandeche2/netbsd-10/src/sys/arch/amd64/compile/GENERIC_CAN amd64
Architecture: x86_64
Machine: amd64
>Description:
I tried updating a server from 10.1_STABLE to 11.0_RC4 and got a
panic within minutes, related to a NULL pointer dereference.
The issue is in ipf_fastroute(), but the code looks good and
dissasembly shows that gcc dropped a NULL pointer check.
I've been able to reproduce it with a simple test funtion (see
How-To-Repeat). It seems that construct like
if (fdp != &fr->fr_dif)
causes gcc to assume (wrongly) that fr cannot be NULL.
This happens at -O2 or highter, -O1 produces the expected code.
>How-To-Repeat:
cat > test-misopt.h << EOF
typedef struct foo {
void *fp;
} foo_t;
typedef struct bar {
void *bp;
foo_t foo;
int flags;
} bar_t;
void testf(foo_t *, bar_t *);
EOF
cat > test-misopt.c << EOF
#include <stdio.h>
#include "test-misopt.h"
void
testf(foo_t *foop, bar_t *barp)
{
if (&barp->foo != foop) {
printf("A ");
if (!barp || !(barp->flags & 0x01)) {
printf("B ");
}
printf("C ");
}
printf("D\n");
}
EOF
/home/build/amd64/obj/netbsd-11/tooldir/bin/x86_64--netbsd-gcc -g -c -O2 test-misopt.c
gdb -ex "disas /s testf" test-misopt.o
and notice:
10 if (!barp || !(barp->flags & 0x01)) {
0x0000000000000021 <+33>: testb $0x1,0x10(%rbx)
0x0000000000000025 <+37>: je 0x4d <testf+77>
%rsi or %rbx is never tested for 0.
>Fix:
#pragma GCC optimize ("O1")
before the affected funtion works around it
But this behavior is worrisome
Home |
Main Index |
Thread Index |
Old Index