extend.texi: Mark named return value extension as deprecated.

* extend.texi: Mark named return value extension as deprecated.

	* NEWS: Mention that the named return value extension has been
	deprecated.
	* cp-tree.h (original_result_rtx): Define.
	(TREE_REFERENCE_EXPR): Remove.
	(DECL_VPARENT): Likewise.
	(pushdecl_nonclass_level): Likewise.
	(store_return_init): Likewise.
	(reinit_lang_specific): Likewise.
	(genrtl_named_return_value): Change prototype.
	* decl.c (original_result_rtx): Remove.
	(cp_finish_decl): Don't build DECL_STMTs for RESULT_DECLs.
	Do not generate RTL for local variables here.
	(store_return_init): Remove.
	* semantics.c (genrtl_named_return_value): Simplify.  Fold in
	store_return_init.
	(finish_named_return_value): Adjust accordingly.  Warn that this
	extension is deprecated.
	(lang_expand_stmt): Adjust call to genrtl_named_return_value.

From-SVN: r36210
This commit is contained in:
Mark Mitchell 2000-09-06 21:25:02 +00:00 committed by Mark Mitchell
parent bcf98e48ef
commit 44835fdd5d
16 changed files with 87 additions and 239 deletions

View File

@ -1,3 +1,7 @@
2000-09-06 Mark Mitchell <mark@codesourcery.com>
* extend.texi: Mark named return value extension as deprecated.
2000-09-06 Geoff Keating <geoffk@cygnus.com>
* config/rs6000/rs6000.c (rs6000_reverse_condition): Return

View File

@ -521,3 +521,5 @@ extern tree default_conversion PARAMS ((tree));
Given two compatible ANSI C types, returns the merged type. */
extern tree common_type PARAMS ((tree, tree));
extern tree expand_tree_builtin PARAMS ((tree, tree, tree));

View File

@ -1,3 +1,24 @@
2000-09-06 Mark Mitchell <mark@codesourcery.com>
* NEWS: Mention that the named return value extension has been
deprecated.
* cp-tree.h (original_result_rtx): Define.
(TREE_REFERENCE_EXPR): Remove.
(DECL_VPARENT): Likewise.
(pushdecl_nonclass_level): Likewise.
(store_return_init): Likewise.
(reinit_lang_specific): Likewise.
(genrtl_named_return_value): Change prototype.
* decl.c (original_result_rtx): Remove.
(cp_finish_decl): Don't build DECL_STMTs for RESULT_DECLs.
Do not generate RTL for local variables here.
(store_return_init): Remove.
* semantics.c (genrtl_named_return_value): Simplify. Fold in
store_return_init.
(finish_named_return_value): Adjust accordingly. Warn that this
extension is deprecated.
(lang_expand_stmt): Adjust call to genrtl_named_return_value.
2000-09-06 Nathan Sidwell <nathan@codesourcery.com>
* pt.c (type_unification_real): Replace switch with if.

View File

