aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2008-11-28 18:35:37 -0500
committerJason Merrill <jason@gcc.gnu.org>2008-11-28 18:35:37 -0500
commit9dbd44061fac61c07bea329c9dfcc75d4cdd274f (patch)
treeaf46d0e75bd9fe9b716cf4cc892d56f23817d241 /gcc/cp
parent68d3564a41166f3378811ab5bfc5727248c1dd3a (diff)
downloadgcc-9dbd44061fac61c07bea329c9dfcc75d4cdd274f.zip
gcc-9dbd44061fac61c07bea329c9dfcc75d4cdd274f.tar.gz
gcc-9dbd44061fac61c07bea329c9dfcc75d4cdd274f.tar.bz2
re PR c++/38233 ('map' value type + new uninitted const member warnings causes error)
PR c++/38233 * init.c (perform_member_init): Fix value-initialization. (build_value_init_1): Add assert to catch cases that will break in the gimplifier. (build_default_init): Remove. * cp-tree.h: Remove its prototype. * pt.c (tsubst_expr) [DECL_EXPR]: Use build_value_init for value-initialization. From-SVN: r142265
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/init.c91
-rw-r--r--gcc/cp/pt.c3
4 files changed, 36 insertions, 68 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c9ce9ce..1c53d89 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,14 @@
2008-11-28 Jason Merrill <jason@redhat.com>
+ PR c++/38233
+ * init.c (perform_member_init): Fix value-initialization.
+ (build_value_init_1): Add assert to catch cases that will break
+ in the gimplifier.
+ (build_default_init): Remove.
+ * cp-tree.h: Remove its prototype.
+ * pt.c (tsubst_expr) [DECL_EXPR]: Use build_value_init for
+ value-initialization.
+
PR c++/38278
* parser.c (cp_parser_class_name): Only call
maybe_note_name_used_in_class if we actually found a class name.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 9f10ed1..a03fe9b 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4468,7 +4468,6 @@ extern tree build_new (tree, tree, tree, tree, int,
tsubst_flags_t);
extern tree build_vec_init (tree, tree, tree, bool, int,
tsubst_flags_t);
-extern tree build_default_init (tree, tree);
extern tree build_delete (tree, tree,
special_function_kind,
int, int);
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 61c78e1..39d87e3 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -266,52 +266,6 @@ build_zero_init (tree type, tree nelts, bool static_storage_p)
return init;
}
-/* Build an expression for the default-initialization of an object of
- the indicated TYPE. If NELTS is non-NULL, and TYPE is an
- ARRAY_TYPE, NELTS is the number of elements in the array. If
- initialization of TYPE requires calling constructors, this function
- returns NULL_TREE; the caller is responsible for arranging for the
- constructors to be called. */
-
-tree
-build_default_init (tree type, tree nelts)
-{
- /* [dcl.init]:
-
- To default-initialize an object of type T means:
-
- --if T is a non-POD class type (clause _class_), the default construc-
- tor for T is called (and the initialization is ill-formed if T has
- no accessible default constructor);
-
- --if T is an array type, each element is default-initialized;
-
- --otherwise, the storage for the object is zero-initialized.
-
- A program that calls for default-initialization of an entity of refer-
- ence type is ill-formed. */
-
- /* If TYPE_NEEDS_CONSTRUCTING is true, the caller is responsible for
- performing the initialization. This is confusing in that some
- non-PODs do not have TYPE_NEEDS_CONSTRUCTING set. (For example,
- a class with a pointer-to-data member as a non-static data member
- does not have TYPE_NEEDS_CONSTRUCTING set.) Therefore, we end up
- passing non-PODs to build_zero_init below, which is contrary to
- the semantics quoted above from [dcl.init].
-
- It happens, however, that the behavior of the constructor the
- standard says we should have generated would be precisely the
- same as that obtained by calling build_zero_init below, so things
- work out OK. */
- if (TYPE_NEEDS_CONSTRUCTING (type)
- || (nelts && TREE_CODE (nelts) != INTEGER_CST))
- return NULL_TREE;
-
- /* At this point, TYPE is either a POD class type, an array of POD
- classes, or something even more innocuous. */
- return build_zero_init (type, nelts, /*static_storage_p=*/false);
-}
-
/* Return a suitable initializer for value-initializing an object of type
TYPE, as described in [dcl.init]. If HAVE_CTOR is true, the initializer
for an enclosing object is already calling the constructor for this
@@ -442,6 +396,10 @@ build_value_init_1 (tree type, bool have_ctor)
max_index);
ce->value = build_value_init_1 (TREE_TYPE (type), have_ctor);
+
+ /* The gimplifier can't deal with a RANGE_EXPR of TARGET_EXPRs. */
+ gcc_assert (TREE_CODE (ce->value) != TARGET_EXPR
+ && TREE_CODE (ce->value) != AGGR_INIT_EXPR);
}
/* Build a constructor to contain the initializations. */
@@ -469,19 +427,13 @@ perform_member_init (tree member, tree init)
{
tree decl;
tree type = TREE_TYPE (member);
- bool is_explicit;
-
- is_explicit = (init != NULL_TREE);
/* Effective C++ rule 12 requires that all data members be
initialized. */
- if (warn_ecpp && !is_explicit && TREE_CODE (type) != ARRAY_TYPE)
+ if (warn_ecpp && init == NULL_TREE && TREE_CODE (type) != ARRAY_TYPE)
warning (OPT_Weffc__, "%J%qD should be initialized in the member initialization "
"list", current_function_decl, member);
- if (init == void_type_node)
- init = NULL_TREE;
-
/* Get an lvalue for the data member. */
decl = build_class_member_access_expr (current_class_ref, member,
/*access_path=*/NULL_TREE,
@@ -490,10 +442,28 @@ perform_member_init (tree member, tree init)
if (decl == error_mark_node)
return;
+ if (init == void_type_node)
+ {
+ /* mem() means value-initialization. */
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ init = build_vec_init (decl, NULL_TREE, NULL_TREE,
+ /*explicit_value_init_p=*/true,
+ /* from_array=*/0,
+ tf_warning_or_error);
+ else
+ {
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ warning (0, "%Jdefault-initialization of %q#D, "
+ "which has reference type",
+ current_function_decl, member);
+ init = build2 (INIT_EXPR, type, decl, build_value_init (type));
+ }
+ finish_expr_stmt (init);
+ }
/* Deal with this here, as we will get confused if we try to call the
assignment op for an anonymous union. This can happen in a
synthesized copy constructor. */
- if (ANON_AGGR_TYPE_P (type))
+ else if (ANON_AGGR_TYPE_P (type))
{
if (init)
{
@@ -503,9 +473,8 @@ perform_member_init (tree member, tree init)
}
else if (TYPE_NEEDS_CONSTRUCTING (type))
{
- if (is_explicit
+ if (init != NULL_TREE
&& TREE_CODE (type) == ARRAY_TYPE
- && init != NULL_TREE
&& TREE_CHAIN (init) == NULL_TREE
&& TREE_CODE (TREE_TYPE (TREE_VALUE (init))) == ARRAY_TYPE)
{
@@ -532,16 +501,8 @@ perform_member_init (tree member, tree init)
{
if (init == NULL_TREE)
{
- if (is_explicit)
- {
- init = build_default_init (type, /*nelts=*/NULL_TREE);
- if (TREE_CODE (type) == REFERENCE_TYPE)
- warning (0, "%Jdefault-initialization of %q#D, "
- "which has reference type",
- current_function_decl, member);
- }
/* member traversal: note it leaves init NULL */
- else if (TREE_CODE (type) == REFERENCE_TYPE)
+ if (TREE_CODE (type) == REFERENCE_TYPE)
permerror (input_location, "%Juninitialized reference member %qD",
current_function_decl, member);
else if (CP_TYPE_CONST_P (type))
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 127d37c..241cea6 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -10560,8 +10560,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
pack expansion where the parameter packs
used in that expansion were of length
zero. */
- init = build_default_init (TREE_TYPE (decl),
- NULL_TREE);
+ init = build_value_init (TREE_TYPE (decl));
else
init = t;
}