analyzer: don't assume extern const vars are zero-initialized [PR97568]
authorDavid Malcolm <dmalcolm@redhat.com>
Tue, 27 Oct 2020 13:54:25 +0000 (09:54 -0400)
committerDavid Malcolm <dmalcolm@redhat.com>
Tue, 27 Oct 2020 13:56:25 +0000 (09:56 -0400)
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.

gcc/analyzer/region-model.cc
gcc/analyzer/region.cc
gcc/testsuite/gcc.dg/analyzer/pr97568.c [new file with mode: 0644]

index 9050b4424f8d8af5dcb84af256083dfac387fd90..e5f027b6059b5caca22de385bc35404e70a3c9a1 100644 (file)
@@ -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
index 3a88a5fbc67de0c0ac7ef1bf32f3e70f65788a50..c43fb782b7d34d0d72616fdd8ad1d6187c8ba21b 100644 (file)
@@ -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 (file)
index 0000000..22d574b
--- /dev/null
@@ -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];
+}