Hi everyone, I'm currently working on new warnings for gcc's -fanalyzer. I've implemented a version of Wrestrict inside the analyzer, using its region model to detect more cases of overlapping buffers in memcpy and aliases to restrict-qualified parameters. While testing my new warning, I got one result on the gnu coreutils touch.c file [1]. See the output below:
../src/touch.c: In function 'get_reldate': ../src/touch.c:115:9: warning: argument passed to 'restrict'-qualified parameter aliases with another argument [-Wanalyzer-restrict] 115 | if (! parse_datetime (result, flex_date, now)) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'main': events 1-8 | | 261 | main (int argc, char **argv) | | ^~~~ | | | | | (1) entry to 'mai |...... | 279 | while ((c = getopt_long (argc, argv, "acd:fhmr:t:", longopts, NULL)) != -1) | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (2) following 'true' branch (when 'c != -1')... | 280 | { | 281 | switch (c) | | ~~~~~~ | | | | | (3) ...to here |...... | 344 | if (use_ref) | | ~ | | | | | (4) following 'true' branch... |...... | 349 | if (no_dereference ? lstat (ref_file, &ref_stats) | | ~ ~ | | | | | | | (5) ...to here | | (6) following 'false' branch... |...... | 353 | newtime[0] = get_stat_atime (&ref_stats); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (7) ...to here |...... | 356 | if (flex_date) | | ~ | | | | | (8) following 'true' branch (when 'flex_date' is non-NULL)... | 'main': events 9-12 | | 358 | if (change_times & CH_ATIME) | | ~ ^ | | | | | | | (9) ...to here | | (10) following 'true' branch... | 359 | get_reldate (&newtime[0], flex_date, &newtime[0]); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (11) ...to here | | (12) calling 'get_reldate' from 'main' | +--> 'get_reldate': events 13-14 | | 112 | get_reldate (struct timespec *result, | | ^~~~~~~~~~~ | | | | | (13) entry to 'get_reldate' |...... | 115 | if (! parse_datetime (result, flex_date, now)) | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (14) 'result' and 'now' point to the same memory location | In file included from ../src/touch.c:31: ../lib/parse-datetime.h:22:6: note: declared here 22 | bool parse_datetime (struct timespec *restrict, | ^~~~~~~~~~~~~~ My (and David's) understanding of the restrict keyword is that any read or write to the memory location must occur through the restrict-qualified parameter. In the case of 'parse_datetime' from gnulib, 'result' is an output parameter, thus the function might write to 'result' before reading 'now' [2]. I'm a bit unsure, due to the bulky definition of restrict, whether this is actually a true positive and does express what gnulib intended with the change. So I'd like to hear your opinions on this. - Tim [1] https://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=blob;f=src/touch.c;h=21c247d0b10eedb615bf044ba6ea08520f3d0546;hb=HEAD#l359 [2] The function does write 'result' after the last read of 'now' and does not use restrict in the implementation, so it should be safe but is still somewhat undefined behavior?