diff options
author | David Malcolm <dmalcolm@redhat.com> | 2020-10-27 09:54:25 -0400 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2020-10-27 09:56:25 -0400 |
commit | 16ad9ae85bb5b9acf80f9d1cf2be5a989ef7ba49 (patch) | |
tree | 8e134356ff4d967b99e1cde3c99be3c795151454 /gcc | |
parent | 942086bf73ee2ba6cfd7fdacc552940048437a6e (diff) | |
download | gcc-16ad9ae85bb5b9acf80f9d1cf2be5a989ef7ba49.zip gcc-16ad9ae85bb5b9acf80f9d1cf2be5a989ef7ba49.tar.gz gcc-16ad9ae85bb5b9acf80f9d1cf2be5a989ef7ba49.tar.bz2 |
analyzer: don't assume extern const vars are zero-initialized [PR97568]
gcc/analyzer/ChangeLog:
PR analyzer/97568
* region-model.cc (region_model::get_initial_value_for_global):
Move check that !DECL_EXTERNAL from here to...
* region.cc (decl_region::get_svalue_for_initializer): ...here,
using it to reject zero initialization.
gcc/testsuite/ChangeLog:
PR analyzer/97568
* gcc.dg/analyzer/pr97568.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/analyzer/region-model.cc | 3 | ||||
-rw-r--r-- | gcc/analyzer/region.cc | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/analyzer/pr97568.c | 29 |
3 files changed, 35 insertions, 2 deletions
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index 9050b44..e5f027b 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -1342,8 +1342,7 @@ region_model::get_initial_value_for_global (const region *reg) const global decl defined in this TU that hasn't been touched yet, then the initial value of REG can be taken from the initialization value of the decl. */ - if ((called_from_main_p () && !DECL_EXTERNAL (decl)) - || TREE_READONLY (decl)) + if (called_from_main_p () || TREE_READONLY (decl)) { /* Attempt to get the initializer value for base_reg. */ if (const svalue *base_reg_init diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc index 3a88a5f..c43fb78 100644 --- a/gcc/analyzer/region.cc +++ b/gcc/analyzer/region.cc @@ -938,6 +938,11 @@ decl_region::get_svalue_for_initializer (region_model_manager *mgr) const tree init = DECL_INITIAL (m_decl); if (!init) { + /* If we have an "extern" decl then there may be an initializer in + another TU. */ + if (DECL_EXTERNAL (m_decl)) + return NULL; + /* Implicit initialization to zero; use a compound_svalue for it. Doing so requires that we have a concrete binding for this region, which can fail if we have a region with unknown size diff --git a/gcc/testsuite/gcc.dg/analyzer/pr97568.c b/gcc/testsuite/gcc.dg/analyzer/pr97568.c new file mode 100644 index 0000000..22d574b --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr97568.c @@ -0,0 +1,29 @@ +#include "analyzer-decls.h" + +#define NULL ((void *)0) + +extern int *const p1; + +int *const p2; + +int v3; +extern int *const p3 = &v3; /* { dg-warning "'p3' initialized and declared 'extern'" } */ + +int v4; +int *const p4 = &v4; + +int main (void) +{ + __analyzer_describe (0, p1); /* { dg-message "INIT_VAL\\(p1\\)" } */ + __analyzer_eval (p1 == NULL); /* { dg-message "UNKNOWN" } */ + + __analyzer_eval (p2 == NULL); /* { dg-message "TRUE" } */ + + __analyzer_describe (0, p3); /* { dg-message "&v3" } */ + __analyzer_eval (p3 == NULL); /* { dg-message "FALSE" } */ + + __analyzer_describe (0, p4); /* { dg-message "&v4" } */ + __analyzer_eval (p4 == NULL); /* { dg-message "FALSE" } */ + + return p1[0]; +} |