https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98281
Bug ID: 98281 Summary: - -Wformat-truncation false positive due to excessive integer range Product: gcc Version: 10.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: ishikawa at yk dot rim.or.jp Target Milestone: --- Created attachment 49763 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49763&action=edit Code that triggered the error. Actually there was bug 94021 but that was for 9.2.1, and this is with 10.2.0, and the error is subtly different. So I am submitting this bug entry. Compared with the example in bug 94021 comment 4, the bug is slightly different. gcc --version gcc (Debian 10.2.0-19) 10.2.0 The source code is from mozilla's thunderbird. The error I observed is: In file included from Unified_c_libical_src_libical1.c:20: /NEW-SSD/NREF-COMM-CENTRAL/mozilla/comm/calendar/libical/src/libical/icalvalue.c: In function ‘icalvalue_utcoffset_as_ical_string_r’: /NEW-SSD/NREF-COMM-CENTRAL/mozilla/comm/calendar/libical/src/libical/icalvalue.c:897:20: error: ‘%02d’ directive output may be truncated writing between 2 and 6 bytes into a region of size between 2 and 4 [-Werror=format-truncation=] 897 | snprintf(str,9,"%c%02d%02d%02d",sign,abs(h),abs(m),abs(s)); | ^~~~~~~~~~~~~~~~ /NEW-SSD/NREF-COMM-CENTRAL/mozilla/comm/calendar/libical/src/libical/icalvalue.c:897:20: note: directive argument in the range [1, 338339] In file included from /usr/include/stdio.h:867, from /NEW-SSD/moz-obj-dir/objdir-tb3/dist/system_wrappers/stdio.h:3, from /NEW-SSD/NREF-COMM-CENTRAL/mozilla/comm/calendar/libical/src/libical/icaltimezone.c:34, from Unified_c_libical_src_libical1.c:2: /usr/include/x86_64-linux-gnu/bits/stdio2.h:67:10: note: ‘__builtin___snprintf_chk’ output between 8 and 14 bytes into a destination of size 9 67 | return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 68 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This does not make sense, since the value(s) ought to be constrained to fit into the final string. Also, I am not sure what this [1, 338339] is valid for WHICH variable. The code snippet from the affected function: Sorry, I could no reproduce the problem with a simplified source code. There must be an optimization issue involved. --- begin quote static char* icalvalue_utcoffset_as_ical_string_r(const icalvalue* value) { int data,h,m,s; char sign; char* str; if(!((value!=0))) { icalerror_set_errno(ICAL_BADARG_ERROR); return 0;}; str = (char*)icalmemory_new_buffer(9); data = icalvalue_get_utcoffset(value); if (abs(data) == data){ sign = '+'; } else { sign = '-'; } if (data >= 3600 * 24 || data <= - 3600 * 24) { snprintf(str,9,"+0000"); return str; } if(data < 0) data = - data; h = data/3600; m = (data - (h*3600))/ 60; s = (data - (h*3600) - (m*60)); if (s > 0) snprintf(str,9,"%c%02d%02d%02d",sign,abs(h),abs(m),abs(s)); else snprintf(str,9,"%c%02d%02d",sign,abs(h),abs(m)); return str; } --- end quote The intention is that the following conditions hold before snprintf is invoked. h is in [0, 24) m is in [0, 60) s is in [0, 60) I wonder where "[1, 338339]" comes from. Yes, I know the original code does something funny like abs(data) == data, The preprocessed source file is in the attachment. The command script to compile the source file is in another comment.