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>
* 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:
* -fhonor-std and -fno-honor-std have been removed. -fno-honor-std was
......
......@@ -6994,6 +6994,7 @@ initialize_array (decl, inits)
context = DECL_CONTEXT (decl);
DECL_CONTEXT (decl) = NULL_TREE;
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);
DECL_CONTEXT (decl) = context;
}
......
......@@ -2437,8 +2437,18 @@ struct lang_decl GTY(())
|| TYPE_PTRMEM_P (TYPE) \
|| TYPE_PTRMEMFUNC_P (TYPE))
/* Nonzero for _TYPE means that the _TYPE defines
at least one constructor. */
/* [dcl.init.aggr]
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))
/* When appearing in an INDIRECT_REF, it means that the tree structure
......@@ -3667,8 +3677,6 @@ extern void start_decl_1 PARAMS ((tree));
extern void cp_finish_decl PARAMS ((tree, tree, tree, int));
extern void finish_decl PARAMS ((tree, tree, 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 int complete_array_type PARAMS ((tree, tree, int));
extern tree build_ptrmemfunc_type PARAMS ((tree));
......
......@@ -2508,34 +2508,24 @@ finish_static_initialization_or_destruction (guard_if_stmt)
DECL_STATIC_FUNCTION_P (current_function_decl) = 0;
}
/* Generate code to do the static initialization of DECL. The
initialization is INIT. If DECL may be initialized more than once
in different object files, GUARD is the guard variable to
check. PRIORITY is the priority for the initialization. */
/* Generate code to do the initialization of DECL, a VAR_DECL with
static storage duration. The initialization is INIT. */
static void
do_static_initialization (decl, init)
tree decl;
tree init;
{
tree expr;
tree guard_if_stmt;
/* Set up for the initialization. */
guard_if_stmt
= start_static_initialization_or_destruction (decl,
/*initp=*/1);
/* Do the initialization itself. */
if (IS_AGGR_TYPE (TREE_TYPE (decl))
|| TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
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);
/* Perform the initialization. */
if (init)
finish_expr_stmt (init);
/* If we're using __cxa_atexit, register a a function that calls the
destructor for the object. */
......@@ -2567,7 +2557,7 @@ do_static_destruction (decl)
/* Actually do the destruction. */
guard_if_stmt = start_static_initialization_or_destruction (decl,
/*initp=*/0);
/*initp=*/0);
finish_expr_stmt (build_cleanup (decl));
finish_static_initialization_or_destruction (guard_if_stmt);
}
......
......@@ -1041,8 +1041,6 @@ expand_member_init (tree name, tree init)
The virtual function table pointer cannot be set up here, because
we do not really know its type.
Virtual baseclass pointers are also set up here.
This never calls operator=().
When initializing, nothing is CONST.
......@@ -1144,10 +1142,8 @@ build_init (decl, init, flags)
|| TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
expr = build_aggr_init (decl, init, flags);
else
{
expr = build (INIT_EXPR, TREE_TYPE (decl), decl, init);
TREE_SIDE_EFFECTS (expr) = 1;
}
expr = build (INIT_EXPR, TREE_TYPE (decl), decl, init);
return expr;
}
......@@ -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
in an exception region. */;
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
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)
tree type = TREE_TYPE (exp);
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.
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)
/* If store_init_value returns NULL_TREE, the INIT has been
record in the DECL_INITIAL for EXP. That means there's
nothing more we have to do. */
if (!store_init_value (exp, init))
{
if (!building_stmt_tree ())
expand_decl_init (exp);
}
else
if (store_init_value (exp, init))
finish_expr_stmt (build (INIT_EXPR, type, exp, init));
return;
}
......@@ -2725,10 +2725,6 @@ build_vec_init (base, init, from_array)
if (maxindex == 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
&& (from_array == 2
? (!CLASS_TYPE_P (type) || !TYPE_HAS_COMPLEX_ASSIGN_REF (type))
......@@ -2745,7 +2741,6 @@ build_vec_init (base, init, from_array)
store_constructor will handle the semantics for us. */
stmt_expr = build (INIT_EXPR, atype, base, init);
TREE_SIDE_EFFECTS (stmt_expr) = 1;
return stmt_expr;
}
......
......@@ -1351,21 +1351,12 @@ new_initializer:
error ("`%T' is not a valid expression", $2.t);
$$ = 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
{
if (pedantic)
pedwarn ("ISO C++ forbids initialization of new expression with `='");
cp_deprecated ("new initializer lists extension");
if (TREE_CODE ($2) != TREE_LIST
&& TREE_CODE ($2) != CONSTRUCTOR)
$$ = build_tree_list (NULL_TREE, $2);
else
$$ = $2;
/* This was previously allowed as an extension, but
was removed in G++ 3.3. */
error ("initialization of new expression with `='");
$$ = error_mark_node;
}
;
......
......@@ -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, tinfo, 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 = build (CONSTRUCTOR,
NULL_TREE, NULL_TREE, base_inits);
TREE_HAS_CONSTRUCTOR (base_inits) = 1;
base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
/* Prepend the number of bases. */
base_inits = tree_cons (NULL_TREE,
......@@ -1163,7 +1165,7 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
/* Create the pseudo type. */
pseudo_type = make_aggr_type (RECORD_TYPE);
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);
TINFO_REAL_NAME (result) = get_identifier (real_name);
......
......@@ -367,15 +367,8 @@ store_init_value (decl, init)
/* End of special C++ code. */
/* We might have already run this bracketed initializer through
digest_init. Don't do so again. */
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);
/* Digest the specified initializer into an expression. */
value = digest_init (type, init, (tree *) 0);
/* Store the expression if valid; else report error. */
......@@ -439,8 +432,7 @@ digest_init (type, init, tail)
enum tree_code code = TREE_CODE (type);
tree element = NULL_TREE;
tree old_tail_contents = NULL_TREE;
/* Nonzero if INIT is a braced grouping, which comes in as a CONSTRUCTOR
tree node which has no TREE_TYPE. */
/* Nonzero if INIT is a braced grouping. */
int raw_constructor;
/* By default, assume we use one element from a list.
......@@ -471,10 +463,8 @@ digest_init (type, init, tail)
if (TREE_CODE (init) == NON_LVALUE_EXPR)
init = TREE_OPERAND (init, 0);
if (TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == type)
return init;
raw_constructor = TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == 0;
raw_constructor = (TREE_CODE (init) == CONSTRUCTOR
&& TREE_HAS_CONSTRUCTOR (init));
if (raw_constructor
&& 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>
* gcc.dg/cpp/assembler.S: Don't use -ansi.
......
......@@ -6,15 +6,15 @@
typedef int iArr[];
const iArr array4={
{1},{2},{3},{4}
1, 2, 3, 4
};
const iArr array3={
{1},{2},{3}
1, 2, 3
};
const iArr array5={
{1},{2},{3},{4},{5}
1, 2, 3, 4, 5
};
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 @@
// Special g++ Options:
int *f(){
return new int[1] = { 1 }; // WARNING - deprecated
return new int[1] = { 1 }; // ERROR - removed
}
......@@ -7,6 +7,6 @@ public:
int DoSomething();
};
int (Foo::*pA)() = { &Foo::DoSomething };
int (Foo::*pA)() = { &Foo::DoSomething }; // ERROR -
int (Foo::*X[1])(int) = { { &Foo::DoSomething } }; // 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