Commit 8e3df2de by Mark Mitchell Committed by Mark Mitchell

NEWS: Document removal of "new X = ..." extension.

	* NEWS: Document removal of "new X = ..." extension.
	* class.c (initialize_array): Set TREE_HAS_CONSTRUCTOR on
	brace-enclosed initializers.
	* cp-tree.h (CP_AGGREGATE_TYPE_P): New macro.
	(initialize_local_var): Remove declaration.
	(expand_static_init): Likewise.
	* decl.c (next_initializable_field): New function.
	(reshape_init): Likewise.
	(check_initializer): Use them.  Build dynamic initializer for
	aggregates here too.
	(initialize_local_var): Simplify, and incorporate cleanup
	insertion code as well.
	(destroy_local_var): Remove.
	(cp_finish_decl): Tidy.
	(expand_static_init): Fold checks for whether or not a variable
	needs initialization into this function.  Simplify.
	* decl2.c (do_static_initialization): Simplify.
	* init.c (build_init): Do not set TREE_SIDE_EFFECTS when it will
	be done for us automatically.
	(expand_default_init): Handle brace-enclosed initializers
	correctly.
	(expand_aggr_init_1): Remove RTL-generation code.
	(build_vec_init): Remove "new X = ..." support.
	* parse.y (new_initializer): Likewise.
	* rtti.c (get_pseudo_ti_init): Set TREE_HAS_CONSTRUCTOR on
	brace-enclosed initializer.
	(create_pseudo_type_info): Likewise.
	* typeck2.c (store_init_value): Don't try to handle digest_init
	being called more than once.
	(digest_init): Tidy handling of brace-enclosed initializers.

	* g++.dg/init/array1.C: Remove invalid braces.
	* g++.dg/init/brace1.C: New test.
	* g++.dg/init/copy2.C: Likewise.
	* g++.dg/init/copy3.C: Likewise.
	* g++.old-deja/g++.ext/arrnew.C: Change WARNING to ERROR.
	* g++.old-deja/g++.mike/p9129.C: Add ERROR on invalid use of
	braces.

