While experimenting with the enhanced -Wnonnull warning added in GCC 7.0 (bug 17308) I noticed that it fails to detect the following trivial case of passing a null pointer to a function declared nonnull. This is different from bug 78914 where the null pointer is being dereferenced directly. $ cat z.c && gcc -O2 -S -Wall -Wextra -Wpedantic -fdump-tree-optimized=/dev/stdout z.c int g (int i, int j) { char *p = i <= 0 ? (char*)0 : "123"; char *q = 0 != i ? (char*)0 : "4567"; char *r = i ? q : p; return __builtin_strlen (r); } z.c: In function ‘g’: z.c:1:19: warning: unused parameter ‘j’ [-Wunused-parameter] int g (int i, int j) ^ ;; Function g (g, funcdef_no=0, decl_uid=1796, cgraph_uid=0, symbol_order=0) g (int i, int j) { long unsigned int _1; int _7; <bb 2> [100.00%]: _1 = __builtin_strlen (0B); _7 = (int) _1; return _7; }
Confirmed, although I'm wondering how this is different from bug 78998? Sure, the original source is slightly different, but they optimize to pretty much the same thing... doing -fdump-tree-optimized to text files instead of /dev/stdout and then comparing them gives: $ diff -u 78998_opt.txt 78917_opt.txt --- 78998_opt.txt 2017-08-28 15:50:10.000000000 -0400 +++ 78917_opt.txt 2017-08-28 15:50:23.000000000 -0400 @@ -1,15 +1,15 @@ -;; Function f (f, funcdef_no=0, decl_uid=1769, cgraph_uid=0, symbol_order=0) +;; Function g (g, funcdef_no=0, decl_uid=1770, cgraph_uid=0, symbol_order=0) -f (int i) +g (int i, int j) { long unsigned int _1; - int _6; + int _7; <bb 2> [100.00%] [count: INV]: _1 = __builtin_strlen (0B); [tail call] - _6 = (int) _1; - return _6; + _7 = (int) _1; + return _7; } $
Another test case: $ cat f.c && gcc -O2 -S -Wall -Wextra f.c int f (int i) { const char * p = __builtin_strchr (i ? "123" : "456", '2'); return __builtin_strlen (p); } The strlen argument is a phi with a null operand so that should make it easy to detect: # prephitmp_11 = PHI <_10(3), 0B(2)> _1 = __builtin_strlen (prephitmp_11);
(In reply to Martin Sebor from comment #2) > Another test case: > > $ cat f.c && gcc -O2 -S -Wall -Wextra f.c > int f (int i) > { > const char * p = __builtin_strchr (i ? "123" : "456", '2'); > return __builtin_strlen (p); > } > > The strlen argument is a phi with a null operand so that should make it easy > to detect: > > # prephitmp_11 = PHI <_10(3), 0B(2)> > _1 = __builtin_strlen (prephitmp_11); OK, this second testcase is different enough, so I guess this bug can stay separate
No improvement in GCC 10 or 11 (trunk).