Fix GIMPLE verification failure in LTO mode on Ada code
authorEric Botcazou <ebotcazou@gcc.gnu.org>
Wed, 11 Mar 2020 10:29:39 +0000 (11:29 +0100)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Wed, 11 Mar 2020 10:34:25 +0000 (11:34 +0100)
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.

gcc/ChangeLog
gcc/ada/ChangeLog
gcc/tree.c

index 1fc6ff36c84ea5404a6286ad8441baaa561f26d0..0a79692a53f822b09923da7dafc5f8351252d7b1 100644 (file)
@@ -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
index 9df3840a41184f9dff76c3f5f8acd05e60aa7432..5349fd96a8f1f9ffa45582c8f7c3bc3a1e78ad06 100644 (file)
@@ -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>
 
index 66d52c71c996e6db2b2de8c72bfba74d5837f5eb..905563fa4be9008080ec3abb3e32c0d03e5fd5fc 100644 (file)
@@ -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;