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.
*** gcc/extend.texi 2000/08/11 13:42:32 1.62
--- gcc/extend.texi 2000/09/06 21:14:49
*************** Previously it was possible to use an emp
*** 3333,3341 ****
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
@node Backwards Compatibility
@section Backwards Compatibility
@cindex Backwards Compatibility
--- 3333,3343 ----
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
*************** test specifically for GNU C++ (@pxref{St
*** 3379,3385 ****
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.
--- 3381,3386 ----
*************** Predefined Macros,cpp.info,The C Preproc
*** 3390,3508 ****
* Bound member functions:: You can extract a function pointer to the
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++
--- 3391,3396 ----
*** gcc/cp/NEWS 2000/05/31 19:27:11 1.24
--- gcc/cp/NEWS 2000/09/06 21:14:50
***************
*** 36,41 ****
--- 36,47 ----
* 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")
*** gcc/cp/cp-tree.h 2000/09/06 05:52:51 1.522
--- gcc/cp/cp-tree.h 2000/09/06 21:14:53
*************** struct language_function
*** 1009,1014 ****
--- 1009,1021 ----
#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;
*************** extern int flag_new_for_scope;
*** 2588,2600 ****
&& 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))
--- 2595,2600 ----
*************** extern int flag_new_for_scope;
*** 2804,2821 ****
/* 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. */
--- 2804,2809 ----
*************** extern int duplicate_decls PARAMS ((tr
*** 3903,3911 ****
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));
--- 3891,3896 ----
*************** extern void check_goto PARAMS ((tree)
*** 3918,3926 ****
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));
--- 3903,3908 ----
*************** extern void build_enumerator PARAMS ((
*** 3974,3980 ****
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));
--- 3956,3961 ----
*************** extern tree make_call_declarator PARAMS
*** 4166,4174 ****
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));
--- 4147,4152 ----
*************** extern void genrtl_ctor_stmt
*** 4464,4471 ****
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 tree begin_global_stmt_expr PARAMS ((void));
extern tree finish_global_stmt_expr PARAMS ((tree));
--- 4442,4448 ----
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 ((void));
extern tree begin_global_stmt_expr PARAMS ((void));
extern tree finish_global_stmt_expr PARAMS ((tree));
*** gcc/cp/decl.c 2000/09/06 08:53:44 1.682
--- gcc/cp/decl.c 2000/09/06 21:15:02
*************** int in_std;
*** 269,281 ****
/* 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. */
--- 269,274 ----
*************** cp_finish_decl (decl, init, asmspec_tree
*** 8092,8098 ****
return;
/* Add this declaration to the statement-tree. */
! if (building_stmt_tree () && at_function_scope_p ())
add_decl_stmt (decl);
if (TYPE_HAS_MUTABLE_P (type))
--- 8085,8093 ----
return;
/* Add this declaration to the statement-tree. */
! if (building_stmt_tree ()
! && at_function_scope_p ()
! && TREE_CODE (decl) != RESULT_DECL)
add_decl_stmt (decl);
if (TYPE_HAS_MUTABLE_P (type))
*************** cp_finish_decl (decl, init, asmspec_tree
*** 8215,8222 ****
{
/* If we're not building RTL, then we need to do so
now. */
! if (!building_stmt_tree ())
! emit_local_var (decl);
/* Initialize the variable. */
initialize_local_var (decl, init, flags);
/* Clean up the variable. */
--- 8210,8216 ----
{
/* If we're not building RTL, then we need to do so
now. */
! my_friendly_assert (building_stmt_tree (), 20000906);
/* Initialize the variable. */
initialize_local_var (decl, init, flags);
/* Clean up the variable. */
*************** store_parm_decls ()
*** 14032,14062 ****
&& building_stmt_tree ()
&& TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)))
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);
- }
}
--- 14026,14031 ----
*** gcc/cp/semantics.c 2000/09/06 05:52:51 1.167
--- gcc/cp/semantics.c 2000/09/06 21:15:04
*************** finish_decl_cleanup (decl, cleanup)
*** 1030,1084 ****
/* Generate the RTL for a RETURN_INIT. */
void
! genrtl_named_return_value (return_id, init)
! tree return_id, init;
{
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)
- {
- 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;
- }
- }
! /* 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
--- 1030,1059 ----
/* Generate the RTL for a RETURN_INIT. */
void
! genrtl_named_return_value ()
{
tree decl;
decl = DECL_RESULT (current_function_decl);
! emit_local_var (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);
}
}
/* Bind a name and initialization to the return value of
*************** finish_named_return_value (return_id, in
*** 1090,1100 ****
{
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)
{
--- 1065,1076 ----
{
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)
pedwarn ("ISO C++ does not permit named return values");
+ cp_deprecated ("the named return value extension");
if (return_id != NULL_TREE)
{
*************** finish_named_return_value (return_id, in
*** 1124,1130 ****
DECL_INITIAL (decl) = init;
if (doing_semantic_analysis_p ())
pushdecl (decl);
! add_tree (build_stmt (RETURN_INIT, return_id, init));
}
/* Don't use tree-inlining for functions with named return values.
--- 1100,1112 ----
DECL_INITIAL (decl) = init;
if (doing_semantic_analysis_p ())
pushdecl (decl);
! 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.
*************** lang_expand_stmt (t)
*** 2463,2470 ****
break;
case RETURN_INIT:
! genrtl_named_return_value (TREE_OPERAND (t, 0),
! TREE_OPERAND (t, 1));
break;
default:
--- 2445,2451 ----
break;
case RETURN_INIT:
! genrtl_named_return_value ();
break;
default:
*** gcc/testsuite/g++.old-deja/g++.benjamin/p13417.C 1998/12/16 21:22:08 1.2
--- gcc/testsuite/g++.old-deja/g++.benjamin/p13417.C 2000/09/06 21:15:04
***************
*** 1,5 ****
// Build don't link:
! // Special g++ Options:
// prms-id: 13417
class Foo {
--- 1,5 ----
// Build don't link:
! // Special g++ Options: -Wno-deprecated
// prms-id: 13417
class Foo {
*** gcc/testsuite/g++.old-deja/g++.ext/return1.C 2000/06/02 18:19:02 1.2
--- gcc/testsuite/g++.old-deja/g++.ext/return1.C 2000/09/06 21:15:04
***************
*** 1,6 ****
// Test that the named return value extension works when passed as a reference.
// Origin: Jason Merrill <jason@redhat.com>
! // Special g++ Options:
void f (int &i)
{
--- 1,6 ----
// Test that the named return value extension works when passed as a reference.
// Origin: Jason Merrill <jason@redhat.com>
! // Special g++ Options: -Wno-deprecated
void f (int &i)
{
*** gcc/testsuite/g++.old-deja/g++.mike/p646.C 2000/07/04 07:47:10 1.4
--- gcc/testsuite/g++.old-deja/g++.mike/p646.C 2000/09/06 21:15:05
***************
*** 6,12 ****
*/
! // Special g++ Options:
extern "C"
{
--- 6,12 ----
*/
! // Special g++ Options: -Wno-deprecated
extern "C"
{
*** gcc/testsuite/g++.old-deja/g++.mike/p700.C 2000/07/25 20:11:43 1.4
--- gcc/testsuite/g++.old-deja/g++.mike/p700.C 2000/09/06 21:15:05
***************
*** 1,4 ****
! // Special g++ Options:
// prms-id: 700
//# 1 "../../../../libg++/etc/benchmarks/dhrystone.cc"
--- 1,4 ----
! // Special g++ Options: -Wno-deprecated
// prms-id: 700
//# 1 "../../../../libg++/etc/benchmarks/dhrystone.cc"
*** gcc/testsuite/g++.old-deja/g++.oliva/nameret1.C 1999/12/26 15:28:17 1.2
--- gcc/testsuite/g++.old-deja/g++.oliva/nameret1.C 2000/09/06 21:15:06
***************
*** 1,11 ****
// Build don't link:
! // Copyright (C) 1999 Free Software Foundation
// by Alexandre Oliva <oliva@lsd.ic.unicamp.br>
// distilled from libg++'s Rational.cc
! // Special g++ Options:
inline int bar () return r {}
--- 1,11 ----
// Build don't link:
! // Copyright (C) 1999, 2000 Free Software Foundation
// by Alexandre Oliva <oliva@lsd.ic.unicamp.br>
// distilled from libg++'s Rational.cc
! // Special g++ Options: -Wno-deprecated
inline int bar () return r {}
*** gcc/testsuite/g++.old-deja/g++.oliva/nameret2.C 1999/12/26 15:28:17 1.4
--- gcc/testsuite/g++.old-deja/g++.oliva/nameret2.C 2000/09/06 21:15:06
***************
*** 1,11 ****
// Build don't link:
! // Copyright (C) 1999 Free Software Foundation
// by Alexandre Oliva <oliva@lsd.ic.unicamp.br>
// distilled from libg++'s Integer.cc
! // Special g++ Options: -O1
inline int bar () return r {}
--- 1,11 ----
// Build don't link:
! // 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 -Wno-deprecated
inline int bar () return r {}
*** gcc/testsuite/g++.old-deja/g++.robertl/eb101.C 1999/04/29 08:33:55 1.4
--- gcc/testsuite/g++.old-deja/g++.robertl/eb101.C 2000/09/06 21:15:07
***************
*** 1,4 ****
! // Special g++ Options: -fcheck-memory-usage
// Build don't link:
--- 1,4 ----
! // Special g++ Options: -fcheck-memory-usage -Wno-deprecated
// Build don't link:
*** gcc/testsuite/g++.old-deja/g++.robertl/eb27.C 1998/12/16 22:03:42 1.8
--- gcc/testsuite/g++.old-deja/g++.robertl/eb27.C 2000/09/06 21:15:07
***************
*** 2,8 ****
/* 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:
// 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.
--- 2,8 ----
/* 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: -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.