fortran/
* trans-stmt.c (gfc_trans_return): Fix comment formatting.
* trans-types.c (gfc_sym_type): Don't return early for functions.
Remove special handling for -ff2c.
(gfc_get_function_type): Add special handling for -ff2c.
* trans-decl.c (gfc_create_function_decl): Fix comment formatting.
(gfc_get_fake_result_decl): Make sure we get the right type for
functions.
(gfc_generate_function_code): Convert type of result variable to
type of function.
testsuite/
* gfortran.dg/f2c_8.f90: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120099
138bc75d-0d04-0410-961f-
82ee72b054a4
+2006-12-20 Tobias Schl\81üter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/25392
+ * trans-stmt.c (gfc_trans_return): Fix comment formatting.
+ * trans-types.c (gfc_sym_type): Don't return early for functions.
+ Remove special handling for -ff2c.
+ (gfc_get_function_type): Add special handling for -ff2c.
+ * trans-decl.c (gfc_create_function_decl): Fix comment formatting.
+ (gfc_get_fake_result_decl): Make sure we get the right type for
+ functions.
+ (gfc_generate_function_code): Convert type of result variable to
+ type of function.
+
2006-12-20 Paul Thomas <pault@gcc.gnu.org>
PR fortran/30190
}
/* Return the decl used to hold the function return value. If
- parent_flag is set, the context is the parent_scope*/
+ parent_flag is set, the context is the parent_scope. */
tree
gfc_get_fake_result_decl (gfc_symbol * sym, int parent_flag)
sprintf (name, "__result_%.20s",
IDENTIFIER_POINTER (DECL_NAME (this_function_decl)));
- decl = build_decl (VAR_DECL, get_identifier (name),
- TREE_TYPE (TREE_TYPE (this_function_decl)));
-
+ if (!sym->attr.mixed_entry_master && sym->attr.function)
+ decl = build_decl (VAR_DECL, get_identifier (name),
+ gfc_sym_type (sym));
+ else
+ decl = build_decl (VAR_DECL, get_identifier (name),
+ TREE_TYPE (TREE_TYPE (this_function_decl)));
DECL_ARTIFICIAL (decl) = 1;
DECL_EXTERNAL (decl) = 0;
TREE_PUBLIC (decl) = 0;
warning (0, "Function return value not set");
else
{
- /* Set the return value to the dummy result variable. */
- tmp = build2 (MODIFY_EXPR, TREE_TYPE (result),
- DECL_RESULT (fndecl), result);
+ /* Set the return value to the dummy result variable. The
+ types may be different for scalar default REAL functions
+ with -ff2c, therefore we have to convert. */
+ tmp = convert (TREE_TYPE (DECL_RESULT (fndecl)), result);
+ tmp = build2 (MODIFY_EXPR, TREE_TYPE (tmp),
+ DECL_RESULT (fndecl), tmp);
tmp = build1_v (RETURN_EXPR, tmp);
gfc_add_expr_to_block (&block, tmp);
}
tree tmp;
tree result;
- /* if code->expr is not NULL, this return statement must appear
+ /* If code->expr is not NULL, this return statement must appear
in a subroutine and current_fake_result_decl has already
been generated. */
if (sym->attr.flavor == FL_PROCEDURE && !sym->attr.function)
return void_type_node;
- if (sym->backend_decl)
- {
- if (sym->attr.function)
- return TREE_TYPE (TREE_TYPE (sym->backend_decl));
- else
- return TREE_TYPE (sym->backend_decl);
- }
+ /* In the case of a function the fake result variable may have a
+ type different from the function type, so don't return early in
+ that case. */
+ if (sym->backend_decl && !sym->attr.function)
+ return TREE_TYPE (sym->backend_decl);
type = gfc_typenode_for_spec (&sym->ts);
- if (gfc_option.flag_f2c
- && sym->attr.function
- && sym->ts.type == BT_REAL
- && sym->ts.kind == gfc_default_real_kind
- && !sym->attr.always_explicit)
- {
- /* Special case: f2c calling conventions require that (scalar)
- default REAL functions return the C type double instead. */
- sym->ts.kind = gfc_default_double_kind;
- type = gfc_typenode_for_spec (&sym->ts);
- sym->ts.kind = gfc_default_real_kind;
- }
if (sym->attr.dummy && !sym->attr.function && !sym->attr.value)
byref = 1;
type = void_type_node;
else if (sym->attr.mixed_entry_master)
type = gfc_get_mixed_entry_union (sym->ns);
+ else if (gfc_option.flag_f2c
+ && sym->ts.type == BT_REAL
+ && sym->ts.kind == gfc_default_real_kind
+ && !sym->attr.always_explicit)
+ {
+ /* Special case: f2c calling conventions require that (scalar)
+ default REAL functions return the C type double instead. f2c
+ compatibility is only an issue with functions that don't
+ require an explicit interface, as only these could be
+ implemented in Fortran 77. */
+ sym->ts.kind = gfc_default_double_kind;
+ type = gfc_typenode_for_spec (&sym->ts);
+ sym->ts.kind = gfc_default_real_kind;
+ }
else
type = gfc_sym_type (sym);
+2006-12-20 Tobias Schlüter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/25392
+ * gfortran.dg/f2c_8.f90: New test.
+
2006-12-20 Bill Wendling <wendling@apple.com>
* gcc.dg/asm-b.c: Check for __ppc64__.
--- /dev/null
+! { dg-do compile }
+! { dg-options "-ff2c" }
+! PR 25392
+! Verify that the type of the result variable matches the declared
+! type of the function. The actual type of the function may be
+! different for f2c calling conventions.
+real function goo () result (foo)
+ real x
+ foo = sign(foo, x)
+end
+
+real function foo ()
+ real x
+ foo = sign(foo, x)
+end
+