diff options
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/c-common.h | 2 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/cp/NEWS | 6 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 39 | ||||
-rw-r--r-- | gcc/cp/decl.c | 39 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 75 | ||||
-rw-r--r-- | gcc/extend.texi | 118 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.benjamin/p13417.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.ext/return1.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.mike/p646.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.mike/p700.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.oliva/nameret1.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.oliva/nameret2.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.robertl/eb101.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.robertl/eb27.C | 2 |
16 files changed, 86 insertions, 238 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e1f6560..ef138d7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/c-common.h b/gcc/c-common.h index bec5214..900b77c 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -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)); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7d49a32..6dd4b94 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/NEWS b/gcc/cp/NEWS index 3a8fc4c..d2c483d 100644 --- a/gcc/cp/NEWS +++ b/gcc/cp/NEWS @@ -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") diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 0a62dfe..f54891c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 8537981..b363266 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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 diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 295c37a..6c9a5a6 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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) - { - 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; - } - } + emit_local_var (decl); - /* Can't let this happen for constructors. */ - if (DECL_CONSTRUCTOR_P (current_function_decl)) + /* If this named return value comes in a register, put it in a + pseudo-register. */ + if (DECL_REGISTER (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); + 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); } - - /* 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: diff --git a/gcc/extend.texi b/gcc/extend.texi index 7ec85bf..4fc1a53 100644 --- a/gcc/extend.texi +++ b/gcc/extend.texi @@ -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++ diff --git a/gcc/testsuite/g++.old-deja/g++.benjamin/p13417.C b/gcc/testsuite/g++.old-deja/g++.benjamin/p13417.C index 18d62e8..ddf02f5 100644 --- a/gcc/testsuite/g++.old-deja/g++.benjamin/p13417.C +++ b/gcc/testsuite/g++.old-deja/g++.benjamin/p13417.C @@ -1,5 +1,5 @@ // Build don't link: -// Special g++ Options: +// Special g++ Options: -Wno-deprecated // prms-id: 13417 class Foo { diff --git a/gcc/testsuite/g++.old-deja/g++.ext/return1.C b/gcc/testsuite/g++.old-deja/g++.ext/return1.C index 9cf0766..29e1fc3 100644 --- a/gcc/testsuite/g++.old-deja/g++.ext/return1.C +++ b/gcc/testsuite/g++.old-deja/g++.ext/return1.C @@ -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) { diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p646.C b/gcc/testsuite/g++.old-deja/g++.mike/p646.C index 3c07476..c1a9622 100644 --- a/gcc/testsuite/g++.old-deja/g++.mike/p646.C +++ b/gcc/testsuite/g++.old-deja/g++.mike/p646.C @@ -6,7 +6,7 @@ */ -// Special g++ Options: +// Special g++ Options: -Wno-deprecated extern "C" { diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p700.C b/gcc/testsuite/g++.old-deja/g++.mike/p700.C index 345831a..eabc42d 100644 --- a/gcc/testsuite/g++.old-deja/g++.mike/p700.C +++ b/gcc/testsuite/g++.old-deja/g++.mike/p700.C @@ -1,4 +1,4 @@ -// Special g++ Options: +// Special g++ Options: -Wno-deprecated // prms-id: 700 //# 1 "../../../../libg++/etc/benchmarks/dhrystone.cc" diff --git a/gcc/testsuite/g++.old-deja/g++.oliva/nameret1.C b/gcc/testsuite/g++.old-deja/g++.oliva/nameret1.C index 88bc4666..6cb5c9e 100644 --- a/gcc/testsuite/g++.old-deja/g++.oliva/nameret1.C +++ b/gcc/testsuite/g++.old-deja/g++.oliva/nameret1.C @@ -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 {} diff --git a/gcc/testsuite/g++.old-deja/g++.oliva/nameret2.C b/gcc/testsuite/g++.old-deja/g++.oliva/nameret2.C index 3a69edf..f54d55c 100644 --- a/gcc/testsuite/g++.old-deja/g++.oliva/nameret2.C +++ b/gcc/testsuite/g++.old-deja/g++.oliva/nameret2.C @@ -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 {} diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb101.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb101.C index 74c6cbb..f605d93 100644 --- a/gcc/testsuite/g++.old-deja/g++.robertl/eb101.C +++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb101.C @@ -1,4 +1,4 @@ -// Special g++ Options: -fcheck-memory-usage +// Special g++ Options: -fcheck-memory-usage -Wno-deprecated // Build don't link: diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb27.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb27.C index 9e44f3a..31012be 100644 --- a/gcc/testsuite/g++.old-deja/g++.robertl/eb27.C +++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb27.C @@ -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. |