[pushed] analyzer: fix ICE on infoleak with poisoned size
Checks
Commit Message
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
@@ -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
new file mode 100644
@@ -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);
+}
new file mode 100644
@@ -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'" } */
+}
@@ -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 \