Commit 0b4e2af7 by Paul Thomas

re PR fortran/37274 ([Regression on 4.3?] error: type name is ambiguous.)

2008-09-18  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/37274
	PR fortran/36374
	* module.c (check_for_ambiguous): New function to test loaded
	symbol for ambiguity with fixup symbol.
	(read_module): Call check_for_ambiguous.
	(write_symtree): Do not write the symtree for symbols coming
	from an interface body.

	PR fortran/36374
	* resolve.c (count_specific_procs ): New function to count the
	number of specific procedures with the same name as the generic
	and emit appropriate errors for and actual argument reference.
	(resolve_assumed_size_actual): Add new argument no_formal_args.
	Correct logic around passing generic procedures as arguments.
	Call count_specific_procs from two locations.
	(resolve_function): Evaluate and pass no_formal_args.
	(resolve call): The same and clean up a bit by using csym more
	widely.

	PR fortran/36454
	* symbol.c (gfc_add_access): Access can be updated if use
	associated and not private.

2008-09-18  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/37274
	* gfortran.dg/used_types_22.f90: New test.
	* gfortran.dg/used_types_23.f90: New test.

	PR fortran/36374
	* gfortran.dg/generic_17.f90: New test.
	* gfortran.dg/ambiguous_specific_2.f90: New test.
	* gfortran.dg/generic_actual_arg.f90: Add test for case that is
	not ambiguous.

	PR fortran/36454
	* gfortran.dg/access_spec_3.f90: New test.

From-SVN: r140434
parent c0b29099
2008-09-18 Paul Thomas <pault@gcc.gnu.org>
PR fortran/37274
PR fortran/36374
* module.c (check_for_ambiguous): New function to test loaded
symbol for ambiguity with fixup symbol.
(read_module): Call check_for_ambiguous.
(write_symtree): Do not write the symtree for symbols coming
from an interface body.
PR fortran/36374
* resolve.c (count_specific_procs ): New function to count the
number of specific procedures with the same name as the generic
and emit appropriate errors for and actual argument reference.
(resolve_assumed_size_actual): Add new argument no_formal_args.
Correct logic around passing generic procedures as arguments.
Call count_specific_procs from two locations.
(resolve_function): Evaluate and pass no_formal_args.
(resolve call): The same and clean up a bit by using csym more
widely.
PR fortran/36454
* symbol.c (gfc_add_access): Access can be updated if use
associated and not private.
2008-09-17 Jakub Jelinek <jakub@redhat.com> 2008-09-17 Jakub Jelinek <jakub@redhat.com>
PR fortran/37536 PR fortran/37536
......
...@@ -3944,6 +3944,48 @@ read_cleanup (pointer_info *p) ...@@ -3944,6 +3944,48 @@ read_cleanup (pointer_info *p)
} }
/* It is not quite enough to check for ambiguity in the symbols by
the loaded symbol and the new symbol not being identical. */
static bool
check_for_ambiguous (gfc_symbol *st_sym, pointer_info *info)
{
gfc_symbol *rsym;
module_locus locus;
symbol_attribute attr;
rsym = info->u.rsym.sym;
if (st_sym == rsym)
return false;
/* Identical derived types are not ambiguous and will be rolled up
later. */
if (st_sym->attr.flavor == FL_DERIVED
&& rsym->attr.flavor == FL_DERIVED
&& gfc_compare_derived_types (st_sym, rsym))
return false;
/* If the existing symbol is generic from a different module and
the new symbol is generic there can be no ambiguity. */
if (st_sym->attr.generic
&& st_sym->module
&& strcmp (st_sym->module, module_name))
{
/* The new symbol's attributes have not yet been read. Since
we need attr.generic, read it directly. */
get_module_locus (&locus);
set_module_locus (&info->u.rsym.where);
mio_lparen ();
attr.generic = 0;
mio_symbol_attribute (&attr);
set_module_locus (&locus);
if (attr.generic)
return false;
}
return true;
}
/* Read a module file. */ /* Read a module file. */
static void static void
...@@ -4085,7 +4127,7 @@ read_module (void) ...@@ -4085,7 +4127,7 @@ read_module (void)
if (st != NULL) if (st != NULL)
{ {
/* Check for ambiguous symbols. */ /* Check for ambiguous symbols. */
if (st->n.sym != info->u.rsym.sym) if (check_for_ambiguous (st->n.sym, info))
st->ambiguous = 1; st->ambiguous = 1;
info->u.rsym.symtree = st; info->u.rsym.symtree = st;
} }
...@@ -4579,6 +4621,14 @@ write_symtree (gfc_symtree *st) ...@@ -4579,6 +4621,14 @@ write_symtree (gfc_symtree *st)
pointer_info *p; pointer_info *p;
sym = st->n.sym; sym = st->n.sym;
/* A symbol in an interface body must not be visible in the
module file. */
if (sym->ns != gfc_current_ns
&& sym->ns->proc_name
&& sym->ns->proc_name->attr.if_source == IFSRC_IFBODY)
return;
if (!gfc_check_access (sym->attr.access, sym->ns->default_access) if (!gfc_check_access (sym->attr.access, sym->ns->default_access)
|| (sym->attr.flavor == FL_PROCEDURE && sym->attr.generic || (sym->attr.flavor == FL_PROCEDURE && sym->attr.generic
&& !sym->attr.subroutine && !sym->attr.function)) && !sym->attr.subroutine && !sym->attr.function))
......
...@@ -1040,6 +1040,38 @@ resolve_assumed_size_actual (gfc_expr *e) ...@@ -1040,6 +1040,38 @@ resolve_assumed_size_actual (gfc_expr *e)
} }
/* Check a generic procedure, passed as an actual argument, to see if
there is a matching specific name. If none, it is an error, and if
more than one, the reference is ambiguous. */
static int
count_specific_procs (gfc_expr *e)
{
int n;
gfc_interface *p;
gfc_symbol *sym;
n = 0;
sym = e->symtree->n.sym;
for (p = sym->generic; p; p = p->next)
if (strcmp (sym->name, p->sym->name) == 0)
{
e->symtree = gfc_find_symtree (p->sym->ns->sym_root,
sym->name);
n++;
}
if (n > 1)
gfc_error ("'%s' at %L is ambiguous", e->symtree->n.sym->name,
&e->where);
if (n == 0)
gfc_error ("GENERIC procedure '%s' is not allowed as an actual "
"argument at %L", sym->name, &e->where);
return n;
}
/* Resolve an actual argument list. Most of the time, this is just /* Resolve an actual argument list. Most of the time, this is just
resolving the expressions in the list. resolving the expressions in the list.
The exception is that we sometimes have to decide whether arguments The exception is that we sometimes have to decide whether arguments
...@@ -1047,7 +1079,8 @@ resolve_assumed_size_actual (gfc_expr *e) ...@@ -1047,7 +1079,8 @@ resolve_assumed_size_actual (gfc_expr *e)
references. */ references. */
static gfc_try static gfc_try
resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype) resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype,
bool no_formal_args)
{ {
gfc_symbol *sym; gfc_symbol *sym;
gfc_symtree *parent_st; gfc_symtree *parent_st;
...@@ -1072,12 +1105,11 @@ resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype) ...@@ -1072,12 +1105,11 @@ resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype)
continue; continue;
} }
if (e->expr_type == EXPR_VARIABLE && e->symtree->ambiguous) if (e->expr_type == FL_VARIABLE
{ && e->symtree->n.sym->attr.generic
gfc_error ("'%s' at %L is ambiguous", e->symtree->n.sym->name, && no_formal_args
&e->where); && count_specific_procs (e) != 1)
return FAILURE; return FAILURE;
}
if (e->ts.type != BT_PROCEDURE) if (e->ts.type != BT_PROCEDURE)
{ {
...@@ -1138,23 +1170,11 @@ resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype) ...@@ -1138,23 +1170,11 @@ resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype)
/* Check if a generic interface has a specific procedure /* Check if a generic interface has a specific procedure
with the same name before emitting an error. */ with the same name before emitting an error. */
if (sym->attr.generic) if (sym->attr.generic && count_specific_procs (e) != 1)
{ return FAILURE;
gfc_interface *p;
for (p = sym->generic; p; p = p->next)
if (strcmp (sym->name, p->sym->name) == 0)
{
e->symtree = gfc_find_symtree
(p->sym->ns->sym_root, sym->name);
sym = p->sym;
break;
}
if (p == NULL || e->symtree == NULL) /* Just in case a specific was found for the expression. */
gfc_error ("GENERIC procedure '%s' is not " sym = e->symtree->n.sym;
"allowed as an actual argument at %L", sym->name,
&e->where);
}
/* If the symbol is the function that names the current (or /* If the symbol is the function that names the current (or
parent) scope, then we really have a variable reference. */ parent) scope, then we really have a variable reference. */
...@@ -2199,6 +2219,7 @@ resolve_function (gfc_expr *expr) ...@@ -2199,6 +2219,7 @@ resolve_function (gfc_expr *expr)
gfc_try t; gfc_try t;
int temp; int temp;
procedure_type p = PROC_INTRINSIC; procedure_type p = PROC_INTRINSIC;
bool no_formal_args;
sym = NULL; sym = NULL;
if (expr->symtree) if (expr->symtree)
...@@ -2238,7 +2259,9 @@ resolve_function (gfc_expr *expr) ...@@ -2238,7 +2259,9 @@ resolve_function (gfc_expr *expr)
if (expr->symtree && expr->symtree->n.sym) if (expr->symtree && expr->symtree->n.sym)
p = expr->symtree->n.sym->attr.proc; p = expr->symtree->n.sym->attr.proc;
if (resolve_actual_arglist (expr->value.function.actual, p) == FAILURE) no_formal_args = sym && is_external_proc (sym) && sym->formal == NULL;
if (resolve_actual_arglist (expr->value.function.actual,
p, no_formal_args) == FAILURE)
return FAILURE; return FAILURE;
/* Need to setup the call to the correct c_associated, depending on /* Need to setup the call to the correct c_associated, depending on
...@@ -2817,26 +2840,27 @@ resolve_call (gfc_code *c) ...@@ -2817,26 +2840,27 @@ resolve_call (gfc_code *c)
{ {
gfc_try t; gfc_try t;
procedure_type ptype = PROC_INTRINSIC; procedure_type ptype = PROC_INTRINSIC;
gfc_symbol *csym;
bool no_formal_args;
if (c->symtree && c->symtree->n.sym csym = c->symtree ? c->symtree->n.sym : NULL;
&& c->symtree->n.sym->ts.type != BT_UNKNOWN)
if (csym && csym->ts.type != BT_UNKNOWN)
{ {
gfc_error ("'%s' at %L has a type, which is not consistent with " gfc_error ("'%s' at %L has a type, which is not consistent with "
"the CALL at %L", c->symtree->n.sym->name, "the CALL at %L", csym->name, &csym->declared_at, &c->loc);
&c->symtree->n.sym->declared_at, &c->loc);
return FAILURE; return FAILURE;
} }
/* If external, check for usage. */ /* If external, check for usage. */
if (c->symtree && is_external_proc (c->symtree->n.sym)) if (csym && is_external_proc (csym))
resolve_global_procedure (c->symtree->n.sym, &c->loc, 1); resolve_global_procedure (csym, &c->loc, 1);
/* Subroutines without the RECURSIVE attribution are not allowed to /* Subroutines without the RECURSIVE attribution are not allowed to
* call themselves. */ * call themselves. */
if (c->symtree && c->symtree->n.sym && !c->symtree->n.sym->attr.recursive) if (csym && !csym->attr.recursive)
{ {
gfc_symbol *csym, *proc; gfc_symbol *proc;
csym = c->symtree->n.sym;
proc = gfc_current_ns->proc_name; proc = gfc_current_ns->proc_name;
if (csym == proc) if (csym == proc)
{ {
...@@ -2859,10 +2883,12 @@ resolve_call (gfc_code *c) ...@@ -2859,10 +2883,12 @@ resolve_call (gfc_code *c)
of procedure, once the procedure itself is resolved. */ of procedure, once the procedure itself is resolved. */
need_full_assumed_size++; need_full_assumed_size++;
if (c->symtree && c->symtree->n.sym) if (csym)
ptype = c->symtree->n.sym->attr.proc; ptype = csym->attr.proc;
if (resolve_actual_arglist (c->ext.actual, ptype) == FAILURE) no_formal_args = csym && is_external_proc (csym) && csym->formal == NULL;
if (resolve_actual_arglist (c->ext.actual, ptype,
no_formal_args) == FAILURE)
return FAILURE; return FAILURE;
/* Resume assumed_size checking. */ /* Resume assumed_size checking. */
...@@ -2870,7 +2896,7 @@ resolve_call (gfc_code *c) ...@@ -2870,7 +2896,7 @@ resolve_call (gfc_code *c)
t = SUCCESS; t = SUCCESS;
if (c->resolved_sym == NULL) if (c->resolved_sym == NULL)
switch (procedure_kind (c->symtree->n.sym)) switch (procedure_kind (csym))
{ {
case PTYPE_GENERIC: case PTYPE_GENERIC:
t = resolve_generic_s (c); t = resolve_generic_s (c);
......
...@@ -1446,7 +1446,8 @@ gfc_add_access (symbol_attribute *attr, gfc_access access, ...@@ -1446,7 +1446,8 @@ gfc_add_access (symbol_attribute *attr, gfc_access access,
const char *name, locus *where) const char *name, locus *where)
{ {
if (attr->access == ACCESS_UNKNOWN) if (attr->access == ACCESS_UNKNOWN
|| (attr->use_assoc && attr->access != ACCESS_PRIVATE))
{ {
attr->access = access; attr->access = access;
return check_conflict (attr, name, where); return check_conflict (attr, name, where);
......
2008-09-18 Paul Thomas <pault@gcc.gnu.org>
PR fortran/37274
* gfortran.dg/used_types_22.f90: New test.
* gfortran.dg/used_types_23.f90: New test.
PR fortran/36374
* gfortran.dg/generic_17.f90: New test.
* gfortran.dg/ambiguous_specific_2.f90: New test.
* gfortran.dg/generic_actual_arg.f90: Add test for case that is
not ambiguous.
PR fortran/36454
* gfortran.dg/access_spec_3.f90: New test.
2008-09-17 Eric Botcazou <ebotcazou@adacore.com> 2008-09-17 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/specs/static_initializer3.ads: New test. * gnat.dg/specs/static_initializer3.ads: New test.
......
! { dg-do compile }
!
! Tests the fix for PR36454, where the PUBLIC declaration for
! aint and bint was rejected because the access was already set.
!
! Contributed by Thomas Orgis <thomas.orgis@awi.de>
module base
integer :: baseint
end module
module a
use base, ONLY: aint => baseint
end module
module b
use base, ONLY: bint => baseint
end module
module c
use a
use b
private
public :: aint, bint
end module
program user
use c, ONLY: aint, bint
aint = 3
bint = 8
write(*,*) aint
end program
! { dg-final { cleanup-modules "base a b c" } }
! { dg-do compile }
! Checks the fix for PR33542 does not throw an error if there is no
! ambiguity in the specific interfaces of foo.
!
! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
!
MODULE M1
INTERFACE FOO
MODULE PROCEDURE FOO
END INTERFACE
CONTAINS
SUBROUTINE FOO(I)
INTEGER, INTENT(IN) :: I
WRITE(*,*) 'INTEGER'
END SUBROUTINE FOO
END MODULE M1
MODULE M2
INTERFACE FOO
MODULE PROCEDURE FOOFOO
END INTERFACE
CONTAINS
SUBROUTINE FOOFOO(R)
REAL, INTENT(IN) :: R
WRITE(*,*) 'REAL'
END SUBROUTINE FOOFOO
END MODULE M2
PROGRAM P
USE M1
USE M2
implicit none
external bar
CALL FOO(10)
CALL FOO(10.)
call bar (foo)
END PROGRAM P
SUBROUTINE bar (arg)
EXTERNAL arg
END SUBROUTINE bar
! { dg-final { cleanup-modules "m1 m2" } }
! { dg-do compile }
! Test the patch for PR36374 in which the different
! symbols for 'foobar' would be incorrectly flagged as
! ambiguous in foo_mod.
!
! Contributed by Salvatore Filippone <sfilippone@uniroma2.it>
!
module s_foo_mod
type s_foo_type
real(kind(1.e0)) :: v
end type s_foo_type
interface foobar
subroutine s_foobar(x)
import
type(s_foo_type), intent (inout) :: x
end subroutine s_foobar
end interface
end module s_foo_mod
module d_foo_mod
type d_foo_type
real(kind(1.d0)) :: v
end type d_foo_type
interface foobar
subroutine d_foobar(x)
import
type(d_foo_type), intent (inout) :: x
end subroutine d_foobar
end interface
end module d_foo_mod
module foo_mod
use s_foo_mod
use d_foo_mod
end module foo_mod
subroutine s_foobar(x)
use foo_mod
end subroutine s_foobar
! { dg-final { cleanup-modules "s_foo_mod d_foo_mod foo_mod" } }
...@@ -2,11 +2,14 @@ ...@@ -2,11 +2,14 @@
! Tests fix for PR20886 in which the passing of a generic procedure as ! Tests fix for PR20886 in which the passing of a generic procedure as
! an actual argument was not detected. ! an actual argument was not detected.
! !
! The second module and the check that CALCULATION2 is a good actual
! argument was added following the fix for PR26374.
!
! Contributed by Joost VandeVondele <jv244@cam.ac.uk> ! Contributed by Joost VandeVondele <jv244@cam.ac.uk>
! !
MODULE TEST MODULE TEST
INTERFACE CALCULATION INTERFACE CALCULATION
MODULE PROCEDURE C1,C2 MODULE PROCEDURE C1, C2
END INTERFACE END INTERFACE
CONTAINS CONTAINS
SUBROUTINE C1(r) SUBROUTINE C1(r)
...@@ -17,10 +20,26 @@ SUBROUTINE C2(r) ...@@ -17,10 +20,26 @@ SUBROUTINE C2(r)
END SUBROUTINE END SUBROUTINE
END MODULE TEST END MODULE TEST
MODULE TEST2
INTERFACE CALCULATION2
MODULE PROCEDURE CALCULATION2, C3
END INTERFACE
CONTAINS
SUBROUTINE CALCULATION2(r)
INTEGER :: r
END SUBROUTINE
SUBROUTINE C3(r)
REAL :: r
END SUBROUTINE
END MODULE TEST2
USE TEST USE TEST
USE TEST2
CALL F(CALCULATION) ! { dg-error "GENERIC procedure" } CALL F(CALCULATION) ! { dg-error "GENERIC procedure" }
CALL F(CALCULATION2) ! OK because there is a same name specific
END END
SUBROUTINE F() SUBROUTINE F()
END SUBROUTINE END SUBROUTINE
! { dg-final { cleanup-modules "TEST" } } ! { dg-final { cleanup-modules "TEST TEST2" } }
! { dg-do compile }
! Tests the fix for PR37274 a regression in which the derived type,
! 'vector' of the function results contained in 'class_motion' is
! private and is incorrectly detected to be ambiguous in 'smooth_mesh'.
!
! Contributed by Salvatore Filippone <sfilippone@uniroma2.it>
!
module class_vector
implicit none
private ! Default
public :: vector
public :: vector_
type vector
private
real(kind(1.d0)) :: x
real(kind(1.d0)) :: y
real(kind(1.d0)) :: z
end type vector
contains
! ----- Constructors -----
! Public default constructor
elemental function vector_(x,y,z)
type(vector) :: vector_
real(kind(1.d0)), intent(in) :: x, y, z
vector_ = vector(x,y,z)
end function vector_
end module class_vector
module class_dimensions
implicit none
private ! Default
public :: dimensions
type dimensions
private
integer :: l
integer :: m
integer :: t
integer :: theta
end type dimensions
end module class_dimensions
module tools_math
implicit none
interface lin_interp
function lin_interp_s(f1,f2,fac)
real(kind(1.d0)) :: lin_interp_s
real(kind(1.d0)), intent(in) :: f1, f2
real(kind(1.d0)), intent(in) :: fac
end function lin_interp_s
function lin_interp_v(f1,f2,fac)
use class_vector
type(vector) :: lin_interp_v
type(vector), intent(in) :: f1, f2
real(kind(1.d0)), intent(in) :: fac
end function lin_interp_v
end interface
interface pwl_deriv
subroutine pwl_deriv_x_s(dydx,x,y_data,x_data)
real(kind(1.d0)), intent(out) :: dydx
real(kind(1.d0)), intent(in) :: x
real(kind(1.d0)), intent(in) :: y_data(:)
real(kind(1.d0)), intent(in) :: x_data(:)
end subroutine pwl_deriv_x_s
subroutine pwl_deriv_x_v(dydx,x,y_data,x_data)
real(kind(1.d0)), intent(out) :: dydx(:)
real(kind(1.d0)), intent(in) :: x
real(kind(1.d0)), intent(in) :: y_data(:,:)
real(kind(1.d0)), intent(in) :: x_data(:)
end subroutine pwl_deriv_x_v
subroutine pwl_deriv_x_vec(dydx,x,y_data,x_data)
use class_vector
type(vector), intent(out) :: dydx
real(kind(1.d0)), intent(in) :: x
type(vector), intent(in) :: y_data(:)
real(kind(1.d0)), intent(in) :: x_data(:)
end subroutine pwl_deriv_x_vec
end interface
end module tools_math
module class_motion
use class_vector
implicit none
private
public :: motion
public :: get_displacement, get_velocity
type motion
private
integer :: surface_motion
integer :: vertex_motion
!
integer :: iml
real(kind(1.d0)), allocatable :: law_x(:)
type(vector), allocatable :: law_y(:)
end type motion
contains
function get_displacement(mot,x1,x2)
use tools_math
type(vector) :: get_displacement
type(motion), intent(in) :: mot
real(kind(1.d0)), intent(in) :: x1, x2
!
integer :: i1, i2, i3, i4
type(vector) :: p1, p2, v_A, v_B, v_C, v_D
type(vector) :: i_trap_1, i_trap_2, i_trap_3
get_displacement = vector_(0.d0,0.d0,0.d0)
end function get_displacement
function get_velocity(mot,x)
use tools_math
type(vector) :: get_velocity
type(motion), intent(in) :: mot
real(kind(1.d0)), intent(in) :: x
!
type(vector) :: v
get_velocity = vector_(0.d0,0.d0,0.d0)
end function get_velocity
end module class_motion
module class_bc_math
implicit none
private
public :: bc_math
type bc_math
private
integer :: id
integer :: nbf
real(kind(1.d0)), allocatable :: a(:)
real(kind(1.d0)), allocatable :: b(:)
real(kind(1.d0)), allocatable :: c(:)
end type bc_math
end module class_bc_math
module class_bc
use class_bc_math
use class_motion
implicit none
private
public :: bc_poly
public :: get_abc, &
& get_displacement, get_velocity
type bc_poly
private
integer :: id
type(motion) :: mot
type(bc_math), pointer :: math => null()
end type bc_poly
interface get_displacement
module procedure get_displacement, get_bc_motion_displacement
end interface
interface get_velocity
module procedure get_velocity, get_bc_motion_velocity
end interface
interface get_abc
module procedure get_abc_s, get_abc_v
end interface
contains
subroutine get_abc_s(bc,dim,id,a,b,c)
use class_dimensions
type(bc_poly), intent(in) :: bc
type(dimensions), intent(in) :: dim
integer, intent(out) :: id
real(kind(1.d0)), intent(inout) :: a(:)
real(kind(1.d0)), intent(inout) :: b(:)
real(kind(1.d0)), intent(inout) :: c(:)
end subroutine get_abc_s
subroutine get_abc_v(bc,dim,id,a,b,c)
use class_dimensions
use class_vector
type(bc_poly), intent(in) :: bc
type(dimensions), intent(in) :: dim
integer, intent(out) :: id
real(kind(1.d0)), intent(inout) :: a(:)
real(kind(1.d0)), intent(inout) :: b(:)
type(vector), intent(inout) :: c(:)
end subroutine get_abc_v
function get_bc_motion_displacement(bc,x1,x2)result(res)
use class_vector
type(vector) :: res
type(bc_poly), intent(in) :: bc
real(kind(1.d0)), intent(in) :: x1, x2
res = get_displacement(bc%mot,x1,x2)
end function get_bc_motion_displacement
function get_bc_motion_velocity(bc,x)result(res)
use class_vector
type(vector) :: res
type(bc_poly), intent(in) :: bc
real(kind(1.d0)), intent(in) :: x
res = get_velocity(bc%mot,x)
end function get_bc_motion_velocity
end module class_bc
module tools_mesh_basics
implicit none
interface
function geom_tet_center(v1,v2,v3,v4)
use class_vector
type(vector) :: geom_tet_center
type(vector), intent(in) :: v1, v2, v3, v4
end function geom_tet_center
end interface
end module tools_mesh_basics
subroutine smooth_mesh
use class_bc
use class_vector
use tools_mesh_basics
implicit none
type(vector) :: new_pos ! the new vertex position, after smoothing
end subroutine smooth_mesh
! { dg-final { cleanup-modules "class_vector class_dimensions tools_math" } }
! { dg-final { cleanup-modules "class_motion class_bc_math class_bc tools_mesh_basics" } }
! { dg-do compile }
! Tests the fix for PR37274 comment 4 in which the use associated 'vector' was
! passed up from the interface to the module 'tools_math'.
!
! Contributed by Mikael Morin <mikael.morin@tele2.fr>
!
module class_vector
implicit none
type vector
end type vector
end module class_vector
module tools_math
implicit none
interface lin_interp
function lin_interp_v()
use class_vector
type(vector) :: lin_interp_v
end function lin_interp_v
end interface
end module tools_math
module smooth_mesh
use tools_math
implicit none
type(vector ) :: new_pos ! { dg-error "used before it is defined" }
end module smooth_mesh
! { dg-final { cleanup-modules "class_vector tools_math smooth_mesh" } }
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