Commit 6442a6f4 by Paul Thomas

re PR fortran/71156 (PURE interface/definition inconsistency: accepts invalid, rejects valid)

2016-06-01  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/71156
	* decl.c (copy_prefix): Add checks that the module procedure
	declaration prefixes are compliant with the interface. Invert
	order of existing elemental and pure checks.
	* resolve.c (resolve_fl_procedure): Invert order of elemental
	and pure errors.

2016-06-01  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/71156
	* gfortran.dg/submodule_14.f08: Add missing recursive prefix
	to the module procedure declaration.
	* gfortran.dg/submodule_16.f08: New test.

From-SVN: r236996
parent ab62397a
2016-06-01 Paul Thomas <pault@gcc.gnu.org>
PR fortran/71156
* decl.c (copy_prefix): Add checks that the module procedure
declaration prefixes are compliant with the interface. Invert
order of existing elemental and pure checks.
* resolve.c (resolve_fl_procedure): Invert order of elemental
and pure errors.
2016-06-01 Jakub Jelinek <jakub@redhat.com> 2016-06-01 Jakub Jelinek <jakub@redhat.com>
* parse.c (case_decl): Move ST_OMP_* to ... * parse.c (case_decl): Move ST_OMP_* to ...
......
...@@ -608,10 +608,10 @@ cleanup: ...@@ -608,10 +608,10 @@ cleanup:
/* Like gfc_match_init_expr, but matches a 'clist' (old-style initialization /* Like gfc_match_init_expr, but matches a 'clist' (old-style initialization
list). The difference here is the expression is a list of constants list). The difference here is the expression is a list of constants
and is surrounded by '/'. and is surrounded by '/'.
The typespec ts must match the typespec of the variable which the The typespec ts must match the typespec of the variable which the
clist is initializing. clist is initializing.
The arrayspec tells whether this should match a list of constants The arrayspec tells whether this should match a list of constants
corresponding to array elements or a scalar (as == NULL). */ corresponding to array elements or a scalar (as == NULL). */
static match static match
...@@ -1848,7 +1848,7 @@ build_struct (const char *name, gfc_charlen *cl, gfc_expr **init, ...@@ -1848,7 +1848,7 @@ build_struct (const char *name, gfc_charlen *cl, gfc_expr **init,
/* If we are in a nested union/map definition, gfc_add_component will not /* If we are in a nested union/map definition, gfc_add_component will not
properly find repeated components because: properly find repeated components because:
(i) gfc_add_component does a flat search, where components of unions (i) gfc_add_component does a flat search, where components of unions
and maps are implicity chained so nested components may conflict. and maps are implicity chained so nested components may conflict.
(ii) Unions and maps are not linked as components of their parent (ii) Unions and maps are not linked as components of their parent
structures until after they are parsed. structures until after they are parsed.
...@@ -4978,12 +4978,51 @@ error: ...@@ -4978,12 +4978,51 @@ error:
static bool static bool
copy_prefix (symbol_attribute *dest, locus *where) copy_prefix (symbol_attribute *dest, locus *where)
{ {
if (current_attr.pure && !gfc_add_pure (dest, where)) if (dest->module_procedure)
return false; {
if (current_attr.elemental)
dest->elemental = 1;
if (current_attr.pure)
dest->pure = 1;
if (current_attr.recursive)
dest->recursive = 1;
/* Module procedures are unusual in that the 'dest' is copied from
the interface declaration. However, this is an oportunity to
check that the submodule declaration is compliant with the
interface. */
if (dest->elemental && !current_attr.elemental)
{
gfc_error ("ELEMENTAL prefix in MODULE PROCEDURE interface is "
"missing at %L", where);
return false;
}
if (dest->pure && !current_attr.pure)
{
gfc_error ("PURE prefix in MODULE PROCEDURE interface is "
"missing at %L", where);
return false;
}
if (dest->recursive && !current_attr.recursive)
{
gfc_error ("RECURSIVE prefix in MODULE PROCEDURE interface is "
"missing at %L", where);
return false;
}
return true;
}
if (current_attr.elemental && !gfc_add_elemental (dest, where)) if (current_attr.elemental && !gfc_add_elemental (dest, where))
return false; return false;
if (current_attr.pure && !gfc_add_pure (dest, where))
return false;
if (current_attr.recursive && !gfc_add_recursive (dest, where)) if (current_attr.recursive && !gfc_add_recursive (dest, where))
return false; return false;
...@@ -8327,7 +8366,7 @@ gfc_get_type_attr_spec (symbol_attribute *attr, char *name) ...@@ -8327,7 +8366,7 @@ gfc_get_type_attr_spec (symbol_attribute *attr, char *name)
does NOT have a generic symbol matching the name given by the user. does NOT have a generic symbol matching the name given by the user.
STRUCTUREs can share names with variables and PARAMETERs so we must allow STRUCTUREs can share names with variables and PARAMETERs so we must allow
for the creation of an independent symbol. for the creation of an independent symbol.
Other parameters are a message to prefix errors with, the name of the new Other parameters are a message to prefix errors with, the name of the new
type to be created, and the flavor to add to the resulting symbol. */ type to be created, and the flavor to add to the resulting symbol. */
static bool static bool
...@@ -8355,7 +8394,7 @@ get_struct_decl (const char *name, sym_flavor fl, locus *decl, ...@@ -8355,7 +8394,7 @@ get_struct_decl (const char *name, sym_flavor fl, locus *decl,
if (sym->components != NULL || sym->attr.zero_comp) if (sym->components != NULL || sym->attr.zero_comp)
{ {
gfc_error ("Type definition of '%s' at %C was already defined at %L", gfc_error ("Type definition of '%s' at %C was already defined at %L",
sym->name, &sym->declared_at); sym->name, &sym->declared_at);
return false; return false;
} }
......
...@@ -11965,17 +11965,17 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag) ...@@ -11965,17 +11965,17 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
goto check_formal; goto check_formal;
/* Check the procedure characteristics. */ /* Check the procedure characteristics. */
if (sym->attr.pure != iface->attr.pure) if (sym->attr.elemental != iface->attr.elemental)
{ {
gfc_error ("Mismatch in PURE attribute between MODULE " gfc_error ("Mismatch in ELEMENTAL attribute between MODULE "
"PROCEDURE at %L and its interface in %s", "PROCEDURE at %L and its interface in %s",
&sym->declared_at, module_name); &sym->declared_at, module_name);
return false; return false;
} }
if (sym->attr.elemental != iface->attr.elemental) if (sym->attr.pure != iface->attr.pure)
{ {
gfc_error ("Mismatch in ELEMENTAL attribute between MODULE " gfc_error ("Mismatch in PURE attribute between MODULE "
"PROCEDURE at %L and its interface in %s", "PROCEDURE at %L and its interface in %s",
&sym->declared_at, module_name); &sym->declared_at, module_name);
return false; return false;
......
2016-06-01 Paul Thomas <pault@gcc.gnu.org>
PR fortran/71156
* gfortran.dg/submodule_14.f08: Add missing recursive prefix
to the module procedure declaration.
* gfortran.dg/submodule_16.f08: New test.
2016-06-01 Jakub Jelinek <jakub@redhat.com> 2016-06-01 Jakub Jelinek <jakub@redhat.com>
PR middle-end/71371 PR middle-end/71371
...@@ -322,7 +329,7 @@ ...@@ -322,7 +329,7 @@
2016-05-26 Jiong Wang <jiong.wang@arm.com> 2016-05-26 Jiong Wang <jiong.wang@arm.com>
* gcc.target/aarch64/simd/vmul_elem_1.c: Force result variables to be * gcc.target/aarch64/simd/vmul_elem_1.c: Force result variables to be
kept in memory. kept in memory.
2016-05-25 Jeff Law <law@redhat.com> 2016-05-25 Jeff Law <law@redhat.com>
......
...@@ -27,7 +27,7 @@ contains ...@@ -27,7 +27,7 @@ contains
Call sub1 (x) Call sub1 (x)
End If End If
End Procedure sub1 End Procedure sub1
module function fcn1 (x) result(res) recursive module function fcn1 (x) result(res)
integer, intent (inout) :: x integer, intent (inout) :: x
integer :: res integer :: res
res = x - 1 res = x - 1
......
! { dg-do compile }
!
! Tests the fix for PR71156 in which the valid code (f7, f8 and f9 below)
! triggered an error, while the invalid code (f1 to f6) compiled.
!
! Contributed by Damian Rousn <damian@sourceryinstitute.org>
!
module my_interface
implicit none
interface
module subroutine f1
end subroutine
module subroutine f2
end subroutine
module subroutine f3
end subroutine
elemental module subroutine f4
end subroutine
pure module subroutine f5
end subroutine
recursive module subroutine f6
end subroutine
elemental module subroutine f7
end subroutine
pure module subroutine f8
end subroutine
recursive module subroutine f9
end subroutine
end interface
end module
submodule(my_interface) my_implementation
implicit none
contains
elemental module subroutine f1 ! { dg-error "Mismatch in ELEMENTAL attribute" }
end subroutine
pure module subroutine f2 ! { dg-error "Mismatch in PURE attribute" }
end subroutine
recursive module subroutine f3 ! { dg-error "Mismatch in RECURSIVE attribute" }
end subroutine
module subroutine f4 ! { dg-error "ELEMENTAL prefix" }
end subroutine
module subroutine f5 ! { dg-error "PURE prefix" }
end subroutine
module subroutine f6 ! { dg-error "RECURSIVE prefix" }
end subroutine
elemental module subroutine f7
end subroutine
pure module subroutine f8
end subroutine
recursive module subroutine f9
end subroutine
end submodule
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment