[gcc/devel/ranger] analyzer: fix ICE on failed casts [PR 93777]

Aldy Hernandez aldyh@gcc.gnu.org
Wed Jun 17 18:58:17 GMT 2020


https://gcc.gnu.org/g:4f40164a9322105012e9070eebd57ba80c69b873

commit 4f40164a9322105012e9070eebd57ba80c69b873
Author: David Malcolm <dmalcolm@redhat.com>
Date:   Mon Feb 17 17:37:52 2020 -0500

    analyzer: fix ICE on failed casts [PR 93777]
    
    PR analyzer/93777 reports ICEs in a Fortran and C++ case involving
    a cast of a NULL pointer to a REFERENCE_TYPE.
    
    In both cases the call to build_cast fails and returns a NULL type, but
    region_model::maybe_cast_1 asserts that a non-NULL type was returned.
    
    This patch fixes the ICEs by converting the assertion to a conditional.
    
    gcc/analyzer/ChangeLog:
            PR analyzer/93777
            * region-model.cc (region_model::maybe_cast_1): Replace assertion
            that build_cast returns non-NULL with a conditional, falling
            through to the logic which returns a new unknown value of the
            desired type if it fails.
    
    gcc/testsuite/ChangeLog:
            PR analyzer/93777
            * g++.dg/analyzer/pr93777.C: New test.
            * gfortran.dg/analyzer/pr93777.f90: New test.

Diff:
---
 gcc/analyzer/ChangeLog                         |  8 ++++++++
 gcc/analyzer/region-model.cc                   |  7 +++----
 gcc/testsuite/ChangeLog                        |  6 ++++++
 gcc/testsuite/g++.dg/analyzer/pr93777.C        |  1 +
 gcc/testsuite/gfortran.dg/analyzer/pr93777.f90 | 22 ++++++++++++++++++++++
 5 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index 05fb6144439..f4c620034dd 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,3 +1,11 @@
+2020-02-18  David Malcolm  <dmalcolm@redhat.com>
+
+	PR analyzer/93777
+	* region-model.cc (region_model::maybe_cast_1): Replace assertion
+	that build_cast returns non-NULL with a conditional, falling
+	through to the logic which returns a new unknown value of the
+	desired type if it fails.
+
 2020-02-18  David Malcolm  <dmalcolm@redhat.com>
 
 	PR analyzer/93778
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index c8ee031dc8f..d061552da37 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -5089,10 +5089,9 @@ region_model::maybe_cast_1 (tree dst_type, svalue_id sid)
   /* Attempt to cast constants.  */
   if (tree src_cst = sval->maybe_get_constant ())
     {
-      tree dst = build_cast (dst_type, src_cst);
-      gcc_assert (dst != NULL_TREE);
-      if (CONSTANT_CLASS_P (dst))
-	return get_or_create_constant_svalue (dst);
+      if (tree dst = build_cast (dst_type, src_cst))
+	if (CONSTANT_CLASS_P (dst))
+	  return get_or_create_constant_svalue (dst);
     }
 
   /* Otherwise, return a new unknown value.  */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d171d4ee618..55e2e6eaa43 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2020-02-18  David Malcolm  <dmalcolm@redhat.com>
+
+	PR analyzer/93777
+	* g++.dg/analyzer/pr93777.C: New test.
+	* gfortran.dg/analyzer/pr93777.f90: New test.
+
 2020-02-18  David Malcolm  <dmalcolm@redhat.com>
 
 	PR analyzer/93778
diff --git a/gcc/testsuite/g++.dg/analyzer/pr93777.C b/gcc/testsuite/g++.dg/analyzer/pr93777.C
new file mode 100644
index 00000000000..e94e75f5e83
--- /dev/null
+++ b/gcc/testsuite/g++.dg/analyzer/pr93777.C
@@ -0,0 +1 @@
+#include "../../g++.old-deja/g++.pt/spec36.C"
diff --git a/gcc/testsuite/gfortran.dg/analyzer/pr93777.f90 b/gcc/testsuite/gfortran.dg/analyzer/pr93777.f90
new file mode 100644
index 00000000000..1c198358829
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/analyzer/pr93777.f90
@@ -0,0 +1,22 @@
+! { dg-additional-options "-O0 -Wno-analyzer-possible-null-dereference -Wno-analyzer-null-dereference -Wno-analyzer-malloc-leak" }
+
+program cb
+  implicit none
+  type :: jn
+     real, allocatable :: ie
+     character(len = :), allocatable :: e5
+  end type jn
+  real, parameter :: gm = 5.0
+
+  block
+    type(jn) :: r2
+
+    r2 = jn (gm, "")
+    call vz (r2%ie, gm)
+  end block
+contains
+  subroutine vz (arg1, arg2)
+    real :: arg1, arg2
+    if (arg1 .ne. arg2) STOP 1
+  end subroutine vz
+end program cb


More information about the Gcc-cvs mailing list