From-SVN: r58053
parent 98ddd678
2002-10-11 Mark Mitchell <mark@codesourcery.com>
* NEWS: Document removal of "new X = ..." extension.
* class.c (initialize_array): Set TREE_HAS_CONSTRUCTOR on
brace-enclosed initializers.
* cp-tree.h (CP_AGGREGATE_TYPE_P): New macro.
(initialize_local_var): Remove declaration.
(expand_static_init): Likewise.
* decl.c (next_initializable_field): New function.
(reshape_init): Likewise.
(check_initializer): Use them. Build dynamic initializer for
aggregates here too.
(initialize_local_var): Simplify, and incorporate cleanup
insertion code as well.
(destroy_local_var): Remove.
(cp_finish_decl): Tidy.
(expand_static_init): Fold checks for whether or not a variable
needs initialization into this function. Simplify.
* decl2.c (do_static_initialization): Simplify.
* init.c (build_init): Do not set TREE_SIDE_EFFECTS when it will
be done for us automatically.
(expand_default_init): Handle brace-enclosed initializers
correctly.
(expand_aggr_init_1): Remove RTL-generation code.
(build_vec_init): Remove "new X = ..." support.
* parse.y (new_initializer): Likewise.
* rtti.c (get_pseudo_ti_init): Set TREE_HAS_CONSTRUCTOR on
brace-enclosed initializer.
(create_pseudo_type_info): Likewise.
* typeck2.c (store_init_value): Don't try to handle digest_init
being called more than once.
(digest_init): Tidy handling of brace-enclosed initializers.
2002-10-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 2002-10-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* decl.c (typename_hash): Use htab_hash_pointer. * decl.c (typename_hash): Use htab_hash_pointer.
......
*** Changes in GCC 3.3:
* The "new X = 3" extension has been removed; you must now use "new X(3)".
*** Changes in GCC 3.1: *** Changes in GCC 3.1:
* -fhonor-std and -fno-honor-std have been removed. -fno-honor-std was * -fhonor-std and -fno-honor-std have been removed. -fno-honor-std was
......
...@@ -6994,6 +6994,7 @@ initialize_array (decl, inits) ...@@ -6994,6 +6994,7 @@ initialize_array (decl, inits)
context = DECL_CONTEXT (decl); context = DECL_CONTEXT (decl);
DECL_CONTEXT (decl) = NULL_TREE; DECL_CONTEXT (decl) = NULL_TREE;
DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE, inits); DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE, inits);
TREE_HAS_CONSTRUCTOR (DECL_INITIAL (decl)) = 1;
cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0); cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
DECL_CONTEXT (decl) = context; DECL_CONTEXT (decl) = context;
} }
......
...@@ -2437,8 +2437,18 @@ struct lang_decl GTY(()) ...@@ -2437,8 +2437,18 @@ struct lang_decl GTY(())
|| TYPE_PTRMEM_P (TYPE) \ || TYPE_PTRMEM_P (TYPE) \
|| TYPE_PTRMEMFUNC_P (TYPE)) || TYPE_PTRMEMFUNC_P (TYPE))
/* Nonzero for _TYPE means that the _TYPE defines /* [dcl.init.aggr]
at least one constructor. */
An aggregate is an array or a class with no user-declared
constructors, no private or protected non-static data members, no
base classes, and no virtual functions. */
#define CP_AGGREGATE_TYPE_P(TYPE) \
(TREE_CODE (TYPE) == ARRAY_TYPE \
|| (CLASS_TYPE_P (TYPE) \
&& !CLASSTYPE_NON_AGGREGATE (TYPE)))
/* Nonzero for a class type means that the class type has a
user-declared constructor. */
#define TYPE_HAS_CONSTRUCTOR(NODE) (TYPE_LANG_FLAG_1 (NODE)) #define TYPE_HAS_CONSTRUCTOR(NODE) (TYPE_LANG_FLAG_1 (NODE))
/* When appearing in an INDIRECT_REF, it means that the tree structure /* When appearing in an INDIRECT_REF, it means that the tree structure
...@@ -3667,8 +3677,6 @@ extern void start_decl_1 PARAMS ((tree)); ...@@ -3667,8 +3677,6 @@ extern void start_decl_1 PARAMS ((tree));
extern void cp_finish_decl PARAMS ((tree, tree, tree, int)); extern void cp_finish_decl PARAMS ((tree, tree, tree, int));
extern void finish_decl PARAMS ((tree, tree, tree)); extern void finish_decl PARAMS ((tree, tree, tree));
extern void maybe_inject_for_scope_var PARAMS ((tree)); extern void maybe_inject_for_scope_var PARAMS ((tree));
extern void initialize_local_var PARAMS ((tree, tree, int));
extern void expand_static_init PARAMS ((tree, tree));
extern tree start_handler_parms PARAMS ((tree, tree)); extern tree start_handler_parms PARAMS ((tree, tree));
extern int complete_array_type PARAMS ((tree, tree, int)); extern int complete_array_type PARAMS ((tree, tree, int));
extern tree build_ptrmemfunc_type PARAMS ((tree)); extern tree build_ptrmemfunc_type PARAMS ((tree));
......
...@@ -2508,34 +2508,24 @@ finish_static_initialization_or_destruction (guard_if_stmt) ...@@ -2508,34 +2508,24 @@ finish_static_initialization_or_destruction (guard_if_stmt)
DECL_STATIC_FUNCTION_P (current_function_decl) = 0; DECL_STATIC_FUNCTION_P (current_function_decl) = 0;
} }
/* Generate code to do the static initialization of DECL. The /* Generate code to do the initialization of DECL, a VAR_DECL with
initialization is INIT. If DECL may be initialized more than once static storage duration. The initialization is INIT. */
in different object files, GUARD is the guard variable to
check. PRIORITY is the priority for the initialization. */
static void static void
do_static_initialization (decl, init) do_static_initialization (decl, init)
tree decl; tree decl;
tree init; tree init;
{ {
tree expr;
tree guard_if_stmt; tree guard_if_stmt;
/* Set up for the initialization. */ /* Set up for the initialization. */
guard_if_stmt guard_if_stmt
= start_static_initialization_or_destruction (decl, = start_static_initialization_or_destruction (decl,
/*initp=*/1); /*initp=*/1);
/* Do the initialization itself. */ /* Perform the initialization. */
if (IS_AGGR_TYPE (TREE_TYPE (decl)) if (init)
|| TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) finish_expr_stmt (init);
expr = build_aggr_init (decl, init, 0);
else
{
expr = build (INIT_EXPR, TREE_TYPE (decl), decl, init);
TREE_SIDE_EFFECTS (expr) = 1;
}
finish_expr_stmt (expr);
/* If we're using __cxa_atexit, register a a function that calls the /* If we're using __cxa_atexit, register a a function that calls the
destructor for the object. */ destructor for the object. */
...@@ -2567,7 +2557,7 @@ do_static_destruction (decl) ...@@ -2567,7 +2557,7 @@ do_static_destruction (decl)
/* Actually do the destruction. */ /* Actually do the destruction. */
guard_if_stmt = start_static_initialization_or_destruction (decl, guard_if_stmt = start_static_initialization_or_destruction (decl,
/*initp=*/0); /*initp=*/0);
finish_expr_stmt (build_cleanup (decl)); finish_expr_stmt (build_cleanup (decl));
finish_static_initialization_or_destruction (guard_if_stmt); finish_static_initialization_or_destruction (guard_if_stmt);
} }
......
...@@ -1041,8 +1041,6 @@ expand_member_init (tree name, tree init) ...@@ -1041,8 +1041,6 @@ expand_member_init (tree name, tree init)
The virtual function table pointer cannot be set up here, because The virtual function table pointer cannot be set up here, because
we do not really know its type. we do not really know its type.
Virtual baseclass pointers are also set up here.
This never calls operator=(). This never calls operator=().
When initializing, nothing is CONST. When initializing, nothing is CONST.
...@@ -1144,10 +1142,8 @@ build_init (decl, init, flags) ...@@ -1144,10 +1142,8 @@ build_init (decl, init, flags)
|| TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
expr = build_aggr_init (decl, init, flags); expr = build_aggr_init (decl, init, flags);
else else
{ expr = build (INIT_EXPR, TREE_TYPE (decl), decl, init);
expr = build (INIT_EXPR, TREE_TYPE (decl), decl, init);
TREE_SIDE_EFFECTS (expr) = 1;
}
return expr; return expr;
} }
...@@ -1184,9 +1180,17 @@ expand_default_init (binfo, true_exp, exp, init, flags) ...@@ -1184,9 +1180,17 @@ expand_default_init (binfo, true_exp, exp, init, flags)
have already built up the constructor call so we could wrap it have already built up the constructor call so we could wrap it
in an exception region. */; in an exception region. */;
else if (TREE_CODE (init) == CONSTRUCTOR) else if (TREE_CODE (init) == CONSTRUCTOR)
/* A brace-enclosed initializer has whatever type is {
required. There's no need to convert it. */ if (!TYPE_HAS_CONSTRUCTOR (type))
; /* A brace-enclosed initializer has whatever type is
required. There's no need to convert it. */
;
else
init = ocp_convert (type,
TREE_VALUE (CONSTRUCTOR_ELTS (init)),
CONV_IMPLICIT | CONV_FORCE_TEMP,
flags);
}
else else
init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags); init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
...@@ -1259,6 +1263,7 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, flags) ...@@ -1259,6 +1263,7 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, flags)
tree type = TREE_TYPE (exp); tree type = TREE_TYPE (exp);
my_friendly_assert (init != error_mark_node && type != error_mark_node, 211); my_friendly_assert (init != error_mark_node && type != error_mark_node, 211);
my_friendly_assert (building_stmt_tree (), 20021010);
/* Use a function returning the desired type to initialize EXP for us. /* Use a function returning the desired type to initialize EXP for us.
If the function is a constructor, and its first argument is If the function is a constructor, and its first argument is
...@@ -1273,12 +1278,7 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, flags) ...@@ -1273,12 +1278,7 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, flags)
/* If store_init_value returns NULL_TREE, the INIT has been /* If store_init_value returns NULL_TREE, the INIT has been
record in the DECL_INITIAL for EXP. That means there's record in the DECL_INITIAL for EXP. That means there's
nothing more we have to do. */ nothing more we have to do. */
if (!store_init_value (exp, init)) if (store_init_value (exp, init))
{
if (!building_stmt_tree ())
expand_decl_init (exp);
}
else
finish_expr_stmt (build (INIT_EXPR, type, exp, init)); finish_expr_stmt (build (INIT_EXPR, type, exp, init));
return; return;
} }
...@@ -2725,10 +2725,6 @@ build_vec_init (base, init, from_array) ...@@ -2725,10 +2725,6 @@ build_vec_init (base, init, from_array)
if (maxindex == error_mark_node) if (maxindex == error_mark_node)
return error_mark_node; return error_mark_node;
/* For g++.ext/arrnew.C. */
if (init && TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == NULL_TREE)
init = digest_init (atype, init, 0);
if (init if (init
&& (from_array == 2 && (from_array == 2
? (!CLASS_TYPE_P (type) || !TYPE_HAS_COMPLEX_ASSIGN_REF (type)) ? (!CLASS_TYPE_P (type) || !TYPE_HAS_COMPLEX_ASSIGN_REF (type))
...@@ -2745,7 +2741,6 @@ build_vec_init (base, init, from_array) ...@@ -2745,7 +2741,6 @@ build_vec_init (base, init, from_array)
store_constructor will handle the semantics for us. */ store_constructor will handle the semantics for us. */
stmt_expr = build (INIT_EXPR, atype, base, init); stmt_expr = build (INIT_EXPR, atype, base, init);
TREE_SIDE_EFFECTS (stmt_expr) = 1;
return stmt_expr; return stmt_expr;
} }
......
...@@ -1351,21 +1351,12 @@ new_initializer: ...@@ -1351,21 +1351,12 @@ new_initializer:
error ("`%T' is not a valid expression", $2.t); error ("`%T' is not a valid expression", $2.t);
$$ = error_mark_node; $$ = error_mark_node;
} }
/* GNU extension so people can use initializer lists. Note that
this alters the meaning of `new int = 1', which was previously
syntactically valid but semantically invalid.
This feature is now deprecated and will be removed in a future
release. */
| '=' init | '=' init
{ {
if (pedantic) /* This was previously allowed as an extension, but
pedwarn ("ISO C++ forbids initialization of new expression with `='"); was removed in G++ 3.3. */
cp_deprecated ("new initializer lists extension"); error ("initialization of new expression with `='");
if (TREE_CODE ($2) != TREE_LIST $$ = error_mark_node;
&& TREE_CODE ($2) != CONSTRUCTOR)
$$ = build_tree_list (NULL_TREE, $2);
else
$$ = $2;
} }
; ;
......
...@@ -1096,10 +1096,12 @@ get_pseudo_ti_init (type, var_desc, non_public_p) ...@@ -1096,10 +1096,12 @@ get_pseudo_ti_init (type, var_desc, non_public_p)
base_init = tree_cons (NULL_TREE, offset, base_init); base_init = tree_cons (NULL_TREE, offset, base_init);
base_init = tree_cons (NULL_TREE, tinfo, base_init); base_init = tree_cons (NULL_TREE, tinfo, base_init);
base_init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_init); base_init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_init);
TREE_HAS_CONSTRUCTOR (base_init) = 1;
base_inits = tree_cons (NULL_TREE, base_init, base_inits); base_inits = tree_cons (NULL_TREE, base_init, base_inits);
} }
base_inits = build (CONSTRUCTOR, base_inits = build (CONSTRUCTOR,
NULL_TREE, NULL_TREE, base_inits); NULL_TREE, NULL_TREE, base_inits);
TREE_HAS_CONSTRUCTOR (base_inits) = 1;
base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE); base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
/* Prepend the number of bases. */ /* Prepend the number of bases. */
base_inits = tree_cons (NULL_TREE, base_inits = tree_cons (NULL_TREE,
...@@ -1163,7 +1165,7 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...)) ...@@ -1163,7 +1165,7 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
/* Create the pseudo type. */ /* Create the pseudo type. */
pseudo_type = make_aggr_type (RECORD_TYPE); pseudo_type = make_aggr_type (RECORD_TYPE);
finish_builtin_type (pseudo_type, pseudo_name, fields, ix, ptr_type_node); finish_builtin_type (pseudo_type, pseudo_name, fields, ix, ptr_type_node);
TYPE_HAS_CONSTRUCTOR (pseudo_type) = 1; CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type;
result = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); result = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE);
TINFO_REAL_NAME (result) = get_identifier (real_name); TINFO_REAL_NAME (result) = get_identifier (real_name);
......
...@@ -367,15 +367,8 @@ store_init_value (decl, init) ...@@ -367,15 +367,8 @@ store_init_value (decl, init)
/* End of special C++ code. */ /* End of special C++ code. */
/* We might have already run this bracketed initializer through /* Digest the specified initializer into an expression. */
digest_init. Don't do so again. */ value = digest_init (type, init, (tree *) 0);
if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init)
&& TREE_TYPE (init)
&& TYPE_MAIN_VARIANT (TREE_TYPE (init)) == TYPE_MAIN_VARIANT (type))
value = init;
else
/* Digest the specified initializer into an expression. */
value = digest_init (type, init, (tree *) 0);
/* Store the expression if valid; else report error. */ /* Store the expression if valid; else report error. */
...@@ -439,8 +432,7 @@ digest_init (type, init, tail) ...@@ -439,8 +432,7 @@ digest_init (type, init, tail)
enum tree_code code = TREE_CODE (type); enum tree_code code = TREE_CODE (type);
tree element = NULL_TREE; tree element = NULL_TREE;
tree old_tail_contents = NULL_TREE; tree old_tail_contents = NULL_TREE;
/* Nonzero if INIT is a braced grouping, which comes in as a CONSTRUCTOR /* Nonzero if INIT is a braced grouping. */
tree node which has no TREE_TYPE. */
int raw_constructor; int raw_constructor;
/* By default, assume we use one element from a list. /* By default, assume we use one element from a list.
...@@ -471,10 +463,8 @@ digest_init (type, init, tail) ...@@ -471,10 +463,8 @@ digest_init (type, init, tail)
if (TREE_CODE (init) == NON_LVALUE_EXPR) if (TREE_CODE (init) == NON_LVALUE_EXPR)
init = TREE_OPERAND (init, 0); init = TREE_OPERAND (init, 0);
if (TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == type) raw_constructor = (TREE_CODE (init) == CONSTRUCTOR
return init; && TREE_HAS_CONSTRUCTOR (init));
raw_constructor = TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == 0;
if (raw_constructor if (raw_constructor
&& CONSTRUCTOR_ELTS (init) != 0 && CONSTRUCTOR_ELTS (init) != 0
......
2002-10-11 Mark Mitchell <mark@codesourcery.com>
* g++.dg/init/array1.C: Remove invalid braces.
* g++.dg/init/brace1.C: New test.
* g++.dg/init/copy2.C: Likewise.
* g++.dg/init/copy3.C: Likewise.
* g++.old-deja/g++.ext/arrnew.C: Change WARNING to ERROR.
* g++.old-deja/g++.mike/p9129.C: Add ERROR on invalid use of
braces.
2002-10-11 Neil Booth <neil@daikokuya.co.uk> 2002-10-11 Neil Booth <neil@daikokuya.co.uk>
* gcc.dg/cpp/assembler.S: Don't use -ansi. * gcc.dg/cpp/assembler.S: Don't use -ansi.
......
...@@ -6,15 +6,15 @@ ...@@ -6,15 +6,15 @@
typedef int iArr[]; typedef int iArr[];
const iArr array4={ const iArr array4={
{1},{2},{3},{4} 1, 2, 3, 4
}; };
const iArr array3={ const iArr array3={
{1},{2},{3} 1, 2, 3
}; };
const iArr array5={ const iArr array5={
{1},{2},{3},{4},{5} 1, 2, 3, 4, 5
}; };
int main() int main()
......
// { dg-do compile }
int i[4] = { { 3 } }; // { dg-error "brace" }
// { dg-do compile }
struct S { S (); };
volatile S s[1] = { S () };
// { dg-do run }
// { dg-options "-fno-elide-constructors" }
int copies;
struct S {
S () {}
S (const S&) { ++copies; }
};
S s[1] = { S () };
int main () {
if (copies != 1)
return 1;
}
...@@ -3,5 +3,5 @@ ...@@ -3,5 +3,5 @@
// Special g++ Options: // Special g++ Options:
int *f(){ int *f(){
return new int[1] = { 1 }; // WARNING - deprecated return new int[1] = { 1 }; // ERROR - removed
} }
...@@ -7,6 +7,6 @@ public: ...@@ -7,6 +7,6 @@ public:
int DoSomething(); int DoSomething();
}; };
int (Foo::*pA)() = { &Foo::DoSomething }; int (Foo::*pA)() = { &Foo::DoSomething }; // ERROR -
int (Foo::*X[1])(int) = { { &Foo::DoSomething } }; // ERROR - int (Foo::*X[1])(int) = { { &Foo::DoSomething } }; // ERROR -
int (Foo::*Y[])(int) = { { &Foo::DoSomething, &Foo::DoSomething, 0 } }; // ERROR - int (Foo::*Y[])(int) = { { &Foo::DoSomething, &Foo::DoSomething, 0 } }; // ERROR -
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment