Index: gcc/fortran/decl.c =================================================================== *** gcc/fortran/decl.c (revision 251948) --- gcc/fortran/decl.c (working copy) *************** variable_decl (int elem) *** 2537,2542 **** --- 2537,2575 ---- goto cleanup; } + if (gfc_current_state () == COMP_DERIVED + && gfc_current_block ()->attr.pdt_template) + { + gfc_symbol *param; + gfc_find_symbol (name, gfc_current_block ()->f2k_derived, + 0, ¶m); + if (!param && (current_attr.pdt_kind || current_attr.pdt_len)) + { + gfc_error ("The component with KIND or LEN attribute at %C does not " + "not appear in the type parameter list at %L", + &gfc_current_block ()->declared_at); + m = MATCH_ERROR; + goto cleanup; + } + else if (param && !(current_attr.pdt_kind || current_attr.pdt_len)) + { + gfc_error ("The component at %C that appears in the type parameter " + "list at %L has neither the KIND nor LEN attribute", + &gfc_current_block ()->declared_at); + m = MATCH_ERROR; + goto cleanup; + } + else if (as && (current_attr.pdt_kind || current_attr.pdt_len)) + { + gfc_error ("The component at %C which is a type parameter must be " + "a scalar"); + m = MATCH_ERROR; + goto cleanup; + } + else if (param && initializer) + param->value = gfc_copy_expr (initializer); + } + /* Add the initializer. Note that it is fine if initializer is NULL here, because we sometimes also need to check if a declaration *must* have an initialization expression. */ *************** gfc_get_pdt_instance (gfc_actual_arglist *** 3193,3200 **** { gfc_error ("The type parameter spec list at %C cannot contain " "both ASSUMED and DEFERRED parameters"); ! gfc_free_actual_arglist (type_param_spec_list); ! return MATCH_ERROR; } } --- 3226,3232 ---- { gfc_error ("The type parameter spec list at %C cannot contain " "both ASSUMED and DEFERRED parameters"); ! goto error_return; } } *************** gfc_get_pdt_instance (gfc_actual_arglist *** 3202,3211 **** name_seen = true; param = type_param_name_list->sym; kind_expr = NULL; if (!name_seen) { ! if (actual_param && actual_param->spec_type == SPEC_EXPLICIT) kind_expr = gfc_copy_expr (actual_param->expr); } else --- 3234,3260 ---- name_seen = true; param = type_param_name_list->sym; + c1 = gfc_find_component (pdt, param->name, false, true, NULL); + if (!pdt->attr.use_assoc && !c1) + { + gfc_error ("The type parameter name list at %L contains a parameter " + "'%qs' , which is not declared as a component of the type", + &pdt->declared_at, param->name); + goto error_return; + } + kind_expr = NULL; if (!name_seen) { ! if (!actual_param && !(c1 && c1->initializer)) ! { ! gfc_error ("The type parameter spec list at %C does not contain " ! "enough parameter expressions"); ! goto error_return; ! } ! else if (!actual_param && c1 && c1->initializer) ! kind_expr = gfc_copy_expr (c1->initializer); ! else if (actual_param && actual_param->spec_type == SPEC_EXPLICIT) kind_expr = gfc_copy_expr (actual_param->expr); } else *************** gfc_get_pdt_instance (gfc_actual_arglist *** 3225,3231 **** { gfc_error ("The derived parameter '%qs' at %C does not " "have a default value", param->name); ! return MATCH_ERROR; } } } --- 3274,3280 ---- { gfc_error ("The derived parameter '%qs' at %C does not " "have a default value", param->name); ! goto error_return; } } } *************** gfc_get_pdt_instance (gfc_actual_arglist *** 3247,3252 **** --- 3296,3312 ---- if (kind_expr) { + /* Variable expressions seem to default to BT_PROCEDURE. + TODO find out why this is and fix it. */ + if (kind_expr->ts.type != BT_INTEGER + && kind_expr->ts.type != BT_PROCEDURE) + { + gfc_error ("The parameter expression at %C must be of " + "INTEGER type and not %s type", + gfc_basic_typename (kind_expr->ts.type)); + goto error_return; + } + tail->expr = gfc_copy_expr (kind_expr); /* Try simplification even for LEN expressions. */ gfc_simplify_expr (tail->expr, 1); *************** gfc_get_pdt_instance (gfc_actual_arglist *** 3257,3263 **** if (!param->attr.pdt_kind) { ! if (!name_seen) actual_param = actual_param->next; if (kind_expr) { --- 3317,3323 ---- if (!param->attr.pdt_kind) { ! if (!name_seen && actual_param) actual_param = actual_param->next; if (kind_expr) { *************** gfc_get_pdt_instance (gfc_actual_arglist *** 3273,3288 **** { gfc_error ("The KIND parameter '%qs' at %C cannot either be " "ASSUMED or DEFERRED", param->name); ! gfc_free_actual_arglist (type_param_spec_list); ! return MATCH_ERROR; } if (!kind_expr || !gfc_is_constant_expr (kind_expr)) { gfc_error ("The value for the KIND parameter '%qs' at %C does not " "reduce to a constant expression", param->name); ! gfc_free_actual_arglist (type_param_spec_list); ! return MATCH_ERROR; } gfc_extract_int (kind_expr, &kind_value); --- 3333,3346 ---- { gfc_error ("The KIND parameter '%qs' at %C cannot either be " "ASSUMED or DEFERRED", param->name); ! goto error_return; } if (!kind_expr || !gfc_is_constant_expr (kind_expr)) { gfc_error ("The value for the KIND parameter '%qs' at %C does not " "reduce to a constant expression", param->name); ! goto error_return; } gfc_extract_int (kind_expr, &kind_value); *************** gfc_get_pdt_instance (gfc_actual_arglist *** 3293,3304 **** gfc_free_expr (kind_expr); } /* Now we search for the PDT instance 'name'. If it doesn't exist, we build it, using 'pdt' as a template. */ if (gfc_get_symbol (name, pdt->ns, &instance)) { gfc_error ("Parameterized derived type at %C is ambiguous"); ! return MATCH_ERROR; } m = MATCH_YES; --- 3351,3369 ---- gfc_free_expr (kind_expr); } + if (!name_seen && actual_param) + { + gfc_error ("The type parameter spec list at %C contains too many " + "parameter expressions"); + goto error_return; + } + /* Now we search for the PDT instance 'name'. If it doesn't exist, we build it, using 'pdt' as a template. */ if (gfc_get_symbol (name, pdt->ns, &instance)) { gfc_error ("Parameterized derived type at %C is ambiguous"); ! goto error_return; } m = MATCH_YES; *************** gfc_get_pdt_instance (gfc_actual_arglist *** 3370,3376 **** gfc_error ("Maximum extension level reached with type %qs at %L", c2->ts.u.derived->name, &c2->ts.u.derived->declared_at); ! return MATCH_ERROR; } instance->attr.extension = c2->ts.u.derived->attr.extension + 1; --- 3435,3441 ---- gfc_error ("Maximum extension level reached with type %qs at %L", c2->ts.u.derived->name, &c2->ts.u.derived->declared_at); ! goto error_return; } instance->attr.extension = c2->ts.u.derived->attr.extension + 1; *************** gfc_get_pdt_instance (gfc_actual_arglist *** 3390,3395 **** --- 3455,3466 ---- gfc_insert_kind_parameter_exprs (e); gfc_extract_int (e, &c2->ts.kind); gfc_free_expr (e); + if (gfc_validate_kind (c2->ts.type, c2->ts.kind, true) < 0) + { + gfc_error ("Kind %d not supported for type %s at %C", + c2->ts.kind, gfc_basic_typename (c2->ts.type)); + goto error_return; + } } /* Similarly, set the string length if parameterized. */ *************** gfc_get_pdt_instance (gfc_actual_arglist *** 3499,3504 **** --- 3570,3579 ---- *ext_param_list = type_param_spec_list; *sym = instance; return m; + + error_return: + gfc_free_actual_arglist (type_param_spec_list); + return MATCH_ERROR; } *************** gfc_match_decl_type_spec (gfc_typespec * *** 3829,3834 **** --- 3904,3922 ---- } if (sym->generic && !dt_sym) dt_sym = gfc_find_dt_in_generic (sym); + + /* Host associated PDTs can get confused with their constructors + because they ar instantiated in the template's namespace. */ + if (!dt_sym) + { + if (gfc_find_symbol (dt_name, NULL, 1, &dt_sym)) + { + gfc_error ("Type name %qs at %C is ambiguous", name); + return MATCH_ERROR; + } + if (dt_sym && !dt_sym->attr.pdt_type) + dt_sym = NULL; + } } else if (ts->kind == -1) { Index: gcc/fortran/expr.c =================================================================== *** gcc/fortran/expr.c (revision 251949) --- gcc/fortran/expr.c (working copy) *************** gfc_replace_expr (gfc_expr *dest, gfc_ex *** 624,629 **** --- 624,643 ---- bool gfc_extract_int (gfc_expr *expr, int *result, int report_error) { + gfc_ref *ref; + + /* A KIND component is a parameter too. The expression for it + is stored in the initializer and should be consistent with + the tests below. */ + if (gfc_expr_attr(expr).pdt_kind) + { + for (ref = expr->ref; ref; ref = ref->next) + { + if (ref->u.c.component->attr.pdt_kind) + expr = ref->u.c.component->initializer; + } + } + if (expr->expr_type != EXPR_CONSTANT) { if (report_error > 0) *************** gfc_check_init_expr (gfc_expr *e) *** 2548,2554 **** t = true; /* This occurs when parsing pdt templates. */ ! if (e->symtree->n.sym->attr.pdt_kind) break; if (gfc_check_iter_variable (e)) --- 2562,2568 ---- t = true; /* This occurs when parsing pdt templates. */ ! if (gfc_expr_attr (e).pdt_kind) break; if (gfc_check_iter_variable (e)) Index: gcc/fortran/primary.c =================================================================== *** gcc/fortran/primary.c (revision 251948) --- gcc/fortran/primary.c (working copy) *************** gfc_match_actual_arglist (int sub_flag, *** 1796,1806 **** if (sub_flag && !pdt && gfc_match_char ('*') == MATCH_YES) { - if (pdt) - { - tail->spec_type = SPEC_ASSUMED; - goto next; - } m = gfc_match_st_label (&label); if (m == MATCH_NO) gfc_error ("Expected alternate return label at %C"); --- 1796,1801 ---- *************** gfc_match_actual_arglist (int sub_flag, *** 1829,1834 **** --- 1824,1838 ---- } else tail->spec_type = SPEC_EXPLICIT; + + m = match_keyword_arg (tail, head, pdt); + if (m == MATCH_YES) + { + seen_keyword = 1; + goto next; + } + if (m == MATCH_ERROR) + goto cleanup; } /* After the first keyword argument is seen, the following Index: gcc/testsuite/gfortran.dg/pdt_4.f03 =================================================================== *** gcc/testsuite/gfortran.dg/pdt_4.f03 (revision 251948) --- gcc/testsuite/gfortran.dg/pdt_4.f03 (working copy) *************** end module *** 81,88 **** end select deallocate (cz) contains ! subroutine foo(arg) ! { dg-error "has no IMPLICIT type" } ! type (mytype(4, *)) :: arg ! { dg-error "is being used before it is defined" } end subroutine subroutine bar(arg) ! { dg-error "cannot have DEFERRED type parameters" } type (thytype(8, :, 4) :: arg --- 81,88 ---- end select deallocate (cz) contains ! subroutine foo(arg) ! type (mytype(4, *)) :: arg ! used to have an invalid "is being used before it is defined" end subroutine subroutine bar(arg) ! { dg-error "cannot have DEFERRED type parameters" } type (thytype(8, :, 4) :: arg Index: gcc/testsuite/gfortran.dg/pdt_6.f03 =================================================================== *** gcc/testsuite/gfortran.dg/pdt_6.f03 (nonexistent) --- gcc/testsuite/gfortran.dg/pdt_6.f03 (working copy) *************** *** 0 **** --- 1,26 ---- + ! { dg-do compile } + ! + ! Fixes of ICE on invalid & accepts invalid + ! + ! Contributed by Thomas Koenig + ! + implicit none + + type :: param_matrix(c,r) + integer, len :: c,r + real :: m(c,r) + end type + + type real_array(k) + integer, kind :: k + real(kind=k), allocatable :: r(:) + end type + + type(param_matrix(1)) :: m1 ! { dg-error "does not contain enough parameter" } + type(param_matrix(1,2)) :: m2 ! ok + type(param_matrix(1,2,3)) :: m3 ! { dg-error "contains too many parameter" } + type(param_matrix(1,2.5)) :: m4 ! { dg-error "must be of INTEGER type" } + + type(real_array(4)) :: a1 ! ok + type(real_array(5)) :: a2 ! { dg-error "Kind 5 not supported for type REAL" } + end Index: gcc/testsuite/gfortran.dg/pdt_7.f03 =================================================================== *** gcc/testsuite/gfortran.dg/pdt_7.f03 (nonexistent) --- gcc/testsuite/gfortran.dg/pdt_7.f03 (working copy) *************** *** 0 **** --- 1,20 ---- + ! { dg-do run } + ! + ! Rejected valid + ! + ! Contributed by Thomas Koenig + ! + implicit none + + type :: param_matrix(k,c,r) + integer, kind :: k + integer, len :: c,r + real(kind=k) :: m(c,r) + end type + + type(param_matrix(8,3,2)) :: mat + real(kind=mat%k) :: m ! Corrected error: Parameter ‘mat’ at (1) has not been declared or ... + + if (kind(m) .ne. 8) call abort + + end Index: gcc/testsuite/gfortran.dg/pdt_8.f03 =================================================================== *** gcc/testsuite/gfortran.dg/pdt_8.f03 (nonexistent) --- gcc/testsuite/gfortran.dg/pdt_8.f03 (working copy) *************** *** 0 **** --- 1,23 ---- + ! { dg-do compile } + ! + ! Fixes of "accepts invalid". + ! Note that the undeclared parameter 'y' in 't1' was originally in the + ! type 't'. It turned out to be convenient to defer the error until the + ! type is used in the declaration of 'z'. + ! + ! Contributed by Thomas Koenig + ! + implicit none + type :: t(i,a,x) ! { dg-error "does not|has neither" } + integer, kind :: k ! { dg-error "does not not appear in the type parameter list" } + integer :: i ! { dg-error "has neither the KIND nor LEN attribute" } + integer, kind :: a(3) ! { dg-error "must be a scalar" } + real, kind :: x ! { dg-error "must be INTEGER" } + end type + + type :: t1(k,y) ! { dg-error "not declared as a component of the type" } + integer, kind :: k + end type + + type(t1(4,4)) :: z + end Index: gcc/testsuite/gfortran.dg/pdt_9.f03 =================================================================== *** gcc/testsuite/gfortran.dg/pdt_9.f03 (nonexistent) --- gcc/testsuite/gfortran.dg/pdt_9.f03 (working copy) *************** *** 0 **** --- 1,23 ---- + ! { dg-do compile } + ! + ! Test the fix for PR82168 in which the declarations for 'a' + ! and 'b' threw errors even though they are valid. + ! + ! Contributed by + ! + module mod + implicit none + integer, parameter :: dp = kind (0.0d0) + type, public :: v(z, k) + integer, len :: z + integer, kind :: k = kind(0.0) + real(kind = k) :: e(z) + end type v + end module mod + + program bug + use mod + implicit none + type (v(2)) :: a ! Missing parameter replaced by initializer. + type (v(z=:, k=dp)), allocatable :: b ! Keyword was not working for '*' or ':' + end program bug