@@ -15971,6 +15971,73 @@ lowering). Note that eok_class_rvalue_adjust operations are not modified here
1597115971} /* remove_qualifiers_from_expr_type_if_needed */
1597215972
1597315973
15974+ static a_boolean replace_param_ref_with_aggregate_this(
15975+ an_expr_node_ptr expr,
15976+ a_boolean candidates_only)
15977+ /*
15978+ expr is an enk_param_ref node that represents "this" while lowering an
15979+ aggregate constant. Go backwards through aggregate_this_stack, the stack of
15980+ nested potential "this" pointers, looking for the innermost entry that
15981+ matches the type of expr. If candidates_only is TRUE, skip the entries
15982+ whose not_this_candidate flag is set (see
15983+ lower_dynamic_init_aggregate_constant). If an entry is found, replace expr
15984+ by an expression that points to the beginning of that aggregate and return
15985+ TRUE; otherwise, return FALSE. Note that the code below is inefficient in
15986+ that it creates an expression representation for the initialization position
15987+ description just to find out its type (and discards expression trees that
15988+ don't match), but the type is difficult to determine (because of potential
15989+ modifiers) and this case doesn't occur frequently.
15990+ */
15991+ {
15992+ a_boolean found = FALSE;
15993+ an_expr_node_ptr new_expr = NULL;
15994+ an_init_pos_descr_ptr ipdp;
15995+ a_type_ptr new_type,
15996+ old_type= skip_typerefs(type_pointed_to(expr->type));
15997+
15998+ for (ipdp = aggregate_this_stack; ipdp != NULL; ipdp = ipdp->next) {
15999+ a_type_ptr subobj_type;
16000+ if (candidates_only && ipdp->not_this_candidate) {
16001+ /* An explicitly specified element of this aggregate is being lowered,
16002+ so this aggregate is not what "this" refers to. */
16003+ continue;
16004+ } /* if */
16005+ new_expr = make_address_of_init_entity_node(ipdp,
16006+ /*using_as_dest=*/FALSE);
16007+ new_type = skip_typerefs(type_pointed_to(new_expr->type));
16008+ if (identical_types_ignoring_qualifiers(new_type, old_type) ||
16009+ (aggregate_classes_can_have_bases &&
16010+ !class_type_supp(old_type)->is_lambda_closure_class &&
16011+ !class_type_supp(new_type)->is_lambda_closure_class &&
16012+ (subobj_type = subobject_for_class(old_type),
16013+ identical_types_ignoring_qualifiers(new_type, subobj_type)))) {
16014+ found = TRUE;
16015+ new_expr = add_cast_if_necessary(new_expr, expr->type);
16016+ overwrite_node(expr, new_expr);
16017+ break;
16018+ } else if (aggregate_classes_can_have_bases &&
16019+ ipdp->base_class_subobject) {
16020+ /* See if this initialization position has been modified to point
16021+ to a subobject base class. If so, temporarily remove the modifier
16022+ to see if the non-modified type is the "this" type that we're
16023+ looking for. */
16024+ an_init_pos_modifier_ptr save_modifiers = ipdp->modifiers;
16025+ ipdp->modifiers = NULL;
16026+ new_expr = make_address_of_init_entity_node(ipdp,
16027+ /*using_as_dest=*/FALSE);
16028+ new_type = type_pointed_to(new_expr->type);
16029+ ipdp->modifiers = save_modifiers;
16030+ if (identical_types_ignoring_qualifiers(new_type, old_type)) {
16031+ found = TRUE;
16032+ overwrite_node(expr, new_expr);
16033+ break;
16034+ } /* if */
16035+ } /* if */
16036+ } /* for */
16037+ return found;
16038+ } /* replace_param_ref_with_aggregate_this */
16039+
16040+
1597416041static void lower_param_ref(an_expr_node_ptr expr)
1597516042/*
1597616043The front end uses enk_param_refs to represent "this" in two particular
@@ -16001,60 +16068,26 @@ as in this case:
1600116068 } a;
1600216069
1600316070If we're in a non-constant aggregate initialization, search for that first.
16071+ Several nested aggregates can have the type of "this", as in:
16072+
16073+ struct Y { unsigned k; unsigned n = Y{2, k}.n; };
16074+
16075+ where "k" refers to the Y being initialized, not to the temporary
16076+ initialized by "Y{2, k}". The aggregates for which an explicitly specified
16077+ element is being lowered are therefore skipped.
1600416078*/
1600516079{
1600616080 a_boolean found = FALSE;
1600716081
1600816082 check_assertion(expr->kind == (an_expr_node_kind)enk_param_ref &&
1600916083 expr->variant.param_ref.param_num == 0);
1601016084 if (aggregate_this_stack != NULL) {
16011- /* We must be lowering an aggregate constant; go backwards through the
16012- stack of nested potential "this" pointers looking for one that matches
16013- the type of the enk_param_ref node (there can only be one) and
16014- create an expression that points to the beginning of that aggregate.
16015- Note that the code below is inefficient in that it creates an
16016- expression representation for the initialization position description
16017- just to find out its type (and discards expression trees that don't
16018- match), but the type is difficult to determine (because of potential
16019- modifiers) and this case doesn't occur frequently. */
16020- an_expr_node_ptr new_expr = NULL;
16021- an_init_pos_descr_ptr ipdp;
16022- a_type_ptr new_type,
16023- old_type= skip_typerefs(type_pointed_to(expr->type));
16024- for (ipdp = aggregate_this_stack; ipdp != NULL; ipdp = ipdp->next) {
16025- a_type_ptr subobj_type;
16026- new_expr = make_address_of_init_entity_node(ipdp,
16027- /*using_as_dest=*/FALSE);
16028- new_type = skip_typerefs(type_pointed_to(new_expr->type));
16029- if (identical_types_ignoring_qualifiers(new_type, old_type) ||
16030- (aggregate_classes_can_have_bases &&
16031- !class_type_supp(old_type)->is_lambda_closure_class &&
16032- !class_type_supp(new_type)->is_lambda_closure_class &&
16033- (subobj_type = subobject_for_class(old_type),
16034- identical_types_ignoring_qualifiers(new_type, subobj_type)))) {
16035- found = TRUE;
16036- new_expr = add_cast_if_necessary(new_expr, expr->type);
16037- overwrite_node(expr, new_expr);
16038- break;
16039- } else if (aggregate_classes_can_have_bases &&
16040- ipdp->base_class_subobject) {
16041- /* See if this initialization position has been modified to point
16042- to a subobject base class. If so, temporarily remove the modifier
16043- to see if the non-modified type is the "this" type that we're
16044- looking for. */
16045- an_init_pos_modifier_ptr save_modifiers = ipdp->modifiers;
16046- ipdp->modifiers = NULL;
16047- new_expr = make_address_of_init_entity_node(ipdp,
16048- /*using_as_dest=*/FALSE);
16049- new_type = type_pointed_to(new_expr->type);
16050- ipdp->modifiers = save_modifiers;
16051- if (identical_types_ignoring_qualifiers(new_type, old_type)) {
16052- found = TRUE;
16053- overwrite_node(expr, new_expr);
16054- break;
16055- } /* if */
16056- } /* if */
16057- } /* for */
16085+ /* We must be lowering an aggregate constant. If no candidate aggregate
16086+ matches, fall back on all the aggregates on the stack. */
16087+ found = replace_param_ref_with_aggregate_this(expr,
16088+ /*candidates_only=*/TRUE) ||
16089+ replace_param_ref_with_aggregate_this(expr,
16090+ /*candidates_only=*/FALSE);
1605816091 } /* if */
1605916092 if (!found) {
1606016093 if (ctor_init_this != NULL) {
0 commit comments