diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc index 67c90b7fce4..e85a19647f7 100644 --- a/gcc/analyzer/store.cc +++ b/gcc/analyzer/store.cc @@ -1759,7 +1759,16 @@ binding_cluster::maybe_get_compound_binding (store_manager *mgr, else default_sval = sval_mgr->get_or_create_initial_value (reg); const binding_key *default_key = binding_key::make (mgr, reg); - default_map.put (default_key, default_sval); + + /* Express the bit-range of the default key for REG relative to REG, + rather than to the base region. */ + const concrete_binding *concrete_default_key + = default_key->dyn_cast_concrete_binding (); + if (!concrete_default_key) + return nullptr; + const concrete_binding *default_key_relative_to_reg + = mgr->get_concrete_binding (0, concrete_default_key->get_size_in_bits ()); + default_map.put (default_key_relative_to_reg, default_sval); for (map_t::iterator iter = m_map.begin (); iter != m_map.end (); ++iter) { diff --git a/gcc/testsuite/c-c++-common/analyzer/compound-assignment-5.c b/gcc/testsuite/c-c++-common/analyzer/compound-assignment-5.c index 3ce2b72c8ff..08f10606d91 100644 --- a/gcc/testsuite/c-c++-common/analyzer/compound-assignment-5.c +++ b/gcc/testsuite/c-c++-common/analyzer/compound-assignment-5.c @@ -48,9 +48,8 @@ void test_3 (void) glob_arr3[7] = arr[3]; // or should the uninit warning be here? - __analyzer_eval (glob_arr3[7].x); /* { dg-warning "uninitialized" "uninit" { xfail *-*-* } } */ - /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */ __analyzer_eval (glob_arr3[7].y == 6); /* { dg-warning "TRUE" } */ + __analyzer_eval (glob_arr3[7].x); /* { dg-warning "uninitialized" "uninit" } */ } /* Symbolic bindings: copying from one array to another. */ diff --git a/gcc/testsuite/c-c++-common/analyzer/compound-assignment-pr112969.c b/gcc/testsuite/c-c++-common/analyzer/compound-assignment-pr112969.c new file mode 100644 index 00000000000..4bc037cb7cf --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/compound-assignment-pr112969.c @@ -0,0 +1,35 @@ +/* Reduced from -Wanalyzer-exposure-through-uninit-copy false positives + seen in Linux kernel in drivers/net/ethernet/intel/ice/ice_ptp.c */ + +#include "analyzer-decls.h" + +/* { dg-do compile } */ + +struct hwtstamp_config +{ + int flags; + int tx_type; + int rx_filter; +}; + +struct ice_ptp +{ + long placeholder; + struct hwtstamp_config tstamp_config; +}; + +struct ice_pf +{ + struct ice_ptp ptp; +}; + +void +ice_ptp_set_ts_config(struct ice_pf* pf) +{ + struct hwtstamp_config config; + pf->ptp.tstamp_config.tx_type = 1; + pf->ptp.tstamp_config.rx_filter = 2; + config = pf->ptp.tstamp_config; + __analyzer_eval (config.flags == pf->ptp.tstamp_config.flags); /* { dg-warning "TRUE" } */ + /* { dg-bogus "use of uninitialized value 'config.flags'" "PR analyzer/112969" { target *-*-* } .-1 } */ +} diff --git a/gcc/testsuite/gcc.dg/plugin/infoleak-pr112969.c b/gcc/testsuite/gcc.dg/plugin/infoleak-pr112969.c new file mode 100644 index 00000000000..e78fe365975 --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/infoleak-pr112969.c @@ -0,0 +1,52 @@ +/* Reduced from -Wanalyzer-exposure-through-uninit-copy false positives + seen in Linux kernel in drivers/net/ethernet/intel/ice/ice_ptp.c */ + +/* { dg-do compile } */ +/* { dg-options "-fanalyzer" } */ +/* { dg-require-effective-target analyzer } */ + +extern unsigned long +copy_from_user(void* to, const void* from, unsigned long n); + +extern unsigned long +copy_to_user(void* to, const void* from, unsigned long n); + +struct ifreq +{ + union + { + void* ifru_data; + } ifr_ifru; +}; + +struct hwtstamp_config +{ + int flags; + int tx_type; + int rx_filter; +}; + +struct ice_ptp +{ + long placeholder; + struct hwtstamp_config tstamp_config; +}; + +struct ice_pf +{ + struct ice_ptp ptp; +}; +int +ice_ptp_set_ts_config(struct ice_pf* pf, struct ifreq* ifr) +{ + struct hwtstamp_config config; + int err; + if (copy_from_user(&config, ifr->ifr_ifru.ifru_data, sizeof(config))) + return -14; + pf->ptp.tstamp_config.tx_type = 0; + pf->ptp.tstamp_config.rx_filter = 0; + config = pf->ptp.tstamp_config; + if (copy_to_user(ifr->ifr_ifru.ifru_data, &config, sizeof(config))) /* { dg-bogus "-Wanalyzer-exposure-through-uninit-copy" "PR analyzer/112969" } */ + return -14; + return 0; +} diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp index 8141cc2aa46..c26dda1f324 100644 --- a/gcc/testsuite/gcc.dg/plugin/plugin.exp +++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp @@ -150,6 +150,7 @@ set plugin_test_list [list \ infoleak-CVE-2017-18550-1.c \ infoleak-antipatterns-1.c \ infoleak-fixit-1.c \ + infoleak-pr112969.c \ infoleak-uninit-size-1.c \ infoleak-uninit-size-2.c \ infoleak-net-ethtool-ioctl.c \