--- ada-lang.c.prev 2008-12-12 12:49:31.000000000 +0100 +++ ada-lang.c 2008-12-12 12:54:17.000000000 +0100 @@ -6831,7 +6831,7 @@ ada_template_to_fixed_record_type_1 (str int keep_dynamic_fields) { struct value *mark = value_mark (); - struct value *dval; + struct value *dval = dval0; struct type *rtype; int nfields, bit_len; int variant_field; @@ -6882,10 +6882,17 @@ ada_template_to_fixed_record_type_1 (str } else if (is_dynamic_field (type, f)) { - if (dval0 == NULL) + /* If dval is NULL, build it using the record type that we are + initializing. This takes advantage of the fact that the + discrimant fields should appear before any dynamic field; + so, at this point, the discriminant fields have already been + added to rtype. This property also assure that this dval will + be valid for the rest of the computation, no need to re-allocate + a new one for every dynamic field. Finally, as the value is + allocated before any dynamic field has been added to the type, + we do not have to check its size before the allocation. */ + if (dval == NULL) dval = value_from_contents_and_address (rtype, valaddr, address); - else - dval = dval0; /* Get the fixed type of the field. Note that, in this case, we do not want to get the real type out of the tag: if the current @@ -6931,10 +6938,8 @@ ada_template_to_fixed_record_type_1 (str off = TYPE_FIELD_BITPOS (rtype, variant_field); - if (dval0 == NULL) + if (dval == NULL) dval = value_from_contents_and_address (rtype, valaddr, address); - else - dval = dval0; branch_type = to_fixed_variant_branch_type