Created attachment 48360 [details] testcase Test with: gcc-10 (Debian 10-20200418-1) 10.0.1 20200418 (experimental) [master revision 27c171775ab:4c277008be0:c5bac7d127f288fd2f8a1f15c3f30da5903141c6] When I want to compile GNU MPFR with -fanalyzer, the compilation of atan.c fails on what appears to be a false positive. I've managed to reduce the 6000-line preprocessed code to code with fewer than 300 lines (attached bug.i file). More specifically, I've removed * blank lines and comments; * unused declarations/definitions; * code that could have an influence only after the "error"; * code testing and handling special cases. I order to see where the issue could come from, I've added 2 lines * "((y)->_mpfr_d)[0] = 0;" at the beginning of mpfr_atan_aux; * "((tmp2)->_mpfr_d)[0] = 0;" just before the call to mpfr_atan_aux. Without these 2 lines, "gcc-10 -c -fanalyzer bug.i" gives: bug.i: In function ‘set_table’: bug.i:145:9: warning: use of uninitialized value ‘yp’ [CWE-457] [-Wanalyzer-use-of-uninitialized-value] 145 | yp[0] &= ~(((void) 0), sh == | ^~ where yp is set with mp_limb_t *yp = ((y)->_mpfr_d); So I suppose that the analyzer complains that (y)->_mpfr_d is uninitialized. This comes from mpfr_atan_aux, and "((y)->_mpfr_d)[0] = 0;" at the beginning of this function should trigger the same error. If I add this line, I get in a consistent way: bug.i: In function ‘mpfr_atan_aux’: bug.i:154:19: warning: use of uninitialized value ‘<unknown>’ [CWE-457] [-Wanalyzer-use-of-uninitialized-value] 154 | ((y)->_mpfr_d)[0] = 0; | ~~~~~~~~~~~~~~~~~~^~~ This mpfr_atan_aux function is called at only one place: mpfr_atan_aux (tmp2, ukz, twopoweri, n0 - i, tabz); So I added "((tmp2)->_mpfr_d)[0] = 0;" just before this call. I thought that I would get an error on this, but I still get an error only on "((y)->_mpfr_d)[0] = 0;" in mpfr_atan_aux. If I remove this line (just keeping the one before the call to mpfr_atan_aux), I get the error in set_table only, just like in the first test. Now, this appears to be a false positif since (tmp2)->_mpfr_d was initialized earlier. I could probably simplify the code even further, focusing on (tmp2)->_mpfr_d only.
Here's the corresponding simple testcase: typedef struct { int *a; } S; int *f (void); static void g (S *x) { int *p = x->a; p[0] = 0; } void h (void) { S x[1]; x->a = f (); g (x); } $ gcc-10 -c -fanalyzer bug.i bug.i: In function ‘g’: bug.i:6:8: warning: use of uninitialized value ‘p’ [CWE-457] [-Wanalyzer-use-of-uninitialized-value] 6 | p[0] = 0; | ~~~~~^~~ ‘h’: events 1-2 | | 8 | void h (void) | | ^ | | | | | (1) entry to ‘h’ |...... | 12 | g (x); | | ~~~~~ | | | | | (2) calling ‘g’ from ‘h’ | +--> ‘g’: events 3-4 | | 3 | static void g (S *x) | | ^ | | | | | (3) entry to ‘g’ |...... | 6 | p[0] = 0; | | ~~~~~~~~ | | | | | (4) use of uninitialized value ‘p’ here |
The master branch has been updated by David Malcolm <dmalcolm@gcc.gnu.org>: https://gcc.gnu.org/g:78b9783774bfd3540f38f5b1e3c7fc9f719653d7 commit r10-8012-g78b9783774bfd3540f38f5b1e3c7fc9f719653d7 Author: David Malcolm <dmalcolm@redhat.com> Date: Thu Apr 23 21:31:22 2020 -0400 analyzer: remove -Wanalyzer-use-of-uninitialized-value for GCC 10 From what I can tell -Wanalyzer-use-of-uninitialized-value has not yet found a true diagnostic in real-world code, and seems to be particularly susceptible to false positives. These relate to bugs in the region_model code. For GCC 10 it seems best to remove this warning, which this patch does. Internally it also removes POISON_KIND_UNINIT. I'm working on a rewrite of the region_model code for GCC 11 that I hope will fix these issues, and allow this warning to be reintroduced. gcc/analyzer/ChangeLog: PR analyzer/94447 PR analyzer/94639 PR analyzer/94732 PR analyzer/94754 * analyzer.opt (Wanalyzer-use-of-uninitialized-value): Delete. * program-state.cc (selftest::test_program_state_dumping): Update expected dump result for removal of "uninit". * region-model.cc (poison_kind_to_str): Delete POISON_KIND_UNINIT case. (root_region::ensure_stack_region): Initialize stack with null svalue_id rather than with a typeless POISON_KIND_UNINIT value. (root_region::ensure_heap_region): Likewise for the heap. (region_model::dump_summary_of_rep_path_vars): Remove summarization of uninit values. (region_model::validate): Remove check that the stack has a POISON_KIND_UNINIT value. (poisoned_value_diagnostic::emit): Remove POISON_KIND_UNINIT case. (poisoned_value_diagnostic::describe_final_event): Likewise. (selftest::test_dump): Update expected dump result for removal of "uninit". (selftest::test_svalue_equality): Remove "uninit" and "freed". * region-model.h (enum poison_kind): Remove POISON_KIND_UNINIT. gcc/ChangeLog: PR analyzer/94447 PR analyzer/94639 PR analyzer/94732 PR analyzer/94754 * doc/invoke.texi (Static Analyzer Options): Remove -Wanalyzer-use-of-uninitialized-value. (-Wno-analyzer-use-of-uninitialized-value): Remove item. gcc/testsuite/ChangeLog: PR analyzer/94447 PR analyzer/94639 PR analyzer/94732 PR analyzer/94754 * gcc.dg/analyzer/data-model-1.c: Mark "use of uninitialized value" warnings as xfail for now. * gcc.dg/analyzer/data-model-5b.c: Remove uninitialized warning. * gcc.dg/analyzer/pr94099.c: Mark "uninitialized" warning as xfail for now. * gcc.dg/analyzer/pr94447.c: New test. * gcc.dg/analyzer/pr94639.c: New test. * gcc.dg/analyzer/pr94732.c: New test. * gcc.dg/analyzer/pr94754.c: New test. * gcc.dg/analyzer/zlib-6.c: Mark "uninitialized" warning as xfail for now.
Should be fixed by r10-8012-g78b9783774bfd3540f38f5b1e3c7fc9f719653d7.