From e835226bab5b3575c8a55c048dcfed3d4cde5e0e Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 11 Mar 2020 11:29:39 +0100 Subject: [PATCH] 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) : Recurse into fields whose type is a qualified union. --- 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 + + PR middle-end/93961 + * tree.c (variably_modified_type_p) : Recurse into fields + whose type is a qualified union. + 2020-03-11 Jakub Jelinek 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 * 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 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; -- 2.30.2