@ -36,6 +36,12 @@
* G++ no longer allows you to overload the conditional operator (i.e.,
the `?:' operator.)
* The "named return value" extension:
int f () return r { r = 3; }
has been deprecated, and will be removed in a future version of G++.
*** Changes in GCC 2.95:
* Messages about non-conformant code that we can still handle ("pedwarns")

View File

@ -1009,6 +1009,13 @@ struct language_function
#define doing_semantic_analysis_p() (!expanding_p)
/* If original DECL_RESULT of current function was a register,
but due to being an addressable named return value, would up
on the stack, this variable holds the named return value's
original location. */
#define original_result_rtx cp_function_chain->x_result_rtx
#define in_function_try_handler cp_function_chain->in_function_try_handler
extern tree current_function_return_value;
@ -2588,13 +2595,6 @@ extern int flag_new_for_scope;
&& CONSTRUCTOR_ELTS (NODE) == NULL_TREE \
&& ! TREE_HAS_CONSTRUCTOR (NODE))
#if 0
/* Indicates that a NON_LVALUE_EXPR came from a C++ reference.
Used to generate more helpful error message in case somebody
tries to take its address. */
#define TREE_REFERENCE_EXPR(NODE) (TREE_LANG_FLAG_3(NODE))
#endif
/* Nonzero for _TYPE means that the _TYPE defines a destructor. */
#define TYPE_HAS_DESTRUCTOR(NODE) (TYPE_LANG_FLAG_2(NODE))
@ -2804,18 +2804,6 @@ extern int flag_new_for_scope;
/* Define fields and accessors for nodes representing declared names. */
#if 0
/* C++: A derived class may be able to directly use the virtual
function table of a base class. When it does so, it may
still have a decl node used to access the virtual function
table (so that variables of this type can initialize their
virtual function table pointers by name). When such thievery
is committed, know exactly which base class's virtual function
table is the one being stolen. This effectively computes the
transitive closure. */
#define DECL_VPARENT(NODE) ((NODE)->decl.arguments)
#endif
#define TYPE_WAS_ANONYMOUS(NODE) (TYPE_LANG_SPECIFIC (NODE)->was_anonymous)
/* C++: all of these are overloaded! These apply only to TYPE_DECLs. */
@ -3903,9 +3891,6 @@ extern int duplicate_decls PARAMS ((tree, tree));
extern tree pushdecl PARAMS ((tree));
extern tree pushdecl_top_level PARAMS ((tree));
extern void pushdecl_class_level PARAMS ((tree));
#if 0
extern void pushdecl_nonclass_level PARAMS ((tree));
#endif
extern tree pushdecl_namespace_level PARAMS ((tree));
extern tree push_using_decl PARAMS ((tree, tree));
extern tree push_using_directive PARAMS ((tree));
@ -3918,9 +3903,6 @@ extern void check_goto PARAMS ((tree));
extern void define_case_label PARAMS ((void));
extern tree getdecls PARAMS ((void));
extern tree gettags PARAMS ((void));
#if 0
extern void set_current_level_tags_transparency PARAMS ((int));
#endif
extern tree binding_for_name PARAMS ((tree, tree));
extern tree namespace_binding PARAMS ((tree, tree));
extern void set_namespace_binding PARAMS ((tree, tree, tree));
@ -3974,7 +3956,6 @@ extern void build_enumerator PARAMS ((tree, tree, tree));
extern int start_function PARAMS ((tree, tree, tree, int));
extern void expand_start_early_try_stmts PARAMS ((void));
extern void store_parm_decls PARAMS ((void));
extern void store_return_init PARAMS ((tree));
extern tree finish_function PARAMS ((int));
extern tree start_method PARAMS ((tree, tree, tree));
extern tree finish_method PARAMS ((tree));
@ -4166,9 +4147,6 @@ extern tree make_call_declarator PARAMS ((tree, tree, tree, tree));
extern void set_quals_and_spec PARAMS ((tree, tree, tree));
extern void lang_init PARAMS ((void));
extern void lang_finish PARAMS ((void));
#if 0
extern void reinit_lang_specific PARAMS ((void));
#endif
extern void print_parse_statistics PARAMS ((void));
extern void extract_interface_info PARAMS ((void));
extern void do_pending_inlines PARAMS ((void));
@ -4464,8 +4442,7 @@ extern void genrtl_ctor_stmt PARAMS ((tree));
extern void genrtl_subobject PARAMS ((tree));
extern tree genrtl_do_poplevel PARAMS ((void));
extern void clear_out_block PARAMS ((void));
extern void genrtl_named_return_value PARAMS ((tree,
tree));
extern void genrtl_named_return_value PARAMS ((void));
extern tree begin_global_stmt_expr PARAMS ((void));
extern tree finish_global_stmt_expr PARAMS ((tree));

View File

@ -269,13 +269,6 @@ int in_std;
/* Expect only namespace names now. */
static int only_namespace_names;
/* If original DECL_RESULT of current function was a register,
but due to being an addressable named return value, would up
on the stack, this variable holds the named return value's
original location. */
#define original_result_rtx cp_function_chain->x_result_rtx
/* Used only for jumps to as-yet undefined labels, since jumps to
defined labels can have their validity checked immediately. */
@ -8092,7 +8085,9 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
return;
/* Add this declaration to the statement-tree. */
if (building_stmt_tree () && at_function_scope_p ())
if (building_stmt_tree ()
&& at_function_scope_p ()
&& TREE_CODE (decl) != RESULT_DECL)
add_decl_stmt (decl);
if (TYPE_HAS_MUTABLE_P (type))
@ -8215,8 +8210,7 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
{
/* If we're not building RTL, then we need to do so
now. */
if (!building_stmt_tree ())
emit_local_var (decl);
my_friendly_assert (building_stmt_tree (), 20000906);
/* Initialize the variable. */
initialize_local_var (decl, init, flags);
/* Clean up the variable. */
@ -14034,31 +14028,6 @@ store_parm_decls ()
current_eh_spec_try_block = expand_start_eh_spec ();
}
/* Bind a name and initialization to the return value of
the current function. */
void
store_return_init (decl)
tree decl;
{
/* If this named return value comes in a register, put it in a
pseudo-register. */
if (DECL_REGISTER (decl))
{
original_result_rtx = DECL_RTL (decl);
/* Note that the mode of the old DECL_RTL may be wider than the
mode of DECL_RESULT, depending on the calling conventions for
the processor. For example, on the Alpha, a 32-bit integer
is returned in a DImode register -- the DECL_RESULT has
SImode but the DECL_RTL for the DECL_RESULT has DImode. So,
here, we use the mode the back-end has already assigned for
the return value. */
DECL_RTL (decl) = gen_reg_rtx (GET_MODE (original_result_rtx));
if (TREE_ADDRESSABLE (decl))
put_var_into_stack (decl);
}
}
/* We have finished doing semantic analysis on DECL, but have not yet
generated RTL for its body. Save away our current state, so that

View File

@ -1030,55 +1030,30 @@ finish_decl_cleanup (decl, cleanup)
/* Generate the RTL for a RETURN_INIT. */
void
genrtl_named_return_value (return_id, init)
tree return_id, init;
genrtl_named_return_value ()
{
tree decl;
/* Clear this out so that finish_named_return_value can set it
again. */
DECL_NAME (DECL_RESULT (current_function_decl)) = NULL_TREE;
decl = DECL_RESULT (current_function_decl);
if (pedantic)
/* Give this error as many times as there are occurrences,
so that users can use Emacs compilation buffers to find
and fix all such places. */
pedwarn ("ISO C++ does not permit named return values");
if (return_id != NULL_TREE)
emit_local_var (decl);
/* If this named return value comes in a register, put it in a
pseudo-register. */
if (DECL_REGISTER (decl))
{
if (DECL_NAME (decl) == NULL_TREE)
{
DECL_NAME (decl) = return_id;
DECL_ASSEMBLER_NAME (decl) = return_id;
}
else
{
cp_error ("return identifier `%D' already in place", return_id);
return;
}
original_result_rtx = DECL_RTL (decl);
/* Note that the mode of the old DECL_RTL may be wider than the
mode of DECL_RESULT, depending on the calling conventions for
the processor. For example, on the Alpha, a 32-bit integer
is returned in a DImode register -- the DECL_RESULT has
SImode but the DECL_RTL for the DECL_RESULT has DImode. So,
here, we use the mode the back-end has already assigned for
the return value. */
DECL_RTL (decl) = gen_reg_rtx (GET_MODE (original_result_rtx));
if (TREE_ADDRESSABLE (decl))
put_var_into_stack (decl);
}
/* Can't let this happen for constructors. */
if (DECL_CONSTRUCTOR_P (current_function_decl))
{
error ("can't redefine default return value for constructors");
return;
}
/* If we have a named return value, put that in our scope as well. */
if (DECL_NAME (decl) != NULL_TREE)
{
/* Let `cp_finish_decl' know that this initializer is ok. */
DECL_INITIAL (decl) = init;
cp_finish_decl (decl, init, NULL_TREE, 0);
store_return_init (decl);
}
/* Don't use tree-inlining for functions with named return values.
That doesn't work properly because we don't do any translation of
the RETURN_INITs when they are copied. */
DECL_UNINLINABLE (current_function_decl) = 1;
}
/* Bind a name and initialization to the return value of
@ -1090,11 +1065,12 @@ finish_named_return_value (return_id, init)
{
tree decl = DECL_RESULT (current_function_decl);
/* Give this error as many times as there are occurrences, so that
users can use Emacs compilation buffers to find and fix all such
places. */
if (pedantic)
/* Give this error as many times as there are occurrences,
so that users can use Emacs compilation buffers to find
and fix all such places. */
pedwarn ("ISO C++ does not permit named return values");
cp_deprecated ("the named return value extension");
if (return_id != NULL_TREE)
{
@ -1124,7 +1100,13 @@ finish_named_return_value (return_id, init)
DECL_INITIAL (decl) = init;
if (doing_semantic_analysis_p ())
pushdecl (decl);
add_tree (build_stmt (RETURN_INIT, return_id, init));
if (!processing_template_decl)
{
cp_finish_decl (decl, init, NULL_TREE, 0);
add_tree (build_stmt (RETURN_INIT, NULL_TREE, NULL_TREE));
}
else
add_tree (build_stmt (RETURN_INIT, return_id, init));
}
/* Don't use tree-inlining for functions with named return values.
@ -2463,8 +2445,7 @@ lang_expand_stmt (t)
break;
case RETURN_INIT:
genrtl_named_return_value (TREE_OPERAND (t, 0),
TREE_OPERAND (t, 1));
genrtl_named_return_value ();
break;
default:

View File

@ -3333,9 +3333,11 @@ Previously it was possible to use an empty prototype parameter list to
indicate an unspecified number of parameters (like C), rather than no
parameters, as C++ demands. This feature has been removed, except where
it is required for backwards compatibility @xref{Backwards Compatibility}.
@end table
The named return value extension has been deprecated, and will be
removed from g++ at some point.
@node Backwards Compatibility
@section Backwards Compatibility
@cindex Backwards Compatibility
@ -3379,7 +3381,6 @@ test specifically for GNU C++ (@pxref{Standard Predefined,,Standard
Predefined Macros,cpp.info,The C Preprocessor}).
@menu
* Naming Results:: Giving a name to C++ function return values.
* Min and Max:: C++ Minimum and maximum operators.
* Volatiles:: What constitutes an access to a volatile object.
* Restricted Pointers:: C99 restricted pointers and references.
@ -3391,119 +3392,6 @@ Predefined Macros,cpp.info,The C Preprocessor}).
method denoted by a @samp{->*} or @samp{.*} expression.
@end menu
@node Naming Results
@section Named Return Values in C++
@cindex @code{return}, in C++ function header
@cindex return value, named, in C++
@cindex named return value in C++
@cindex C++ named return value
GNU C++ extends the function-definition syntax to allow you to specify a
name for the result of a function outside the body of the definition, in
C++ programs:
@example
@group
@var{type}
@var{functionname} (@var{args}) return @var{resultname};
@{
@dots{}
@var{body}
@dots{}
@}
@end group
@end example
You can use this feature to avoid an extra constructor call when
a function result has a class type. For example, consider a function
@code{m}, declared as @w{@samp{X v = m ();}}, whose result is of class
@code{X}:
@example
X
m ()
@{
X b;
b.a = 23;
return b;
@}
@end example
@cindex implicit argument: return value
Although @code{m} appears to have no arguments, in fact it has one implicit
argument: the address of the return value. At invocation, the address
of enough space to hold @code{v} is sent in as the implicit argument.
Then @code{b} is constructed and its @code{a} field is set to the value
23. Finally, a copy constructor (a constructor of the form @samp{X(X&)})
is applied to @code{b}, with the (implicit) return value location as the
target, so that @code{v} is now bound to the return value.
But this is wasteful. The local @code{b} is declared just to hold
something that will be copied right out. While a compiler that
combined an ``elision'' algorithm with interprocedural data flow
analysis could conceivably eliminate all of this, it is much more
practical to allow you to assist the compiler in generating
efficient code by manipulating the return value explicitly,
thus avoiding the local variable and copy constructor altogether.
Using the extended GNU C++ function-definition syntax, you can avoid the
temporary allocation and copying by naming @code{r} as your return value
at the outset, and assigning to its @code{a} field directly:
@example
X
m () return r;
@{
r.a = 23;
@}
@end example
@noindent
The declaration of @code{r} is a standard, proper declaration, whose effects
are executed @strong{before} any of the body of @code{m}.
Functions of this type impose no additional restrictions; in particular,
you can execute @code{return} statements, or return implicitly by
reaching the end of the function body (``falling off the edge'').
Cases like
@example
X
m () return r (23);
@{
return;
@}
@end example
@noindent
(or even @w{@samp{X m () return r (23); @{ @}}}) are unambiguous, since
the return value @code{r} has been initialized in either case. The
following code may be hard to read, but also works predictably:
@example
X
m () return r;
@{
X b;
return b;
@}
@end example
The return value slot denoted by @code{r} is initialized at the outset,
but the statement @samp{return b;} overrides this value. The compiler
deals with this by destroying @code{r} (calling the destructor if there
is one, or doing nothing if there is not), and then reinitializing
@code{r} with @code{b}.
This extension is provided primarily to help people who use overloaded
operators, where there is a great need to control not just the
arguments, but the return values of functions. For classes where the
copy constructor incurs a heavy performance penalty (especially in the
common case where there is a quick default constructor), this is a major
savings. The disadvantage of this extension is that you do not control
when the default constructor for the return value is called: it is
always called at the beginning.
@node Min and Max
@section Minimum and Maximum Operators in C++

View File

@ -1,5 +1,5 @@
// Build don't link:
// Special g++ Options:
// Special g++ Options: -Wno-deprecated
// prms-id: 13417
class Foo {

View File

@ -1,6 +1,6 @@
// Test that the named return value extension works when passed as a reference.
// Origin: Jason Merrill <jason@redhat.com>
// Special g++ Options:
// Special g++ Options: -Wno-deprecated
void f (int &i)
{

View File

@ -6,7 +6,7 @@
*/
// Special g++ Options:
// Special g++ Options: -Wno-deprecated
extern "C"
{

View File

@ -1,4 +1,4 @@
// Special g++ Options:
// Special g++ Options: -Wno-deprecated
// prms-id: 700
//# 1 "../../../../libg++/etc/benchmarks/dhrystone.cc"

View File

@ -1,11 +1,11 @@
// Build don't link:
// Copyright (C) 1999 Free Software Foundation
// Copyright (C) 1999, 2000 Free Software Foundation
// by Alexandre Oliva <oliva@lsd.ic.unicamp.br>
// distilled from libg++'s Rational.cc
// Special g++ Options:
// Special g++ Options: -Wno-deprecated
inline int bar () return r {}

View File

@ -1,11 +1,11 @@
// Build don't link:
// Copyright (C) 1999 Free Software Foundation
// Copyright (C) 1999, 2000 Free Software Foundation
// by Alexandre Oliva <oliva@lsd.ic.unicamp.br>
// distilled from libg++'s Integer.cc
// Special g++ Options: -O1
// Special g++ Options: -O1 -Wno-deprecated
inline int bar () return r {}

View File

@ -1,4 +1,4 @@
// Special g++ Options: -fcheck-memory-usage
// Special g++ Options: -fcheck-memory-usage -Wno-deprecated
// Build don't link:

View File

@ -2,7 +2,7 @@
/* simple program to demonstrate the bug with named return values in gcc
*/
/* (w) 4.9.97 by Kurt Garloff <K.Garloff@ping.de> */
// Special g++ Options:
// Special g++ Options: -Wno-deprecated
// 8/28/1998 - This dies in add_conversions from dfs_walk, null CLASSTYPE_METHOD_VEC
// for the test<T> record_type. This is marked as an expected failure for now,
// until we actually fix it.