cp-tree.h (struct lang_type): Added non_zero_init.
* cp-tree.h (struct lang_type): Added non_zero_init. (CLASS_NON_ZERO_INIT_P): New macro. (zero_init_p, force_store_init_value, build_forced_zero_init): Declare. * class.c (check_field_decls): Test non_zero_init. * cvt.c (convert_to_pointer_force): Use cp_convert_to_pointer for zero-to-NULL conversions. * decl.c (obscure_complex_init): Don't reset DECL_INITIAL of a type that needs zero-initialization without zeros. (check_initializer_decl): Compute zero-initializer for types that require a non-trivial one. * init.c (build_forced_zero_init): New function. (build_default_init): Use it. * tree.c (zero_init_p): New function. * typeck2.c (force_store_init_value): New function. (process_init_constructor): Create non-trivial zero-initializers for array members and class fields. From-SVN: r53461
This commit is contained in:
parent
e5f5feea65
commit
94e6e4c4f3
@ -1,3 +1,22 @@
|
||||
2002-05-14 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* cp-tree.h (struct lang_type): Added non_zero_init.
|
||||
(CLASS_NON_ZERO_INIT_P): New macro.
|
||||
(zero_init_p, force_store_init_value, build_forced_zero_init): Declare.
|
||||
* class.c (check_field_decls): Test non_zero_init.
|
||||
* cvt.c (convert_to_pointer_force): Use cp_convert_to_pointer for
|
||||
zero-to-NULL conversions.
|
||||
* decl.c (obscure_complex_init): Don't reset DECL_INITIAL of a
|
||||
type that needs zero-initialization without zeros.
|
||||
(check_initializer_decl): Compute zero-initializer for types
|
||||
that require a non-trivial one.
|
||||
* init.c (build_forced_zero_init): New function.
|
||||
(build_default_init): Use it.
|
||||
* tree.c (zero_init_p): New function.
|
||||
* typeck2.c (force_store_init_value): New function.
|
||||
(process_init_constructor): Create non-trivial zero-initializers
|
||||
for array members and class fields.
|
||||
|
||||
2002-05-14 Neil Booth <neil@daikokuya.demon.co.uk>
|
||||
|
||||
* lang-specs.h: Remove redundant -lang-c++.
|
||||
|
@ -3405,6 +3405,9 @@ check_field_decls (t, access_decls, empty_p,
|
||||
to be allowed in POD structs. */
|
||||
CLASSTYPE_NON_POD_P (t) = 1;
|
||||
|
||||
if (! zero_init_p (type))
|
||||
CLASSTYPE_NON_ZERO_INIT_P (t) = 1;
|
||||
|
||||
/* If any field is const, the structure type is pseudo-const. */
|
||||
if (CP_TYPE_CONST_P (type))
|
||||
{
|
||||
|
@ -1240,6 +1240,8 @@ struct lang_type
|
||||
unsigned is_partial_instantiation : 1;
|
||||
unsigned java_interface : 1;
|
||||
|
||||
unsigned non_zero_init : 1;
|
||||
|
||||
/* When adding a flag here, consider whether or not it ought to
|
||||
apply to a template instance if it applies to the template. If
|
||||
so, make sure to copy it in instantiate_class_template! */
|
||||
@ -1247,7 +1249,7 @@ struct lang_type
|
||||
/* There are some bits left to fill out a 32-bit word. Keep track
|
||||
of this by updating the size of this bitfield whenever you add or
|
||||
remove a flag. */
|
||||
unsigned dummy : 8;
|
||||
unsigned dummy : 7;
|
||||
|
||||
int vsize;
|
||||
|
||||
@ -1501,9 +1503,14 @@ struct lang_type
|
||||
#define CLASSTYPE_HAS_MUTABLE(NODE) (TYPE_LANG_SPECIFIC (NODE)->has_mutable)
|
||||
#define TYPE_HAS_MUTABLE_P(NODE) (cp_has_mutable_p (NODE))
|
||||
|
||||
/* Nonzero means that this class type is a non-POD class. */
|
||||
/* Nonzero means that this class type is a non-POD class. */
|
||||
#define CLASSTYPE_NON_POD_P(NODE) (TYPE_LANG_SPECIFIC (NODE)->non_pod_class)
|
||||
|
||||
/* Nonzero means that this class contains pod types whose default
|
||||
initialization is not a zero initialization (namely, pointers to
|
||||
data members). */
|
||||
#define CLASSTYPE_NON_ZERO_INIT_P(NODE) (TYPE_LANG_SPECIFIC (NODE)->non_zero_init)
|
||||
|
||||
/* Nonzero if this class is "nearly empty", i.e., contains only a
|
||||
virtual function table pointer. */
|
||||
#define CLASSTYPE_NEARLY_EMPTY_P(NODE) \
|
||||
@ -3912,6 +3919,7 @@ extern tree build_init PARAMS ((tree, 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));
|
||||
extern tree build_forced_zero_init PARAMS ((tree));
|
||||
extern tree build_member_call PARAMS ((tree, tree, tree));
|
||||
extern tree build_offset_ref PARAMS ((tree, tree));
|
||||
extern tree resolve_offset_ref PARAMS ((tree));
|
||||
@ -4230,6 +4238,7 @@ extern tree cxx_unsave_expr_now PARAMS ((tree));
|
||||
extern tree cxx_maybe_build_cleanup PARAMS ((tree));
|
||||
extern void init_tree PARAMS ((void));
|
||||
extern int pod_type_p PARAMS ((tree));
|
||||
extern int zero_init_p PARAMS ((tree));
|
||||
extern tree canonical_type_variant PARAMS ((tree));
|
||||
extern void unshare_base_binfos PARAMS ((tree));
|
||||
extern int member_p PARAMS ((tree));
|
||||
@ -4376,6 +4385,7 @@ extern int abstract_virtuals_error PARAMS ((tree, tree));
|
||||
#define my_friendly_assert(EXP, N) (void) \
|
||||
(((EXP) == 0) ? (fancy_abort (__FILE__, __LINE__, __FUNCTION__), 0) : 0)
|
||||
|
||||
extern tree force_store_init_value PARAMS ((tree, tree));
|
||||
extern tree store_init_value PARAMS ((tree, tree));
|
||||
extern tree digest_init PARAMS ((tree, tree, tree *));
|
||||
extern tree build_scoped_ref PARAMS ((tree, tree, tree *));
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Language-level data type conversion for GNU C++.
|
||||
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Hacked by Michael Tiemann (tiemann@cygnus.com)
|
||||
|
||||
This file is part of GNU CC.
|
||||
@ -288,13 +288,6 @@ convert_to_pointer_force (type, expr)
|
||||
register tree intype = TREE_TYPE (expr);
|
||||
register enum tree_code form = TREE_CODE (intype);
|
||||
|
||||
if (integer_zerop (expr))
|
||||
{
|
||||
expr = build_int_2 (0, 0);
|
||||
TREE_TYPE (expr) = type;
|
||||
return expr;
|
||||
}
|
||||
|
||||
if (form == POINTER_TYPE)
|
||||
{
|
||||
intype = TYPE_MAIN_VARIANT (intype);
|
||||
|
@ -7592,7 +7592,13 @@ obscure_complex_init (decl, init)
|
||||
NULL_TREE);
|
||||
else
|
||||
#endif
|
||||
DECL_INITIAL (decl) = error_mark_node;
|
||||
{
|
||||
if (zero_init_p (TREE_TYPE (decl)))
|
||||
DECL_INITIAL (decl) = error_mark_node;
|
||||
/* Otherwise, force_store_init_value will have already stored a
|
||||
zero-init initializer in DECL_INITIAL, that should be
|
||||
retained. */
|
||||
}
|
||||
|
||||
return init;
|
||||
}
|
||||
@ -7838,8 +7844,16 @@ check_initializer (decl, init)
|
||||
if (init)
|
||||
init = obscure_complex_init (decl, init);
|
||||
}
|
||||
else if (!DECL_EXTERNAL (decl) && !zero_init_p (type))
|
||||
{
|
||||
force_store_init_value (decl, build_forced_zero_init (type));
|
||||
|
||||
if (init)
|
||||
goto process_init;
|
||||
}
|
||||
else if (init)
|
||||
{
|
||||
process_init:
|
||||
if (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type))
|
||||
{
|
||||
if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Handle initialization things in C++.
|
||||
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Michael Tiemann (tiemann@cygnus.com)
|
||||
|
||||
This file is part of GNU CC.
|
||||
@ -156,6 +156,44 @@ initialize_vtbl_ptrs (addr)
|
||||
dfs_marked_real_bases_queue_p, type);
|
||||
}
|
||||
|
||||
/* Types containing pointers to data members cannot be
|
||||
zero-initialized with zeros, because the NULL value for such
|
||||
pointers is -1.
|
||||
|
||||
TYPE is a type that requires such zero initialization. The
|
||||
returned value is the initializer. */
|
||||
|
||||
tree
|
||||
build_forced_zero_init (type)
|
||||
tree type;
|
||||
{
|
||||
tree init = NULL;
|
||||
|
||||
if (AGGREGATE_TYPE_P (type) && !TYPE_PTRMEMFUNC_P (type))
|
||||
{
|
||||
/* This is a default initialization of an aggregate, but not one of
|
||||
non-POD class type. We cleverly notice that the initialization
|
||||
rules in such a case are the same as for initialization with an
|
||||
empty brace-initialization list. */
|
||||
init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE);
|
||||
}
|
||||
else if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
/* --if T is a reference type, no initialization is performed. */
|
||||
return NULL_TREE;
|
||||
else
|
||||
{
|
||||
init = integer_zero_node;
|
||||
|
||||
if (TREE_CODE (type) == ENUMERAL_TYPE)
|
||||
/* We must make enumeral types the right type. */
|
||||
init = fold (build1 (NOP_EXPR, type, init));
|
||||
}
|
||||
|
||||
init = digest_init (type, init, 0);
|
||||
|
||||
return init;
|
||||
}
|
||||
|
||||
/* [dcl.init]:
|
||||
|
||||
To default-initialize an object of type T means:
|
||||
@ -182,28 +220,8 @@ build_default_init (type)
|
||||
anything with a CONSTRUCTOR for arrays here, as that would imply
|
||||
copy-initialization. */
|
||||
return NULL_TREE;
|
||||
else if (AGGREGATE_TYPE_P (type) && !TYPE_PTRMEMFUNC_P (type))
|
||||
{
|
||||
/* This is a default initialization of an aggregate, but not one of
|
||||
non-POD class type. We cleverly notice that the initialization
|
||||
rules in such a case are the same as for initialization with an
|
||||
empty brace-initialization list. */
|
||||
init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE);
|
||||
}
|
||||
else if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
/* --if T is a reference type, no initialization is performed. */
|
||||
return NULL_TREE;
|
||||
else
|
||||
{
|
||||
init = integer_zero_node;
|
||||
|
||||
if (TREE_CODE (type) == ENUMERAL_TYPE)
|
||||
/* We must make enumeral types the right type. */
|
||||
init = fold (build1 (NOP_EXPR, type, init));
|
||||
}
|
||||
|
||||
init = digest_init (type, init, 0);
|
||||
return init;
|
||||
return build_forced_zero_init (type);
|
||||
}
|
||||
|
||||
/* Subroutine of emit_base_init. */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Language-dependent node constructors for parse phase of GNU compiler.
|
||||
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Hacked by Michael Tiemann (tiemann@cygnus.com)
|
||||
|
||||
This file is part of GNU CC.
|
||||
@ -1901,6 +1901,27 @@ pod_type_p (t)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Returns 1 iff zero initialization of type T means actually storing
|
||||
zeros in it. */
|
||||
|
||||
int
|
||||
zero_init_p (t)
|
||||
tree t;
|
||||
{
|
||||
t = strip_array_types (t);
|
||||
|
||||
/* NULL pointers to data members are initialized with -1. */
|
||||
if (TYPE_PTRMEM_P (t))
|
||||
return 0;
|
||||
|
||||
/* Classes that contain types that can't be zero-initialized, cannot
|
||||
be zero-initialized themselves. */
|
||||
if (CLASS_TYPE_P (t) && CLASSTYPE_NON_ZERO_INIT_P (t))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Table of valid C++ attributes. */
|
||||
const struct attribute_spec cxx_attribute_table[] =
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* Report error messages, build initializers, and perform
|
||||
some front-end optimizations for C++ compiler.
|
||||
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Hacked by Michael Tiemann (tiemann@cygnus.com)
|
||||
|
||||
This file is part of GNU CC.
|
||||
@ -420,6 +420,28 @@ store_init_value (decl, init)
|
||||
DECL_INITIAL (decl) = value;
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Same as store_init_value, but used for known-to-be-valid static
|
||||
initializers. Used to introduce a static initializer even in data
|
||||
structures that may require dynamic initialization. */
|
||||
|
||||
tree
|
||||
force_store_init_value (decl, init)
|
||||
tree decl, init;
|
||||
{
|
||||
tree type = TREE_TYPE (decl);
|
||||
int needs_constructing = TYPE_NEEDS_CONSTRUCTING (type);
|
||||
|
||||
TYPE_NEEDS_CONSTRUCTING (type) = 0;
|
||||
|
||||
init = store_init_value (decl, init);
|
||||
if (init)
|
||||
abort ();
|
||||
|
||||
TYPE_NEEDS_CONSTRUCTING (type) = needs_constructing;
|
||||
|
||||
return init;
|
||||
}
|
||||
|
||||
/* Digest the parser output INIT as an initializer for type TYPE.
|
||||
Return a C expression of type TYPE to represent the initial value.
|
||||
@ -732,6 +754,8 @@ process_init_constructor (type, init, elts)
|
||||
next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE);
|
||||
next1 = digest_init (TREE_TYPE (type), next1, 0);
|
||||
}
|
||||
else if (! zero_init_p (TREE_TYPE (type)))
|
||||
next1 = build_forced_zero_init (TREE_TYPE (type));
|
||||
else
|
||||
/* The default zero-initialization is fine for us; don't
|
||||
add anything to the CONSTRUCTOR. */
|
||||
@ -848,9 +872,12 @@ process_init_constructor (type, init, elts)
|
||||
&& (!init || TREE_HAS_CONSTRUCTOR (init)))
|
||||
warning ("missing initializer for member `%D'", field);
|
||||
|
||||
/* The default zero-initialization is fine for us; don't
|
||||
add anything to the CONSTRUCTOR. */
|
||||
continue;
|
||||
if (! zero_init_p (TREE_TYPE (field)))
|
||||
next1 = build_forced_zero_init (TREE_TYPE (field));
|
||||
else
|
||||
/* The default zero-initialization is fine for us; don't
|
||||
add anything to the CONSTRUCTOR. */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (next1 == error_mark_node)
|
||||
|
Loading…
x
Reference in New Issue
Block a user