aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2020-10-27 09:54:25 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2020-10-27 09:56:25 -0400
commit16ad9ae85bb5b9acf80f9d1cf2be5a989ef7ba49 (patch)
tree8e134356ff4d967b99e1cde3c99be3c795151454
parent942086bf73ee2ba6cfd7fdacc552940048437a6e (diff)
downloadgcc-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.
-rw-r--r--gcc/analyzer/region-model.cc3
-rw-r--r--gcc/analyzer/region.cc5
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr97568.c29
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];
+}