/* Check to see if this is a PDT constructor. The format of these
constructors is rather unusual:
- name (type_params)(component_values)
+ name [(type_params)](component_values)
where, component_values excludes the type_params. With the present
gfortran representation this is rather awkward because the two are not
distinguished, other than by their attributes. */
gfc_find_sym_tree (gfc_dt_upper_string (name), NULL, 1, &pdt_st);
if (pdt_st && pdt_st->n.sym && pdt_st->n.sym->attr.pdt_template)
{
+ bool type_spec_list = false;
pdt_sym = pdt_st->n.sym;
+ gfc_gobble_whitespace ();
+ /* Look for a second actual arglist. If present, try the first
+ for the type parameters. Otherwise, or if there is no match,
+ depend on default values by setting the type parameters to
+ NULL. */
+ if (gfc_peek_ascii_char() == '(')
+ type_spec_list = true;
/* Generate this instance using the type parameters from the
first argument list and return the parameter list in
m = gfc_get_pdt_instance (actual_arglist, &pdt_sym, &ctr_arglist);
if (m != MATCH_YES)
{
- m = MATCH_ERROR;
- break;
+ if (ctr_arglist)
+ gfc_free_actual_arglist (ctr_arglist);
+ /* See if all the type parameters have default values. */
+ m = gfc_get_pdt_instance (NULL, &pdt_sym, &ctr_arglist);
+ if (m != MATCH_YES)
+ {
+ m = MATCH_NO;
+ break;
+ }
}
- /* Now match the component_values. */
- m = gfc_match_actual_arglist (0, &actual_arglist);
- if (m != MATCH_YES)
+
+ /* Now match the component_values if the type parameters were
+ present. */
+ if (type_spec_list)
{
- m = MATCH_ERROR;
- break;
+ m = gfc_match_actual_arglist (0, &actual_arglist);
+ if (m != MATCH_YES)
+ {
+ m = MATCH_ERROR;
+ break;
+ }
}
/* Make sure that the component names are in place so that this
tmp = tmp->next;
}
- gfc_get_ha_sym_tree (gfc_dt_lower_string (pdt_sym->name) ,
- &symtree);
- symtree->n.sym = pdt_sym;
- symtree->n.sym->ts.u.derived = pdt_sym;
- symtree->n.sym->ts.type = BT_DERIVED;
+ gfc_find_sym_tree (gfc_dt_lower_string (pdt_sym->name),
+ NULL, 1, &symtree);
+ if (!symtree)
+ {
+ gfc_get_ha_sym_tree (gfc_dt_lower_string (pdt_sym->name) ,
+ &symtree);
+ symtree->n.sym = pdt_sym;
+ symtree->n.sym->ts.u.derived = pdt_sym;
+ symtree->n.sym->ts.type = BT_DERIVED;
+ }
- /* Do the appending. */
+ /* Append the type_params and the component_values. */
for (tmp = ctr_arglist; tmp && tmp->next;)
tmp = tmp->next;
tmp->next = actual_arglist;
--- /dev/null
+! { dg-do run }
+!
+! Test the fix for PR121948, in which the PDT constructor expressions without
+! the type specification list, ie. relying on default values, failed. The fix
+! also required that the incorrect initialization of functions with implicit
+! function result be eliminated.
+!
+! Contributed by Damian Rouson <damian@archaeologic.codes>
+!
+ implicit none
+
+ integer, parameter :: dp = kind(1d0)
+ real, parameter :: ap = 42.0
+ real(dp), parameter :: ap_d = 42.0d0
+
+ type operands_t(k)
+ integer, kind :: k = kind(1.)
+ real(k) :: actual, expected
+ end type
+
+ type(operands_t) :: x
+ type(operands_t(dp)) :: y
+
+ x = operands (ap, 10 * ap)
+ if (abs (x%actual - ap) >1e-5) stop 1
+ if (abs (x%expected - 10 * ap) > 1e-5) stop 2
+
+
+ y = operands_dp (ap_d, 10d0 * ap_d)
+ if (abs (y%actual - ap_d) > 1d-10) stop 3
+ if (abs (y%expected - 10d0 * ap_d) > 1d-10) stop 4
+ if (kind (y%actual) /= dp) stop 5
+ if (kind (y%expected) /= dp) stop 6
+
+contains
+
+ function operands(actual, expected) ! Use the default 'k'
+ real actual, expected
+ type(operands_t) :: operands
+ operands = operands_t(actual, expected)
+ end function
+
+
+ function operands_dp(actual, expected) ! Override the default
+ real(dp) actual, expected
+ type(operands_t(dp)) :: operands_dp
+ operands_dp = operands_t(dp)(actual, expected)
+ end function
+
+end