[gcc(refs/vendors/redhat/heads/gcc-10-branch)] analyzer: handle NOP_EXPR in get_lvalue [PR94099, PR94105]

Jakub Jelinek jakub@gcc.gnu.org
Wed Mar 25 09:56:50 GMT 2020


https://gcc.gnu.org/g:5c048755ec98645f8436b630df3f9294ca9cbc2a

commit 5c048755ec98645f8436b630df3f9294ca9cbc2a
Author: David Malcolm <dmalcolm@redhat.com>
Date:   Tue Mar 10 19:03:37 2020 -0400

    analyzer: handle NOP_EXPR in get_lvalue [PR94099,PR94105]
    
    PR analyzer/94099 and PR analyzer/94105 both report ICEs relating to
    calling region_model::get_lvalue on a NOP_EXPR.
    
    PR analyzer/94099's ICE happens when generating a checker_path when
    encountering an unhandled tree code (NOP_EXPR) in get_lvalue with a
    NULL context (from for_each_state_change).
    
    PR analyzer/94105 ICE happens when handling an ARRAY_REF where the
    first operand is a NOP_EXPR: the unhandled tree code gives us
    a symbolic_region, but the case for ARRAY_REF assumes we have an
    array_region.
    
    This patch fixes the ICEs by handling NOP_EXPR within
    region_model::get_lvalue, and bulletproofs both of the above sources
    of failure.
    
    gcc/analyzer/ChangeLog:
            PR analyzer/94099
            PR analyzer/94105
            * diagnostic-manager.cc (for_each_state_change): Bulletproof
            against errors in get_rvalue by passing a
            tentative_region_model_context and rejecting if there's an error.
            * region-model.cc (region_model::get_lvalue_1): When handling
            ARRAY_REF, handle results of error-handling.  Handle NOP_EXPR.
    
    gcc/testsuite/ChangeLog:
            PR analyzer/94099
            PR analyzer/94105
            * gcc.dg/analyzer/pr94099.c: New test.
            * gcc.dg/analyzer/pr94105.c: New test.

Diff:
---
 gcc/analyzer/ChangeLog                  | 10 ++++++++++
 gcc/analyzer/diagnostic-manager.cc      |  5 +++--
 gcc/analyzer/region-model.cc            | 14 +++++++++++++-
 gcc/testsuite/ChangeLog                 |  7 +++++++
 gcc/testsuite/gcc.dg/analyzer/pr94099.c | 27 +++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/analyzer/pr94105.c |  3 +++
 6 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index e51a1cdf56a..8fc5dc4448f 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,3 +1,13 @@
+2020-03-13  David Malcolm  <dmalcolm@redhat.com>
+
+	PR analyzer/94099
+	PR analyzer/94105
+	* diagnostic-manager.cc (for_each_state_change): Bulletproof
+	against errors in get_rvalue by passing a
+	tentative_region_model_context and rejecting if there's an error.
+	* region-model.cc (region_model::get_lvalue_1): When handling
+	ARRAY_REF, handle results of error-handling.  Handle NOP_EXPR.
+
 2020-03-06  David Malcolm  <dmalcolm@redhat.com>
 
 	* analyzer.h (class array_region): New forward decl.
diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc
index 1b2c3ce68fa..bea566da9fc 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -768,9 +768,10 @@ for_each_state_change (const program_state &src_state,
 	      if (dst_pv->m_stack_depth
 		  >= src_state.m_region_model->get_stack_depth ())
 		continue;
+	      tentative_region_model_context ctxt;
 	      svalue_id src_sid
-		= src_state.m_region_model->get_rvalue (*dst_pv, NULL);
-	      if (src_sid.null_p ())
+		= src_state.m_region_model->get_rvalue (*dst_pv, &ctxt);
+	      if (src_sid.null_p () || ctxt.had_errors_p ())
 		continue;
 	      state_machine::state_t src_sm_val = src_smap.get_state (src_sid);
 	      if (dst_sm_val != src_sm_val)
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 87980e7c8cd..45a190299ea 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -4749,7 +4749,18 @@ region_model::get_lvalue_1 (path_var pv, region_model_context *ctxt)
 
 	region_id array_rid = get_lvalue (array, ctxt);
 	svalue_id index_sid = get_rvalue (index, ctxt);
-	array_region *array_reg = get_region<array_region> (array_rid);
+	region *base_array_reg = get_region (array_rid);
+	array_region *array_reg  = base_array_reg->dyn_cast_array_region ();
+	if (!array_reg)
+	  {
+	    /* Normally, array_rid ought to refer to an array_region, since
+	       array's type will be ARRAY_TYPE.  However, if we have an
+	       unexpected tree code for array, we could have a
+	       symbolic_region here.  If so, we're in error-handling. */
+	    gcc_assert (base_array_reg->get_type () == NULL_TREE);
+	    return make_region_for_unexpected_tree_code (ctxt, expr,
+							 dump_location_t ());
+	  }
 	return array_reg->get_element (this, array_rid, index_sid, ctxt);
       }
       break;
@@ -4849,6 +4860,7 @@ region_model::get_lvalue_1 (path_var pv, region_model_context *ctxt)
       }
       break;
 
+    case NOP_EXPR:
     case VIEW_CONVERT_EXPR:
       {
 	tree obj = TREE_OPERAND (expr, 0);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 296ea8f0011..75d6041ba90 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2020-03-13  David Malcolm  <dmalcolm@redhat.com>
+
+	PR analyzer/94099
+	PR analyzer/94105
+	* gcc.dg/analyzer/pr94099.c: New test.
+	* gcc.dg/analyzer/pr94105.c: New test.
+
 2020-03-13  Vasee Vinayagamoorthy  <vaseeharan.vinayagamoorthy@arm.com>
 
 	* gcc.target/aarch64/advsimd-intrinsics/bfcvt-nosimd.c: Fix DejaGnu
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94099.c b/gcc/testsuite/gcc.dg/analyzer/pr94099.c
new file mode 100644
index 00000000000..0a34f561821
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr94099.c
@@ -0,0 +1,27 @@
+/* { dg-additional-options "-O1" } */
+
+struct cg {
+  int hk;
+  int *bg;
+};
+
+union vb {
+  struct cg gk;
+};
+
+void
+l3 (union vb *);
+
+void
+pl (void)
+{
+  union vb th = { 0, };
+  int sc;
+
+  for (sc = 0; sc < 1; ++sc)
+    {
+      th.gk.hk = 0;
+      th.gk.bg[sc] = 0; /* { dg-warning "uninitialized" } */
+      l3 (&th);
+    }
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94105.c b/gcc/testsuite/gcc.dg/analyzer/pr94105.c
new file mode 100644
index 00000000000..8220723bf6c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr94105.c
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+#include "../../c-c++-common/torture/pr58794-1.c"


More information about the Gcc-cvs mailing list