Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Pushed to trunk as r14-6348-g08262e78209ed4.
gcc/analyzer/ChangeLog: * region-model.cc (contains_uninit_p): Only check for svalues that the infoleak warning can handle. gcc/testsuite/ChangeLog: * gcc.dg/plugin/infoleak-uninit-size-1.c: New test. * gcc.dg/plugin/infoleak-uninit-size-2.c: New test. * gcc.dg/plugin/plugin.exp: Add the new tests. --- gcc/analyzer/region-model.cc | 37 ++++++++++++------- .../gcc.dg/plugin/infoleak-uninit-size-1.c | 20 ++++++++++ .../gcc.dg/plugin/infoleak-uninit-size-2.c | 20 ++++++++++ gcc/testsuite/gcc.dg/plugin/plugin.exp | 2 + 4 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/plugin/infoleak-uninit-size-1.c create mode 100644 gcc/testsuite/gcc.dg/plugin/infoleak-uninit-size-2.c diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index 2157ad2578b..9b970d7a3e3 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -6557,22 +6557,33 @@ private: static bool contains_uninit_p (const svalue *sval) { - struct uninit_finder : public visitor - { - public: - uninit_finder () : m_found_uninit (false) {} - void visit_poisoned_svalue (const poisoned_svalue *sval) + switch (sval->get_kind ()) { - if (sval->get_poison_kind () == POISON_KIND_UNINIT) - m_found_uninit = true; - } - bool m_found_uninit; - }; + default: + return false; + case SK_POISONED: + { + const poisoned_svalue *psval + = as_a <const poisoned_svalue *> (sval); + return psval->get_poison_kind () == POISON_KIND_UNINIT; + } + case SK_COMPOUND: + { + const compound_svalue *compound_sval + = as_a <const compound_svalue *> (sval); - uninit_finder v; - sval->accept (&v); + for (auto iter : *compound_sval) + { + const svalue *sval = iter.second; + if (const poisoned_svalue *psval + = sval->dyn_cast_poisoned_svalue ()) + if (psval->get_poison_kind () == POISON_KIND_UNINIT) + return true; + } - return v.m_found_uninit; + return false; + } + } } /* Function for use by plugins when simulating writing data through a diff --git a/gcc/testsuite/gcc.dg/plugin/infoleak-uninit-size-1.c b/gcc/testsuite/gcc.dg/plugin/infoleak-uninit-size-1.c new file mode 100644 index 00000000000..7466112fe14 --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/infoleak-uninit-size-1.c @@ -0,0 +1,20 @@ +/* Reduced from infoleak ICE seen on Linux kernel with + -Wno-analyzer-use-of-uninitialized-value. + + Verify that we don't ICE when complaining about an infoleak + when the size is uninitialized. */ + +/* { dg-do compile } */ +/* { dg-options "-fanalyzer -Wno-analyzer-use-of-uninitialized-value" } */ +/* { dg-require-effective-target analyzer } */ + +extern unsigned long +copy_to_user(void* to, const void* from, unsigned long n); + +unsigned long +test_uninit_size (void *to, void *from) +{ + unsigned long n; + char buf[16]; + return copy_to_user(to, from, n); +} diff --git a/gcc/testsuite/gcc.dg/plugin/infoleak-uninit-size-2.c b/gcc/testsuite/gcc.dg/plugin/infoleak-uninit-size-2.c new file mode 100644 index 00000000000..a8a383f4b2d --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/infoleak-uninit-size-2.c @@ -0,0 +1,20 @@ +/* Reduced from infoleak ICE seen on Linux kernel with + -Wno-analyzer-use-of-uninitialized-value. + + Verify that we complain about the uninit value when + -Wno-analyzer-use-of-uninitialized-value isn't supplied. */ + +/* { dg-do compile } */ +/* { dg-options "-fanalyzer" } */ +/* { dg-require-effective-target analyzer } */ + +extern unsigned long +copy_to_user(void* to, const void* from, unsigned long n); + +unsigned long +test_uninit_size (void *to, void *from) +{ + unsigned long n; + char buf[16]; + return copy_to_user(to, from, n); /* { dg-warning "use of uninitialized value 'n'" } */ +} diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp index f0b4bb7a051..d6cccb269df 100644 --- a/gcc/testsuite/gcc.dg/plugin/plugin.exp +++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp @@ -150,6 +150,8 @@ set plugin_test_list [list \ infoleak-CVE-2017-18550-1.c \ infoleak-antipatterns-1.c \ infoleak-fixit-1.c \ + infoleak-uninit-size-1.c \ + infoleak-uninit-size-2.c \ infoleak-net-ethtool-ioctl.c \ infoleak-vfio_iommu_type1.c \ taint-CVE-2011-0521-1-fixed.c \ -- 2.26.3