mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-21 02:50:27 +08:00
analyzer: fix ICE on pointer arithmetic with incomplete types [PR 93774]
PR analyzer/93774 reports an ICE in gfortran with -fanalyzer within region_model::convert_byte_offset_to_array_index on a pointer of incomplete type ("character(kind=1)[0:][1:0] * restrict"). This patch bulletproofs the routine against incomplete types, fixing the ICE. gcc/analyzer/ChangeLog: PR analyzer/93774 * region-model.cc (region_model::convert_byte_offset_to_array_index): Use int_size_in_bytes before calling size_in_bytes, to gracefully fail on incomplete types. gcc/testsuite/ChangeLog: PR analyzer/93774 * gfortran.dg/analyzer/deferred_character_25.f90: New test, based on gfortran.dg/deferred_character_25.f90.
This commit is contained in:
parent
68f9c41d54
commit
a674c7b8b8
@ -1,3 +1,11 @@
|
||||
2020-02-18 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
PR analyzer/93774
|
||||
* region-model.cc
|
||||
(region_model::convert_byte_offset_to_array_index): Use
|
||||
int_size_in_bytes before calling size_in_bytes, to gracefully fail
|
||||
on incomplete types.
|
||||
|
||||
2020-02-17 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
PR analyzer/93775
|
||||
|
@ -6514,24 +6514,27 @@ region_model::convert_byte_offset_to_array_index (tree ptr_type,
|
||||
|
||||
/* Arithmetic on void-pointers is a GNU C extension, treating the size
|
||||
of a void as 1.
|
||||
https://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html
|
||||
|
||||
Returning early for this case avoids a diagnostic from within the
|
||||
call to size_in_bytes. */
|
||||
https://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html */
|
||||
if (TREE_CODE (elem_type) == VOID_TYPE)
|
||||
return offset_sid;
|
||||
|
||||
/* This might not be a constant. */
|
||||
tree byte_size = size_in_bytes (elem_type);
|
||||
|
||||
/* Try to get a constant by dividing, ensuring that we're in a
|
||||
signed representation first. */
|
||||
tree index
|
||||
= fold_binary (TRUNC_DIV_EXPR, ssizetype,
|
||||
fold_convert (ssizetype, offset_cst),
|
||||
fold_convert (ssizetype, byte_size));
|
||||
if (index && TREE_CODE (index) == INTEGER_CST)
|
||||
return get_or_create_constant_svalue (index);
|
||||
/* First, use int_size_in_bytes, to reject the case where we have an
|
||||
incomplete type, or a non-constant value. */
|
||||
HOST_WIDE_INT hwi_byte_size = int_size_in_bytes (elem_type);
|
||||
if (hwi_byte_size > 0)
|
||||
{
|
||||
/* Now call size_in_bytes to get the answer in tree form. */
|
||||
tree byte_size = size_in_bytes (elem_type);
|
||||
gcc_assert (byte_size);
|
||||
/* Try to get a constant by dividing, ensuring that we're in a
|
||||
signed representation first. */
|
||||
tree index
|
||||
= fold_binary (TRUNC_DIV_EXPR, ssizetype,
|
||||
fold_convert (ssizetype, offset_cst),
|
||||
fold_convert (ssizetype, byte_size));
|
||||
if (index && TREE_CODE (index) == INTEGER_CST)
|
||||
return get_or_create_constant_svalue (index);
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, we don't know the array index; generate a new unknown value.
|
||||
|
@ -1,3 +1,9 @@
|
||||
2020-02-18 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
PR analyzer/93774
|
||||
* gfortran.dg/analyzer/deferred_character_25.f90: New test,
|
||||
based on gfortran.dg/deferred_character_25.f90.
|
||||
|
||||
2020-02-18 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
PR analyzer/93779
|
||||
|
32
gcc/testsuite/gfortran.dg/analyzer/deferred_character_25.f90
Normal file
32
gcc/testsuite/gfortran.dg/analyzer/deferred_character_25.f90
Normal file
@ -0,0 +1,32 @@
|
||||
! { dg-do compile }
|
||||
! { dg-additional-options "-Wno-analyzer-too-complex" }
|
||||
|
||||
! Copy of gfortran.dg/deferred_character_25.f90
|
||||
! as a regression test for ICE with -fanalyzer (PR analyzer/93774)
|
||||
|
||||
PROGRAM TEST
|
||||
IMPLICIT NONE
|
||||
INTEGER, PARAMETER :: I = 3
|
||||
character (len = i), parameter :: str(5) = ['abc','cde','fgh','ijk','lmn']
|
||||
|
||||
TYPE T
|
||||
CHARACTER(LEN=:), ALLOCATABLE :: C(:)
|
||||
END TYPE T
|
||||
TYPE(T), TARGET :: S
|
||||
CHARACTER (LEN=I), POINTER :: P(:)
|
||||
|
||||
ALLOCATE ( CHARACTER(LEN=I) :: S%C(5) )
|
||||
s%c = str
|
||||
|
||||
! This PR uncovered several problems associated with determining the
|
||||
! element length and indexing. Test fairly thoroughly!
|
||||
if (SIZE(S%C, 1) .ne. 5) stop 1
|
||||
if (LEN(S%C) .ne. 3) stop 2
|
||||
if (any (s%c .ne. str)) stop 3
|
||||
if (s%c(3) .ne. str(3)) stop 4
|
||||
P => S%C
|
||||
if (SIZE(p, 1) .ne. 5) stop 5
|
||||
if (LEN(p) .ne. 3) stop 6
|
||||
if (any (p .ne. str)) stop 7
|
||||
if (p(5) .ne. str(5)) stop 8
|
||||
END PROGRAM TEST
|
Loading…
x
Reference in New Issue
Block a user