analyzer: fix ICE on failed casts [PR 93777]
authorDavid Malcolm <dmalcolm@redhat.com>
Mon, 17 Feb 2020 22:37:52 +0000 (17:37 -0500)
committerDavid Malcolm <dmalcolm@redhat.com>
Tue, 18 Feb 2020 13:17:43 +0000 (08:17 -0500)
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.

gcc/analyzer/ChangeLog
gcc/analyzer/region-model.cc
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/analyzer/pr93777.C [new file with mode: 0644]
gcc/testsuite/gfortran.dg/analyzer/pr93777.f90 [new file with mode: 0644]

index 05fb614..f4c6200 100644 (file)
@@ -1,5 +1,13 @@
 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
        * engine.cc (impl_region_model_context::on_unknown_tree_code):
        Rename to...
index c8ee031..d061552 100644 (file)
@@ -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.  */
index d171d4e..55e2e6e 100644 (file)
@@ -1,5 +1,11 @@
 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
        * gfortran.dg/analyzer/pr93778.f90: New test.
 
diff --git a/gcc/testsuite/g++.dg/analyzer/pr93777.C b/gcc/testsuite/g++.dg/analyzer/pr93777.C
new file mode 100644 (file)
index 0000000..e94e75f
--- /dev/null
@@ -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 (file)
index 0000000..1c19835
--- /dev/null
@@ -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