[gcc(refs/vendors/ibm/heads/perf)] Fix GIMPLE verification failure in LTO mode on Ada code

Jiu Fu Guo guojiufu@gcc.gnu.org
Thu Mar 19 06:15:32 GMT 2020


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

commit e835226bab5b3575c8a55c048dcfed3d4cde5e0e
Author: Eric Botcazou <ebotcazou@gcc.gnu.org>
Date:   Wed Mar 11 11:29:39 2020 +0100

    Fix GIMPLE verification failure in LTO mode on Ada code
    
    The issue is that tree_is_indexable doesn't return the same result for
    a FIELD_DECL with QUAL_UNION_TYPE and the QUAL_UNION_TYPE, resulting
    in two instances of the QUAL_UNION_TYPE in the bytecode.  The result
    for the type is the correct one (false, since it is variably modified)
    while the result for the field is falsely true because:
    
      else if (TREE_CODE (t) == FIELD_DECL
               && lto_variably_modified_type_p (DECL_CONTEXT (t)))
        return false;
    
    is not satisfied.  The reason for this is that the DECL_QUALIFIER of
    fields of a QUAL_UNION_TYPE depends on a discriminant in Ada, which
    means that the size of the type does too (CONTAINS_PLACEHOLDER_P),
    which in turn means that it is reset to a mere PLACEHOLDER_EXPR by
    free_lang_data, which finally means that the size of DECL_CONTEXT is
    too, so RETURN_TRUE_IF_VAR is false.
    
    In other words, the CONTAINS_PLACEHOLDER_P property of the DECL_QUALIFIER
    of fields of a QUAL_UNION_TYPE hides the variably_modified_type_p property
    of  these fields, if you look from the outside.
    
            PR middle-end/93961
            * tree.c (variably_modified_type_p) <RECORD_TYPE>: Recurse into
            fields whose type is a qualified union.

Diff:
---
 gcc/ChangeLog     |  6 ++++++
 gcc/ada/ChangeLog |  2 +-
 gcc/tree.c        | 10 ++++++++++
 3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1fc6ff36c84..0a79692a53f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2020-03-11  Eric Botcazou  <ebotcazou@adacore.com>
+
+	PR middle-end/93961
+	* tree.c (variably_modified_type_p) <RECORD_TYPE>: Recurse into fields
+	whose type is a qualified union.
+
 2020-03-11  Jakub Jelinek  <jakub@redhat.com>
 
 	PR target/94121
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 9df3840a411..5349fd96a8f 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,7 +1,7 @@
 2020-03-11  Richard Wai  <richard@annexi-strayline.com>
 
 	* gcc-interface/decl.c (gnat_to_gnu_entity): Also test Is_Public on
-	the Alias of the entitiy, if is present, in the main assertion.
+	the Alias of the entitiy, if it is present, in the main assertion.
 
 2020-02-06  Alexandre Oliva <oliva@adacore.com>
 
diff --git a/gcc/tree.c b/gcc/tree.c
index 66d52c71c99..905563fa4be 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -9206,8 +9206,18 @@ variably_modified_type_p (tree type, tree fn)
 	    RETURN_TRUE_IF_VAR (DECL_SIZE (t));
 	    RETURN_TRUE_IF_VAR (DECL_SIZE_UNIT (t));
 
+	    /* If the type is a qualified union, then the DECL_QUALIFIER
+	       of fields can also be an expression containing a variable.  */
 	    if (TREE_CODE (type) == QUAL_UNION_TYPE)
 	      RETURN_TRUE_IF_VAR (DECL_QUALIFIER (t));
+
+	    /* If the field is a qualified union, then it's only a container
+	       for what's inside so we look into it.  That's necessary in LTO
+	       mode because the sizes of the field tested above have been set
+	       to PLACEHOLDER_EXPRs by free_lang_data.  */
+	    if (TREE_CODE (TREE_TYPE (t)) == QUAL_UNION_TYPE
+		&& variably_modified_type_p (TREE_TYPE (t), fn))
+	      return true;
 	  }
       break;


More information about the Gcc-cvs mailing list