Under the new ABI, constructors don't return `this'.
* cp-tree.h (warn_reorder): Declare. (special_function_kind): New enum. (global_base_init_list): Remove declaration. (emit_base_init): Don't return a value. (check_base_init): Don't declare. (is_aggr_typedef): Likewise. * decl.c (check_special_function_return_type): New function. (return_types): Remove. (grokdeclarator): Use check_special_function_return_type. (start_function): Don't initialize ctor_label under the new ABI. (finish_construtor_body): Don't create a corresponding LABEL_STMT. * init.c (begin_init_stmts): Move to top of file. (finish_init_stmts): Likewise. (warn_reorder): Don't declare. (emit_base_init): Don't create a STMT_EXPR here. Don't return a value. (check_base_init): Remove. (is_aggr_typedef): Likewise. (build_new_1): Don't use the return value of a constructor. * semantics.c (setup_vtbl_ptr): Don't use the return value of emit_base_init. * typeck.c (check_return_expr): Don't magically convert return statements into `return this' in constructors under the new ABI. From-SVN: r33035
This commit is contained in:
parent
4eaf5996ad
commit
3dbc07b651
|
@ -1,5 +1,30 @@
|
|||
2000-04-08 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
Under the new ABI, constructors don't return `this'.
|
||||
* cp-tree.h (warn_reorder): Declare.
|
||||
(special_function_kind): New enum.
|
||||
(global_base_init_list): Remove declaration.
|
||||
(emit_base_init): Don't return a value.
|
||||
(check_base_init): Don't declare.
|
||||
(is_aggr_typedef): Likewise.
|
||||
* decl.c (check_special_function_return_type): New function.
|
||||
(return_types): Remove.
|
||||
(grokdeclarator): Use check_special_function_return_type.
|
||||
(start_function): Don't initialize ctor_label under the new ABI.
|
||||
(finish_construtor_body): Don't create a corresponding LABEL_STMT.
|
||||
* init.c (begin_init_stmts): Move to top of file.
|
||||
(finish_init_stmts): Likewise.
|
||||
(warn_reorder): Don't declare.
|
||||
(emit_base_init): Don't create a STMT_EXPR here. Don't return a
|
||||
value.
|
||||
(check_base_init): Remove.
|
||||
(is_aggr_typedef): Likewise.
|
||||
(build_new_1): Don't use the return value of a constructor.
|
||||
* semantics.c (setup_vtbl_ptr): Don't use the return value
|
||||
of emit_base_init.
|
||||
* typeck.c (check_return_expr): Don't magically convert return
|
||||
statements into `return this' in constructors under the new ABI.
|
||||
|
||||
* cp-tree.h (cp_tree_index): Add CPTI_BASE_CTOR_IDENTIFIER,
|
||||
CPTI_BASE_DTOR_IDENTIFIER, and CPTI_DELETING_DTOR_IDENTIFIER.
|
||||
(base_ctor_identifier): New macro.
|
||||
|
|
|
@ -1102,6 +1102,10 @@ extern int warn_extern_inline;
|
|||
|
||||
extern int warn_old_style_cast;
|
||||
|
||||
/* Non-zero means warn when the compiler will reorder code. */
|
||||
|
||||
extern int warn_reorder;
|
||||
|
||||
/* Nonzero means to treat bitfields as unsigned unless they say `signed'. */
|
||||
|
||||
extern int flag_signed_bitfields;
|
||||
|
@ -3098,6 +3102,13 @@ typedef enum access_kind {
|
|||
ak_private = 3 /* Accessible, as a `private' thing. */
|
||||
} access_kind;
|
||||
|
||||
typedef enum special_function_kind {
|
||||
sfk_none, /* Not a special function. */
|
||||
sfk_constructor, /* A constructor. */
|
||||
sfk_destructor, /* A destructor. */
|
||||
sfk_conversion /* A conversion operator. */
|
||||
} special_function_kind;
|
||||
|
||||
/* Zero means prototype weakly, as in ANSI C (no args means nothing).
|
||||
Each language context defines how this variable should be set. */
|
||||
extern int strict_prototype;
|
||||
|
@ -3217,10 +3228,6 @@ extern int current_class_depth;
|
|||
/* Points to the name of that function. May not be the DECL_NAME
|
||||
of CURRENT_FUNCTION_DECL due to overloading */
|
||||
extern tree original_function_name;
|
||||
|
||||
/* in init.c */
|
||||
extern tree global_base_init_list;
|
||||
|
||||
|
||||
/* Here's where we control how name mangling takes place. */
|
||||
|
||||
|
@ -3999,11 +4006,9 @@ extern tree do_friend PARAMS ((tree, tree, tree, tree, tree, enum overload_fl
|
|||
|
||||
/* in init.c */
|
||||
extern void init_init_processing PARAMS ((void));
|
||||
extern tree emit_base_init PARAMS ((tree));
|
||||
extern void check_base_init PARAMS ((tree));
|
||||
extern void emit_base_init PARAMS ((tree));
|
||||
extern void expand_member_init PARAMS ((tree, tree, tree));
|
||||
extern tree build_aggr_init PARAMS ((tree, tree, int));
|
||||
extern int is_aggr_typedef PARAMS ((tree, int));
|
||||
extern int is_aggr_type PARAMS ((tree, int));
|
||||
extern tree get_aggr_from_typedef PARAMS ((tree, int));
|
||||
extern tree get_type_value PARAMS ((tree));
|
||||
|
|
148
gcc/cp/decl.c
148
gcc/cp/decl.c
|
@ -178,6 +178,8 @@ static tree start_cleanup_fn PARAMS ((void));
|
|||
static void end_cleanup_fn PARAMS ((void));
|
||||
static tree cp_make_fname_decl PARAMS ((tree, const char *, int));
|
||||
static void initialize_predefined_identifiers PARAMS ((void));
|
||||
static tree check_special_function_return_type
|
||||
PARAMS ((special_function_kind, tree, tree, tree));
|
||||
|
||||
#if defined (DEBUG_CP_BINDING_LEVELS)
|
||||
static void indent PARAMS ((void));
|
||||
|
@ -9298,6 +9300,54 @@ create_array_type_for_decl (name, type, size)
|
|||
return build_cplus_array_type (type, itype);
|
||||
}
|
||||
|
||||
/* Check that it's OK to declare a function with the indicated TYPE.
|
||||
SFK indicates the kind of special function (if any) that this
|
||||
function is. CTYPE is the class of which this function is a
|
||||
member. OPTYPE is the type given in a conversion operator
|
||||
declaration. Returns the actual return type of the function; that
|
||||
may be different than TYPE if an error occurs, or for certain
|
||||
special functions. */
|
||||
|
||||
static tree
|
||||
check_special_function_return_type (sfk, type, ctype, optype)
|
||||
special_function_kind sfk;
|
||||
tree type;
|
||||
tree ctype;
|
||||
tree optype;
|
||||
{
|
||||
switch (sfk)
|
||||
{
|
||||
case sfk_constructor:
|
||||
if (type)
|
||||
cp_error ("return type specification for constructor invalid");
|
||||
|
||||
/* In the old ABI, we return `this'; in the new ABI we don't
|
||||
bother. */
|
||||
type = flag_new_abi ? void_type_node : build_pointer_type (ctype);
|
||||
break;
|
||||
|
||||
case sfk_destructor:
|
||||
if (type)
|
||||
cp_error ("return type specification for destructor invalid");
|
||||
type = void_type_node;
|
||||
break;
|
||||
|
||||
case sfk_conversion:
|
||||
if (type && !same_type_p (type, optype))
|
||||
cp_error ("operator `%T' declared to return `%T'", optype, type);
|
||||
else if (type)
|
||||
cp_pedwarn ("return type specified for `operator %T'", optype);
|
||||
type = optype;
|
||||
break;
|
||||
|
||||
default:
|
||||
my_friendly_abort (20000408);
|
||||
break;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/* Given declspecs and a declarator,
|
||||
determine the name and type of the object declared
|
||||
and construct a ..._DECL node for it.
|
||||
|
@ -9358,8 +9408,6 @@ create_array_type_for_decl (name, type, size)
|
|||
May return void_type_node if the declarator turned out to be a friend.
|
||||
See grokfield for details. */
|
||||
|
||||
enum return_types { return_normal, return_ctor, return_dtor, return_conversion };
|
||||
|
||||
tree
|
||||
grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
tree declspecs;
|
||||
|
@ -9398,7 +9446,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
|||
/* Keep track of what sort of function is being processed
|
||||
so that we can warn about default return values, or explicit
|
||||
return values which do not match prescribed defaults. */
|
||||
enum return_types return_type = return_normal;
|
||||
special_function_kind sfk = sfk_none;
|
||||
|
||||
tree dname = NULL_TREE;
|
||||
tree ctype = current_class_type;
|
||||
|
@ -9448,7 +9496,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
|||
|
||||
my_friendly_assert (flags == NO_SPECIAL, 152);
|
||||
flags = DTOR_FLAG;
|
||||
return_type = return_dtor;
|
||||
sfk = sfk_destructor;
|
||||
if (TREE_CODE (name) == TYPE_DECL)
|
||||
TREE_OPERAND (decl, 0) = name = constructor_name (name);
|
||||
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 153);
|
||||
|
@ -9547,7 +9595,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
|||
&& decl != NULL_TREE && flags != DTOR_FLAG
|
||||
&& decl == constructor_name (ctype))
|
||||
{
|
||||
return_type = return_ctor;
|
||||
sfk = sfk_constructor;
|
||||
ctor_return_type = ctype;
|
||||
}
|
||||
ctype = NULL_TREE;
|
||||
|
@ -9595,7 +9643,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
|||
my_friendly_assert (flags == NO_SPECIAL, 154);
|
||||
flags = TYPENAME_FLAG;
|
||||
ctor_return_type = TREE_TYPE (dname);
|
||||
return_type = return_conversion;
|
||||
sfk = sfk_conversion;
|
||||
}
|
||||
name = operator_name_string (dname);
|
||||
}
|
||||
|
@ -9659,7 +9707,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
|||
if (TREE_CODE (decl) == IDENTIFIER_NODE
|
||||
&& constructor_name (ctype) == decl)
|
||||
{
|
||||
return_type = return_ctor;
|
||||
sfk = sfk_constructor;
|
||||
ctor_return_type = ctype;
|
||||
}
|
||||
else if (TREE_CODE (decl) == BIT_NOT_EXPR
|
||||
|
@ -9667,7 +9715,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
|||
&& (constructor_name (ctype) == TREE_OPERAND (decl, 0)
|
||||
|| constructor_name_full (ctype) == TREE_OPERAND (decl, 0)))
|
||||
{
|
||||
return_type = return_dtor;
|
||||
sfk = sfk_destructor;
|
||||
ctor_return_type = ctype;
|
||||
flags = DTOR_FLAG;
|
||||
TREE_OPERAND (decl, 0) = constructor_name (ctype);
|
||||
|
@ -9883,58 +9931,35 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
|||
defaulted_int = 1;
|
||||
}
|
||||
|
||||
if (type == NULL_TREE)
|
||||
if (sfk != sfk_none)
|
||||
type = check_special_function_return_type (sfk, type,
|
||||
ctor_return_type,
|
||||
ctor_return_type);
|
||||
else if (type == NULL_TREE)
|
||||
{
|
||||
int is_main;
|
||||
|
||||
explicit_int = -1;
|
||||
if (return_type == return_dtor)
|
||||
type = void_type_node;
|
||||
else if (return_type == return_ctor)
|
||||
type = build_pointer_type (ctor_return_type);
|
||||
else if (return_type == return_conversion)
|
||||
type = ctor_return_type;
|
||||
else
|
||||
{
|
||||
|
||||
/* We handle `main' specially here, because 'main () { }' is so
|
||||
common. With no options, it is allowed. With -Wreturn-type,
|
||||
it is a warning. It is only an error with -pedantic-errors. */
|
||||
int is_main = (funcdef_flag
|
||||
&& MAIN_NAME_P (dname)
|
||||
&& ctype == NULL_TREE
|
||||
&& in_namespace == NULL_TREE
|
||||
&& current_namespace == global_namespace);
|
||||
is_main = (funcdef_flag
|
||||
&& MAIN_NAME_P (dname)
|
||||
&& ctype == NULL_TREE
|
||||
&& in_namespace == NULL_TREE
|
||||
&& current_namespace == global_namespace);
|
||||
|
||||
if (in_system_header || flag_ms_extensions)
|
||||
/* Allow it, sigh. */;
|
||||
else if (pedantic || ! is_main)
|
||||
cp_pedwarn ("ISO C++ forbids declaration of `%s' with no type",
|
||||
name);
|
||||
else if (warn_return_type)
|
||||
cp_warning ("ISO C++ forbids declaration of `%s' with no type",
|
||||
name);
|
||||
if (in_system_header || flag_ms_extensions)
|
||||
/* Allow it, sigh. */;
|
||||
else if (pedantic || ! is_main)
|
||||
cp_pedwarn ("ISO C++ forbids declaration of `%s' with no type",
|
||||
name);
|
||||
else if (warn_return_type)
|
||||
cp_warning ("ISO C++ forbids declaration of `%s' with no type",
|
||||
name);
|
||||
|
||||
type = integer_type_node;
|
||||
}
|
||||
}
|
||||
else if (return_type == return_dtor)
|
||||
{
|
||||
error ("return type specification for destructor invalid");
|
||||
type = void_type_node;
|
||||
}
|
||||
else if (return_type == return_ctor)
|
||||
{
|
||||
error ("return type specification for constructor invalid");
|
||||
type = build_pointer_type (ctor_return_type);
|
||||
}
|
||||
else if (return_type == return_conversion)
|
||||
{
|
||||
if (!same_type_p (type, ctor_return_type))
|
||||
cp_error ("operator `%T' declared to return `%T'",
|
||||
ctor_return_type, type);
|
||||
else
|
||||
cp_pedwarn ("return type specified for `operator %T'",
|
||||
ctor_return_type);
|
||||
|
||||
type = ctor_return_type;
|
||||
type = integer_type_node;
|
||||
}
|
||||
|
||||
ctype = NULL_TREE;
|
||||
|
@ -10079,7 +10104,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
|||
type = build_complex_type (type);
|
||||
}
|
||||
|
||||
if (return_type == return_conversion
|
||||
if (sfk == sfk_conversion
|
||||
&& (RIDBIT_SETP (RID_CONST, specbits)
|
||||
|| RIDBIT_SETP (RID_VOLATILE, specbits)
|
||||
|| RIDBIT_SETP (RID_RESTRICT, specbits)))
|
||||
|
@ -10376,7 +10401,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
|||
&& (friendp == 0 || dname == current_class_name))
|
||||
ctype = current_class_type;
|
||||
|
||||
if (ctype && return_type == return_conversion)
|
||||
if (ctype && sfk == sfk_conversion)
|
||||
TYPE_HAS_CONVERSION (ctype) = 1;
|
||||
if (ctype && constructor_name (ctype) == dname)
|
||||
{
|
||||
|
@ -10435,7 +10460,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
|||
if (RIDBIT_ANY_SET (tmp_bits))
|
||||
error ("return value type specifier for constructor ignored");
|
||||
}
|
||||
type = build_pointer_type (ctype);
|
||||
if (decl_context == FIELD)
|
||||
{
|
||||
if (! member_function_or_else (ctype,
|
||||
|
@ -10443,7 +10467,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
|||
flags))
|
||||
return void_type_node;
|
||||
TYPE_HAS_CONSTRUCTOR (ctype) = 1;
|
||||
if (return_type != return_ctor)
|
||||
if (sfk != sfk_constructor)
|
||||
return NULL_TREE;
|
||||
}
|
||||
}
|
||||
|
@ -13532,7 +13556,12 @@ start_function (declspecs, declarator, attrs, flags)
|
|||
dtor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
|
||||
DECL_CONTEXT (dtor_label) = current_function_decl;
|
||||
}
|
||||
else if (DECL_CONSTRUCTOR_P (decl1))
|
||||
/* Under the old ABI we return `this' from constructors, so we make
|
||||
ordinary `return' statements in constructors jump to CTOR_LABEL;
|
||||
from there we return `this'. Under the new ABI, we don't bother
|
||||
with any of this. By not setting CTOR_LABEL the remainder of the
|
||||
machinery is automatically disabled. */
|
||||
else if (!flag_new_abi && DECL_CONSTRUCTOR_P (decl1))
|
||||
{
|
||||
ctor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
|
||||
DECL_CONTEXT (ctor_label) = current_function_decl;
|
||||
|
@ -13764,7 +13793,8 @@ static void
|
|||
finish_constructor_body ()
|
||||
{
|
||||
/* Any return from a constructor will end up here. */
|
||||
add_tree (build_min_nt (LABEL_STMT, ctor_label));
|
||||
if (ctor_label)
|
||||
add_tree (build_min_nt (LABEL_STMT, ctor_label));
|
||||
|
||||
/* Clear CTOR_LABEL so that finish_return_stmt knows to really
|
||||
generate the return, rather than a goto to CTOR_LABEL. */
|
||||
|
|
149
gcc/cp/init.c
149
gcc/cp/init.c
|
@ -79,6 +79,45 @@ void init_init_processing ()
|
|||
ggc_add_tree_root (&BI_header_size, 1);
|
||||
}
|
||||
|
||||
/* We are about to generate some complex initialization code.
|
||||
Conceptually, it is all a single expression. However, we may want
|
||||
to include conditionals, loops, and other such statement-level
|
||||
constructs. Therefore, we build the initialization code inside a
|
||||
statement-expression. This function starts such an expression.
|
||||
STMT_EXPR_P and COMPOUND_STMT_P are filled in by this function;
|
||||
pass them back to finish_init_stmts when the expression is
|
||||
complete. */
|
||||
|
||||
void
|
||||
begin_init_stmts (stmt_expr_p, compound_stmt_p)
|
||||
tree *stmt_expr_p;
|
||||
tree *compound_stmt_p;
|
||||
{
|
||||
*stmt_expr_p = begin_stmt_expr ();
|
||||
*compound_stmt_p = begin_compound_stmt (/*has_no_scope=*/1);
|
||||
}
|
||||
|
||||
/* Finish out the statement-expression begun by the previous call to
|
||||
begin_init_stmts. Returns the statement-expression itself. */
|
||||
|
||||
tree
|
||||
finish_init_stmts (stmt_expr, compound_stmt)
|
||||
tree stmt_expr;
|
||||
tree compound_stmt;
|
||||
{
|
||||
finish_compound_stmt (/*has_no_scope=*/1, compound_stmt);
|
||||
stmt_expr = finish_stmt_expr (stmt_expr);
|
||||
|
||||
/* To avoid spurious warnings about unused values, we set
|
||||
TREE_USED. */
|
||||
if (stmt_expr)
|
||||
TREE_USED (stmt_expr) = 1;
|
||||
|
||||
return stmt_expr;
|
||||
}
|
||||
|
||||
/* Constructors */
|
||||
|
||||
/* Called from initialize_vtbl_ptrs via dfs_walk. */
|
||||
|
||||
static tree
|
||||
|
@ -132,8 +171,6 @@ initialize_vtbl_ptrs (type, addr)
|
|||
expand_indirect_vtbls_init (TYPE_BINFO (type), addr);
|
||||
}
|
||||
|
||||
|
||||
/* 348 - 351 */
|
||||
/* Subroutine of emit_base_init. */
|
||||
|
||||
static void
|
||||
|
@ -240,8 +277,6 @@ perform_member_init (member, name, init, explicit)
|
|||
}
|
||||
}
|
||||
|
||||
extern int warn_reorder;
|
||||
|
||||
/* Subroutine of emit_member_init. */
|
||||
|
||||
static tree
|
||||
|
@ -485,7 +520,7 @@ sort_base_init (t, rbase_ptr, vbase_ptr)
|
|||
Note that emit_base_init does *not* initialize virtual base
|
||||
classes. That is done specially, elsewhere. */
|
||||
|
||||
tree
|
||||
void
|
||||
emit_base_init (t)
|
||||
tree t;
|
||||
{
|
||||
|
@ -494,9 +529,8 @@ emit_base_init (t)
|
|||
tree rbase_init_list, vbase_init_list;
|
||||
tree t_binfo = TYPE_BINFO (t);
|
||||
tree binfos = BINFO_BASETYPES (t_binfo);
|
||||
int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
|
||||
tree stmt_expr;
|
||||
tree compound_stmt;
|
||||
int i;
|
||||
int n_baseclasses = BINFO_N_BASETYPES (t_binfo);
|
||||
|
||||
mem_init_list = sort_member_init (t);
|
||||
current_member_init_list = NULL_TREE;
|
||||
|
@ -504,8 +538,6 @@ emit_base_init (t)
|
|||
sort_base_init (t, &rbase_init_list, &vbase_init_list);
|
||||
current_base_init_list = NULL_TREE;
|
||||
|
||||
begin_init_stmts (&stmt_expr, &compound_stmt);
|
||||
|
||||
/* First, initialize the virtual base classes, if we are
|
||||
constructing the most-derived object. */
|
||||
if (TYPE_USES_VIRTUAL_BASECLASSES (t))
|
||||
|
@ -618,25 +650,6 @@ emit_base_init (t)
|
|||
}
|
||||
mem_init_list = TREE_CHAIN (mem_init_list);
|
||||
}
|
||||
|
||||
/* All the implicit try blocks we built up will be zapped
|
||||
when we come to a real binding contour boundary. */
|
||||
return finish_init_stmts (stmt_expr, compound_stmt);
|
||||
}
|
||||
|
||||
/* Check that all fields are properly initialized after
|
||||
an assignment to `this'. Called only when such an assignment
|
||||
is actually noted. */
|
||||
|
||||
void
|
||||
check_base_init (t)
|
||||
tree t;
|
||||
{
|
||||
tree member;
|
||||
for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member))
|
||||
if (DECL_NAME (member) && TREE_USED (member))
|
||||
cp_error ("field `%D' used before initialized (after assignment to `this')",
|
||||
member);
|
||||
}
|
||||
|
||||
/* This code sets up the virtual function tables appropriate for
|
||||
|
@ -983,43 +996,6 @@ expand_member_init (exp, name, init)
|
|||
}
|
||||
}
|
||||
|
||||
/* We are about to generate some complex initialization code.
|
||||
Conceptually, it is all a single expression. However, we may want
|
||||
to include conditionals, loops, and other such statement-level
|
||||
constructs. Therefore, we build the initialization code inside a
|
||||
statement-expression. This function starts such an expression.
|
||||
STMT_EXPR_P and COMPOUND_STMT_P are filled in by this function;
|
||||
pass them back to finish_init_stmts when the expression is
|
||||
complete. */
|
||||
|
||||
void
|
||||
begin_init_stmts (stmt_expr_p, compound_stmt_p)
|
||||
tree *stmt_expr_p;
|
||||
tree *compound_stmt_p;
|
||||
{
|
||||
*stmt_expr_p = begin_stmt_expr ();
|
||||
*compound_stmt_p = begin_compound_stmt (/*has_no_scope=*/1);
|
||||
}
|
||||
|
||||
/* Finish out the statement-expression begun by the previous call to
|
||||
begin_init_stmts. Returns the statement-expression itself. */
|
||||
|
||||
tree
|
||||
finish_init_stmts (stmt_expr, compound_stmt)
|
||||
tree stmt_expr;
|
||||
tree compound_stmt;
|
||||
{
|
||||
finish_compound_stmt (/*has_no_scope=*/1, compound_stmt);
|
||||
stmt_expr = finish_stmt_expr (stmt_expr);
|
||||
|
||||
/* To avoid spurious warnings about unused values, we set
|
||||
TREE_USED. */
|
||||
if (stmt_expr)
|
||||
TREE_USED (stmt_expr) = 1;
|
||||
|
||||
return stmt_expr;
|
||||
}
|
||||
|
||||
/* This is like `expand_member_init', only it stores one aggregate
|
||||
value into another.
|
||||
|
||||
|
@ -1268,39 +1244,6 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, flags)
|
|||
expand_default_init (binfo, true_exp, exp, init, flags);
|
||||
}
|
||||
|
||||
/* Report an error if NAME is not the name of a user-defined,
|
||||
aggregate type. If OR_ELSE is nonzero, give an error message. */
|
||||
|
||||
int
|
||||
is_aggr_typedef (name, or_else)
|
||||
tree name;
|
||||
int or_else;
|
||||
{
|
||||
tree type;
|
||||
|
||||
if (name == error_mark_node)
|
||||
return 0;
|
||||
|
||||
if (IDENTIFIER_HAS_TYPE_VALUE (name))
|
||||
type = IDENTIFIER_TYPE_VALUE (name);
|
||||
else
|
||||
{
|
||||
if (or_else)
|
||||
cp_error ("`%T' is not an aggregate typedef", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! IS_AGGR_TYPE (type)
|
||||
&& TREE_CODE (type) != TEMPLATE_TYPE_PARM
|
||||
&& TREE_CODE (type) != TEMPLATE_TEMPLATE_PARM)
|
||||
{
|
||||
if (or_else)
|
||||
cp_error ("`%T' is not an aggregate type", type);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Report an error if TYPE is not a user-defined, aggregate type. If
|
||||
OR_ELSE is nonzero, give an error message. */
|
||||
|
||||
|
@ -2413,8 +2356,7 @@ build_new_1 (exp)
|
|||
flags |= LOOKUP_HAS_IN_CHARGE;
|
||||
}
|
||||
|
||||
if (use_java_new)
|
||||
rval = save_expr (rval);
|
||||
rval = save_expr (rval);
|
||||
newrval = rval;
|
||||
|
||||
if (newrval && TREE_CODE (TREE_TYPE (newrval)) == POINTER_TYPE)
|
||||
|
@ -2426,10 +2368,7 @@ build_new_1 (exp)
|
|||
if (newrval == NULL_TREE || newrval == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
/* Java constructors compiled by jc1 do not return this. */
|
||||
if (use_java_new)
|
||||
newrval = build (COMPOUND_EXPR, TREE_TYPE (newrval),
|
||||
newrval, rval);
|
||||
newrval = build (COMPOUND_EXPR, TREE_TYPE (rval), newrval, rval);
|
||||
rval = newrval;
|
||||
TREE_HAS_CONSTRUCTOR (rval) = 1;
|
||||
}
|
||||
|
|
|
@ -1235,7 +1235,7 @@ setup_vtbl_ptr ()
|
|||
add_tree (ctor_stmt);
|
||||
|
||||
/* And actually initialize the base-classes and members. */
|
||||
finish_expr_stmt (emit_base_init (current_class_type));
|
||||
emit_base_init (current_class_type);
|
||||
}
|
||||
}
|
||||
else if (DECL_DESTRUCTOR_P (current_function_decl)
|
||||
|
|
|
@ -6796,9 +6796,9 @@ check_return_expr (retval)
|
|||
/* You can't return a value from a constructor. */
|
||||
error ("returning a value from a constructor");
|
||||
|
||||
/* Constructors actually always return `this', even though in C++
|
||||
you can't return a value from a constructor. */
|
||||
if (DECL_CONSTRUCTOR_P (current_function_decl))
|
||||
/* Under the old ABI, constructors actually always return `this',
|
||||
even though in C++ you can't return a value from a constructor. */
|
||||
if (!flag_new_abi && DECL_CONSTRUCTOR_P (current_function_decl))
|
||||
retval = current_class_ptr;
|
||||
|
||||
/* When no explicit return-value is given in a function with a named
|
||||
|
|
Loading…
Reference in New Issue