diff options
author | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2020-09-10 17:47:32 +0200 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2020-09-10 18:00:57 +0200 |
commit | 71465223b95af43951c423ad77391e706f02901d (patch) | |
tree | 708ff979248ddb6daebc0a49eed834903174c78a /gcc/ada/gcc-interface | |
parent | 66a204a6567385638f633732bb61e2ac26b2eb02 (diff) | |
download | gcc-71465223b95af43951c423ad77391e706f02901d.zip gcc-71465223b95af43951c423ad77391e706f02901d.tar.gz gcc-71465223b95af43951c423ad77391e706f02901d.tar.bz2 |
Fix uninitialized variable with nested variant record types
This fixes a wrong code issue with nested variant record types: the
compiler generates move instructions that depend on an uninitialized
variable, which was initially a SAVE_EXPR not instantiated early enough.
gcc/ada/ChangeLog:
* gcc-interface/decl.c (build_subst_list): For a definition, make
sure to instantiate the SAVE_EXPRs generated by the elaboration of
the constraints in front of the elaboration of the type itself.
gcc/testsuite/ChangeLog:
* gnat.dg/discr59.adb: New test.
* gnat.dg/discr59_pkg1.ads: New helper.
* gnat.dg/discr59_pkg2.ads: Likewise.
Diffstat (limited to 'gcc/ada/gcc-interface')
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 025714b..f85b2b5 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -8849,11 +8849,15 @@ build_subst_list (Entity_Id gnat_subtype, Entity_Id gnat_type, bool definition) if (!Is_Access_Type (Etype (Node (gnat_constr)))) { tree gnu_field = gnat_to_gnu_field_decl (gnat_discrim); - tree replacement = convert (TREE_TYPE (gnu_field), - elaborate_expression - (Node (gnat_constr), gnat_subtype, - get_entity_char (gnat_discrim), - definition, true, false)); + tree replacement + = elaborate_expression (Node (gnat_constr), gnat_subtype, + get_entity_char (gnat_discrim), + definition, true, false); + /* If this is a definition, we need to make sure that the SAVE_EXPRs + are instantiated on every possibly path in size computations. */ + if (definition && TREE_CODE (replacement) == SAVE_EXPR) + add_stmt (replacement); + replacement = convert (TREE_TYPE (gnu_field), replacement); subst_pair s = { gnu_field, replacement }; gnu_list.safe_push (s); } |