diff mbox series

[Ada] Fix uninitialized variable with nested variant record types

Message ID 2220376.IqttJVBmUs@fomalhaut
State New
Headers show
Series [Ada] Fix uninitialized variable with nested variant record types | expand

Commit Message

Eric Botcazou Sept. 10, 2020, 4:04 p.m. UTC
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.

Tested on x86_64-suse-linux, applied on mainline, 10 and 9 branches.


2020-09-10  Eric Botcazou  <ebotcazou@adacore.com>

	* 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.


2020-09-10  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/discr59.adb: New test.
	* gnat.dg/discr59_pkg1.ads: New helper.
	* gnat.dg/discr59_pkg2.ads: Likewise.
diff mbox series

Patch

diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 025714bd339..f85b2b5bbbb 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);
       }