public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-6323] analyzer: make use of may_be_aliased in alias detection [PR103546]
@ 2022-01-06 22:43 David Malcolm
  0 siblings, 0 replies; only message in thread
From: David Malcolm @ 2022-01-06 22:43 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:d564a83d14252d7db01381f71900b7a68357803b

commit r12-6323-gd564a83d14252d7db01381f71900b7a68357803b
Author: David Malcolm <dmalcolm@redhat.com>
Date:   Thu Jan 6 11:39:54 2022 -0500

    analyzer: make use of may_be_aliased in alias detection [PR103546]
    
    Whilst debugging PR analyzer/103546 (false +ve in flex-generated lexers)
    I noticed that the analyzer was considering that writes through symbolic
    pointers could be treated as clobbering static globals such as:
    
       static YY_BUFFER_STATE * yy_buffer_stack = NULL;
    
    even for such variables that never have their address taken.
    
    This patch fixes this issue at least, so that the analyzer can preserve
    knowledge of such globals on code paths with writes through symbolic
    pointers.
    
    It does not fix the false +ve in the lexer code.
    
    gcc/analyzer/ChangeLog:
            PR analyzer/103546
            * store.cc (store::eval_alias_1): Refactor handling of decl
            regions, adding a test for may_be_aliased, rejecting those for
            which it returns false.
    
    gcc/testsuite/ChangeLog:
            PR analyzer/103546
            * gcc.dg/analyzer/aliasing-3.c: New test.
    
    Signed-off-by: David Malcolm <dmalcolm@redhat.com>

Diff:
---
 gcc/analyzer/store.cc                      | 18 ++++---
 gcc/testsuite/gcc.dg/analyzer/aliasing-3.c | 75 ++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+), 7 deletions(-)

diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc
index 8729aa8dab6..3f91b6107a9 100644
--- a/gcc/analyzer/store.cc
+++ b/gcc/analyzer/store.cc
@@ -2456,13 +2456,17 @@ store::eval_alias_1 (const region *base_reg_a,
       = base_reg_a->dyn_cast_symbolic_region ())
     {
       const svalue *sval_a = sym_reg_a->get_pointer ();
-      if (sval_a->get_kind () == SK_INITIAL)
-	if (tree decl_b = base_reg_b->maybe_get_decl ())
-	  if (!is_global_var (decl_b))
-	    {
-	      /* The initial value of a pointer can't point to a local.  */
-	      return tristate::TS_FALSE;
-	    }
+      if (tree decl_b = base_reg_b->maybe_get_decl ())
+	{
+	  if (!may_be_aliased (decl_b))
+	    return tristate::TS_FALSE;
+	  if (sval_a->get_kind () == SK_INITIAL)
+	    if (!is_global_var (decl_b))
+	      {
+		/* The initial value of a pointer can't point to a local.  */
+		return tristate::TS_FALSE;
+	      }
+	}
       if (sval_a->get_kind () == SK_INITIAL
 	  && base_reg_b->get_kind () == RK_HEAP_ALLOCATED)
 	{
diff --git a/gcc/testsuite/gcc.dg/analyzer/aliasing-3.c b/gcc/testsuite/gcc.dg/analyzer/aliasing-3.c
new file mode 100644
index 00000000000..003077ad5c1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/aliasing-3.c
@@ -0,0 +1,75 @@
+#include "analyzer-decls.h"
+
+#define NULL ((void *)0)
+
+struct s1
+{
+  int f1;
+};
+
+static struct s1 *p1_glob = NULL;
+
+void test_1 (struct s1 **pp1, struct s1 *p1_parm)
+{
+  struct s1 *init_p1_glob = p1_glob;
+
+  __analyzer_eval (p1_glob == init_p1_glob); /* { dg-warning "TRUE" } */
+
+  if (!p1_glob)
+    return;
+
+  __analyzer_eval (p1_glob == init_p1_glob); /* { dg-warning "TRUE" } */
+  __analyzer_eval (p1_glob != NULL); /* { dg-warning "TRUE" } */
+
+  *pp1 = p1_parm;
+
+  /* The write through *pp1 can't have changed p1_glob, because
+     we never take a pointer to p1_glob (and it's static to this TU).  */
+  __analyzer_eval (p1_glob == init_p1_glob); /* { dg-warning "TRUE" } */
+  __analyzer_eval (p1_glob != NULL); /* { dg-warning "TRUE" } */
+}
+
+struct s2
+{
+  int f1;
+};
+
+static struct s2 *p2_glob = NULL;
+
+void test_2 (struct s2 **pp2, struct s2 *p2_parm)
+{
+  /* Ensure that p2_glob is modified.  */
+  p2_glob = __builtin_malloc (sizeof (struct s2));
+  if (!p2_glob)
+    return;
+
+  __analyzer_eval (p2_glob != NULL); /* { dg-warning "TRUE" } */
+
+  *pp2 = p2_parm;
+
+  /* The write through *pp2 can't have changed p2_glob, because
+     we never take a pointer to p2_glob (and it's static to this TU).  */
+  __analyzer_eval (p2_glob != NULL); /* { dg-warning "TRUE" } */
+}
+
+struct s3
+{
+  int f1;
+};
+
+struct s3 *p3_glob = NULL;
+
+void test_3 (struct s3 **pp3, struct s3 *p3_parm)
+{
+  p3_glob = __builtin_malloc (sizeof (struct s3));
+  if (!p3_glob)
+    return;
+
+  __analyzer_eval (p3_glob != NULL); /* { dg-warning "TRUE" } */
+
+  *pp3 = p3_parm;
+
+  /* The write through *pp3 could have changed p3_glob, because
+     another TU could take a pointer to p3_glob.  */
+  __analyzer_eval (p3_glob != NULL); /* { dg-warning "UNKNOWN" } */
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-01-06 22:43 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-06 22:43 [gcc r12-6323] analyzer: make use of may_be_aliased in alias detection [PR103546] David Malcolm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).