https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89672
Bug ID: 89672
Summary: NULL pointer check optimized out for the return value
of memchr(NULL, c, 0)
Product: gcc
Version: 8.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: him at revl dot org
Target Milestone: ---
Created attachment 45947
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45947&action=edit
Source that reproduces the problem
The attached code, when compiled with -O1 or more aggressive,
produces incorrect output and exits with return code 1:
$ g++ -Wall -Wextra -Werror -pedantic -O1 -o parser parser.cc
$ ./parser
tok(first)
m_CurrentPtr=[...]
tok(second)
m_CurrentPtr=(nil)
tok()
echo $?
1
When compiled without optimization, or when *any* of the three optimizations
listed below is disabled, the code produces the correct output and exits
normally:
$ g++ -Wall -Wextra -Werror -pedantic -O0 -o parser parser.cc
$ ./parser
tok(first)
m_CurrentPtr=[...]
tok(second)
echo $?
0
It appears that the check m_CurrentPtr != nullptr in the second call to
PrintTokenIfFound() is optimized out if the built-in memchr is used.
If a custom implementation of memchr (FindNewline()) is used in the
second call, the code produces the correct result.
Adding *any* of these options to the command line also fixes the problem:
-fno-delete-null-pointer-checks
-fno-tree-dominator-opts
-fno-inline
The problem is also reproducible with older versions (I tried 4.9.3 and
7.3.0).