aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2013-10-23 14:08:56 -0400
committerJason Merrill <jason@gcc.gnu.org>2013-10-23 14:08:56 -0400
commiteca7fc5755041ad90a7db18bbd6b3294f5075da7 (patch)
tree42c2ea99646dafa555892877e4e1670084770361 /gcc
parentd4c579b56109284162f084bf031cd4eea1f1b036 (diff)
downloadgcc-eca7fc5755041ad90a7db18bbd6b3294f5075da7.zip
gcc-eca7fc5755041ad90a7db18bbd6b3294f5075da7.tar.gz
gcc-eca7fc5755041ad90a7db18bbd6b3294f5075da7.tar.bz2
In C++11 a trivial [cd]tor might not be callable.
* class.c (user_provided_p): A function deleted on its declation in the class is not user-provided. (type_build_ctor_call): Also force a ctor call if we might have a deleted or private trivial ctor. (type_build_dtor_call): New. (deduce_noexcept_on_destructors): Remove obsolete code. * cp-tree.h: Declare type_build_dtor_call. * decl.c (expand_static_init): Make sure trivial dtors are callable. (cxx_maybe_build_cleanup): Likewise. * except.c (build_throw): Likewise. * init.c (build_value_init): Handle trivial but not callable ctors. (perform_target_ctor): Make sure trivial dtor is callable. (perform_member_init): Likewise. (expand_cleanup_for_base): Likewise. (build_vec_delete_1): Likewise. (build_delete): Likewise. (push_base_cleanups): Likewise. (build_new_1): Avoid redundant error. * method.c (synthesized_method_walk): Can't ever exit early in C++11. Always process the subobject destructor. * semantics.c (finish_compound_literal): Make sure trivial dtor is callable. * typeck2.c (split_nonconstant_init): Likewise. From-SVN: r203985
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog27
-rw-r--r--gcc/cp/call.c3
-rw-r--r--gcc/cp/class.c54
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl.c10
-rw-r--r--gcc/cp/except.c20
-rw-r--r--gcc/cp/init.c167
-rw-r--r--gcc/cp/method.c9
-rw-r--r--gcc/cp/semantics.c4
-rw-r--r--gcc/cp/typeck2.c5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/defaulted19.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/defaulted19a.C24
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/defaulted2.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/defaulted46.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/implicit11.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/sfinae21.C6
-rw-r--r--gcc/testsuite/g++.dg/ext/anon-struct4.C4
-rw-r--r--gcc/testsuite/g++.dg/init/ctor8.C5
-rw-r--r--gcc/testsuite/g++.dg/init/pr25811.C104
-rw-r--r--gcc/testsuite/g++.dg/init/pr29043.C18
-rw-r--r--gcc/testsuite/g++.dg/init/pr43719.C104
-rw-r--r--gcc/testsuite/g++.dg/init/pr44086.C12
-rw-r--r--gcc/testsuite/g++.dg/init/ref14.C2
-rw-r--r--gcc/testsuite/g++.dg/init/uninitialized1.C8
24 files changed, 384 insertions, 231 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c17e19d..99269af 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,30 @@
+2013-10-23 Jason Merrill <jason@redhat.com>
+
+ In C++11 a trivial [cd]tor might not be callable.
+ * class.c (user_provided_p): A function deleted on its declation
+ in the class is not user-provided.
+ (type_build_ctor_call): Also force a ctor call if we
+ might have a deleted or private trivial ctor.
+ (type_build_dtor_call): New.
+ (deduce_noexcept_on_destructors): Remove obsolete code.
+ * cp-tree.h: Declare type_build_dtor_call.
+ * decl.c (expand_static_init): Make sure trivial dtors are callable.
+ (cxx_maybe_build_cleanup): Likewise.
+ * except.c (build_throw): Likewise.
+ * init.c (build_value_init): Handle trivial but not callable ctors.
+ (perform_target_ctor): Make sure trivial dtor is callable.
+ (perform_member_init): Likewise.
+ (expand_cleanup_for_base): Likewise.
+ (build_vec_delete_1): Likewise.
+ (build_delete): Likewise.
+ (push_base_cleanups): Likewise.
+ (build_new_1): Avoid redundant error.
+ * method.c (synthesized_method_walk): Can't ever exit early in C++11.
+ Always process the subobject destructor.
+ * semantics.c (finish_compound_literal): Make sure trivial dtor is
+ callable.
+ * typeck2.c (split_nonconstant_init): Likewise.
+
2013-10-23 Edward Smith-Rowland <3dw4rd@verizon.net>
Implement C++14 [[deprecated]] modulo [[gnu::deprecated]] bugs.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 3ed73b8..cd90140 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -9273,6 +9273,9 @@ set_up_extended_ref_temp (tree decl, tree expr, vec<tree, va_gc> **cleanups,
static_aggregates = tree_cons (NULL_TREE, var,
static_aggregates);
}
+ else
+ /* Check whether the dtor is callable. */
+ cxx_maybe_build_cleanup (var, tf_warning_or_error);
}
*initp = init;
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index c587e55..43f90d7 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -4674,15 +4674,8 @@ deduce_noexcept_on_destructors (tree t)
if (!CLASSTYPE_METHOD_VEC (t))
return;
- bool saved_nontrivial_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t);
-
- /* Avoid early exit from synthesized_method_walk (c++/57645). */
- TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = true;
-
for (tree fns = CLASSTYPE_DESTRUCTORS (t); fns; fns = OVL_NEXT (fns))
deduce_noexcept_on_destructor (OVL_CURRENT (fns));
-
- TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = saved_nontrivial_dtor;
}
/* Subroutine of set_one_vmethod_tm_attributes. Search base classes
@@ -4884,7 +4877,8 @@ user_provided_p (tree fn)
return true;
else
return (!DECL_ARTIFICIAL (fn)
- && !DECL_DEFAULTED_IN_CLASS_P (fn));
+ && !(DECL_INITIALIZED_IN_CLASS_P (fn)
+ && (DECL_DEFAULTED_FN (fn) || DECL_DELETED_FN (fn))));
}
/* Returns true iff class T has a user-provided constructor. */
@@ -5149,7 +5143,7 @@ type_has_user_declared_move_assign (tree t)
}
/* Nonzero if we need to build up a constructor call when initializing an
- object of this class, either because it has a user-provided constructor
+ object of this class, either because it has a user-declared constructor
or because it doesn't have a default constructor (so we need to give an
error if no initializer is provided). Use TYPE_NEEDS_CONSTRUCTING when
what you care about is whether or not an object can be produced by a
@@ -5165,8 +5159,46 @@ type_build_ctor_call (tree t)
if (TYPE_NEEDS_CONSTRUCTING (t))
return true;
inner = strip_array_types (t);
- return (CLASS_TYPE_P (inner) && !TYPE_HAS_DEFAULT_CONSTRUCTOR (inner)
- && !ANON_AGGR_TYPE_P (inner));
+ if (!CLASS_TYPE_P (inner) || ANON_AGGR_TYPE_P (inner))
+ return false;
+ if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (inner))
+ return true;
+ /* A user-declared constructor might be private, and a constructor might
+ be trivial but deleted. */
+ for (tree fns = lookup_fnfields_slot (inner, complete_ctor_identifier);
+ fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+ if (!DECL_ARTIFICIAL (fn)
+ || DECL_DELETED_FN (fn))
+ return true;
+ }
+ return false;
+}
+
+/* Like type_build_ctor_call, but for destructors. */
+
+bool
+type_build_dtor_call (tree t)
+{
+ tree inner;
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
+ return true;
+ inner = strip_array_types (t);
+ if (!CLASS_TYPE_P (inner) || ANON_AGGR_TYPE_P (inner)
+ || !COMPLETE_TYPE_P (inner))
+ return false;
+ /* A user-declared destructor might be private, and a destructor might
+ be trivial but deleted. */
+ for (tree fns = lookup_fnfields_slot (inner, complete_dtor_identifier);
+ fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+ if (!DECL_ARTIFICIAL (fn)
+ || DECL_DELETED_FN (fn))
+ return true;
+ }
+ return false;
}
/* Remove all zero-width bit-fields from T. */
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b1347e2..507b389 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5115,6 +5115,7 @@ extern bool type_has_move_assign (tree);
extern bool type_has_user_declared_move_constructor (tree);
extern bool type_has_user_declared_move_assign(tree);
extern bool type_build_ctor_call (tree);
+extern bool type_build_dtor_call (tree);
extern void explain_non_literal_class (tree);
extern void defaulted_late_check (tree);
extern bool defaultable_fn_check (tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index fe8fe4e..1e92f2a 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -6897,7 +6897,11 @@ expand_static_init (tree decl, tree init)
/* Some variables require no dynamic initialization. */
if (!init
&& TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
- return;
+ {
+ /* Make sure the destructor is callable. */
+ cxx_maybe_build_cleanup (decl, tf_warning_or_error);
+ return;
+ }
if (DECL_THREAD_LOCAL_P (decl) && DECL_GNU_TLS_P (decl)
&& !DECL_FUNCTION_SCOPE_P (decl))
@@ -14296,7 +14300,7 @@ cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain)
}
/* Handle ordinary C++ destructors. */
type = TREE_TYPE (decl);
- if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+ if (type_build_dtor_call (type))
{
int flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR;
bool has_vbases = (TREE_CODE (type) == RECORD_TYPE
@@ -14317,6 +14321,8 @@ cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain)
sfk_complete_destructor, flags, 0, complain);
if (call == error_mark_node)
cleanup = error_mark_node;
+ else if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
+ /* Discard the call. */;
else if (cleanup)
cleanup = cp_build_compound_expr (cleanup, call, complain);
else
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index c76d944..daac0fd 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -868,17 +868,21 @@ build_throw (tree exp)
throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object)));
- if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (object)))
+ cleanup = NULL_TREE;
+ if (type_build_dtor_call (TREE_TYPE (object)))
{
- cleanup = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
+ tree fn = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
complete_dtor_identifier, 0);
- cleanup = BASELINK_FUNCTIONS (cleanup);
- mark_used (cleanup);
- cxx_mark_addressable (cleanup);
- /* Pretend it's a normal function. */
- cleanup = build1 (ADDR_EXPR, cleanup_type, cleanup);
+ fn = BASELINK_FUNCTIONS (fn);
+ mark_used (fn);
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (object)))
+ {
+ cxx_mark_addressable (fn);
+ /* Pretend it's a normal function. */
+ cleanup = build1 (ADDR_EXPR, cleanup_type, fn);
+ }
}
- else
+ if (cleanup == NULL_TREE)
cleanup = build_int_cst (cleanup_type, 0);
/* ??? Indicate that this function call throws throw_type. */
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index d18dc5e..78ea986 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -312,60 +312,55 @@ build_value_init (tree type, tsubst_flags_t complain)
To value-initialize an object of type T means:
- - if T is a class type (clause 9) with a user-provided constructor
- (12.1), then the default constructor for T is called (and the
- initialization is ill-formed if T has no accessible default
- constructor);
+ - if T is a class type (clause 9) with either no default constructor
+ (12.1) or a default constructor that is user-provided or deleted,
+ then then the object is default-initialized;
- - if T is a non-union class type without a user-provided constructor,
- then every non-static data member and base-class component of T is
- value-initialized;92)
+ - if T is a (possibly cv-qualified) class type without a user-provided
+ or deleted default constructor, then the object is zero-initialized
+ and the semantic constraints for default-initialization are checked,
+ and if T has a non-trivial default constructor, the object is
+ default-initialized;
- if T is an array type, then each element is value-initialized;
- otherwise, the object is zero-initialized.
A program that calls for default-initialization or
- value-initialization of an entity of reference type is ill-formed.
-
- 92) Value-initialization for such a class object may be implemented by
- zero-initializing the object and then calling the default
- constructor. */
+ value-initialization of an entity of reference type is ill-formed. */
/* The AGGR_INIT_EXPR tweaking below breaks in templates. */
gcc_assert (!processing_template_decl
|| (SCALAR_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE));
- if (CLASS_TYPE_P (type))
+ if (type_build_ctor_call (type))
{
- /* Instead of the above, only consider the user-providedness of the
- default constructor itself so value-initializing a class with an
- explicitly defaulted default constructor and another user-provided
- constructor works properly (c++std-core-19883). */
- if (type_has_user_provided_default_constructor (type)
- || (!TYPE_HAS_DEFAULT_CONSTRUCTOR (type)
- && type_has_user_provided_constructor (type)))
- return build_aggr_init_expr
- (type,
- build_special_member_call (NULL_TREE, complete_ctor_identifier,
- NULL, type, LOOKUP_NORMAL,
- complain));
+ tree ctor = build_aggr_init_expr
+ (type,
+ build_special_member_call (NULL_TREE, complete_ctor_identifier,
+ NULL, type, LOOKUP_NORMAL,
+ complain));
+ if (ctor == error_mark_node
+ || type_has_user_provided_default_constructor (type))
+ return ctor;
else if (TYPE_HAS_COMPLEX_DFLT (type))
{
/* This is a class that needs constructing, but doesn't have
a user-provided constructor. So we need to zero-initialize
the object and then call the implicitly defined ctor.
This will be handled in simplify_aggr_init_expr. */
- tree ctor = build_special_member_call
- (NULL_TREE, complete_ctor_identifier,
- NULL, type, LOOKUP_NORMAL, complain);
- ctor = build_aggr_init_expr (type, ctor);
- if (ctor != error_mark_node)
- AGGR_INIT_ZERO_FIRST (ctor) = 1;
+ AGGR_INIT_ZERO_FIRST (ctor) = 1;
return ctor;
}
}
- return build_value_init_noctor (type, complain);
+
+ /* Discard any access checking during subobject initialization;
+ the checks are implied by the call to the ctor which we have
+ verified is OK (cpp0x/defaulted46.C). */
+ push_deferring_access_checks (dk_deferred);
+ tree r = build_value_init_noctor (type, complain);
+ pop_deferring_access_checks ();
+ return r;
}
/* Like build_value_init, but don't call the constructor for TYPE. Used
@@ -503,14 +498,15 @@ perform_target_ctor (tree init)
finish_expr_stmt (build_aggr_init (decl, init,
LOOKUP_NORMAL|LOOKUP_DELEGATING_CONS,
tf_warning_or_error));
- if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+ if (type_build_dtor_call (type))
{
tree expr = build_delete (type, decl, sfk_complete_destructor,
LOOKUP_NORMAL
|LOOKUP_NONVIRTUAL
|LOOKUP_DESTRUCTOR,
0, tf_warning_or_error);
- if (expr != error_mark_node)
+ if (expr != error_mark_node
+ && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
finish_eh_cleanup (expr);
}
}
@@ -732,7 +728,7 @@ perform_member_init (tree member, tree init)
tf_warning_or_error));
}
- if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+ if (type_build_dtor_call (type))
{
tree expr;
@@ -744,7 +740,8 @@ perform_member_init (tree member, tree init)
LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0,
tf_warning_or_error);
- if (expr != error_mark_node)
+ if (expr != error_mark_node
+ && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
finish_eh_cleanup (expr);
}
}
@@ -1192,7 +1189,7 @@ expand_cleanup_for_base (tree binfo, tree flag)
{
tree expr;
- if (TYPE_HAS_TRIVIAL_DESTRUCTOR (BINFO_TYPE (binfo)))
+ if (!type_build_dtor_call (BINFO_TYPE (binfo)))
return;
/* Call the destructor. */
@@ -1202,6 +1199,10 @@ expand_cleanup_for_base (tree binfo, tree flag)
binfo,
LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
tf_warning_or_error);
+
+ if (TYPE_HAS_TRIVIAL_DESTRUCTOR (BINFO_TYPE (binfo)))
+ return;
+
if (flag)
expr = fold_build3_loc (input_location,
COND_EXPR, void_type_node,
@@ -2360,7 +2361,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
is_initialized = (type_build_ctor_call (elt_type) || *init != NULL);
- if (*init == NULL)
+ if (*init == NULL && cxx_dialect < cxx11)
{
bool maybe_uninitialized_error = false;
/* A program that calls for default-initialization [...] of an
@@ -3152,8 +3153,21 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
size_exp = size_in_bytes (type);
- if (! MAYBE_CLASS_TYPE_P (type) || TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
+ if (! MAYBE_CLASS_TYPE_P (type))
goto no_destructor;
+ else if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
+ {
+ /* Make sure the destructor is callable. */
+ if (type_build_dtor_call (type))
+ {
+ tmp = build_delete (ptype, base, sfk_complete_destructor,
+ LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1,
+ complain);
+ if (tmp == error_mark_node)
+ return error_mark_node;
+ }
+ goto no_destructor;
+ }
/* The below is short by the cookie size. */
virtual_size = size_binop (MULT_EXPR, size_exp,
@@ -3829,7 +3843,7 @@ build_dtor_call (tree exp, special_function_kind dtor_kind, int flags,
flags. See cp-tree.h for more info. */
tree
-build_delete (tree type, tree addr, special_function_kind auto_delete,
+build_delete (tree otype, tree addr, special_function_kind auto_delete,
int flags, int use_global_delete, tsubst_flags_t complain)
{
tree expr;
@@ -3837,22 +3851,33 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
if (addr == error_mark_node)
return error_mark_node;
+ tree type = TYPE_MAIN_VARIANT (otype);
+
/* Can happen when CURRENT_EXCEPTION_OBJECT gets its type
set to `error_mark_node' before it gets properly cleaned up. */
if (type == error_mark_node)
return error_mark_node;
- type = TYPE_MAIN_VARIANT (type);
+ if (TREE_CODE (type) == POINTER_TYPE)
+ type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
- addr = mark_rvalue_use (addr);
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ if (TYPE_DOMAIN (type) == NULL_TREE)
+ {
+ if (complain & tf_error)
+ error ("unknown array size in delete");
+ return error_mark_node;
+ }
+ return build_vec_delete (addr, array_type_nelts (type),
+ auto_delete, use_global_delete, complain);
+ }
- if (TYPE_PTR_P (type))
+ if (TYPE_PTR_P (otype))
{
bool complete_p = true;
- type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
- if (TREE_CODE (type) == ARRAY_TYPE)
- goto handle_array;
+ addr = mark_rvalue_use (addr);
/* We don't want to warn about delete of void*, only other
incomplete types. Deleting other incomplete types
@@ -3908,19 +3933,6 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
/* Throw away const and volatile on target type of addr. */
addr = convert_force (build_pointer_type (type), addr, 0, complain);
}
- else if (TREE_CODE (type) == ARRAY_TYPE)
- {
- handle_array:
-
- if (TYPE_DOMAIN (type) == NULL_TREE)
- {
- if (complain & tf_error)
- error ("unknown array size in delete");
- return error_mark_node;
- }
- return build_vec_delete (addr, array_type_nelts (type),
- auto_delete, use_global_delete, complain);
- }
else
{
/* Don't check PROTECT here; leave that decision to the
@@ -3935,10 +3947,18 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
addr = convert_force (build_pointer_type (type), addr, 0, complain);
}
- gcc_assert (MAYBE_CLASS_TYPE_P (type));
-
if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
{
+ /* Make sure the destructor is callable. */
+ if (type_build_dtor_call (type))
+ {
+ expr = build_dtor_call (cp_build_indirect_ref (addr, RO_NULL,
+ complain),
+ sfk_complete_destructor, flags, complain);
+ if (expr == error_mark_node)
+ return error_mark_node;
+ }
+
if (auto_delete != sfk_deleting_destructor)
return void_zero_node;
@@ -4062,7 +4082,7 @@ push_base_cleanups (void)
for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0;
vec_safe_iterate (vbases, i, &base_binfo); i++)
{
- if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo)))
+ if (type_build_dtor_call (BINFO_TYPE (base_binfo)))
{
expr = build_special_member_call (current_class_ref,
base_dtor_identifier,
@@ -4070,10 +4090,13 @@ push_base_cleanups (void)
base_binfo,
(LOOKUP_NORMAL
| LOOKUP_NONVIRTUAL),
- tf_warning_or_error);
- expr = build3 (COND_EXPR, void_type_node, cond,
- expr, void_zero_node);
- finish_decl_cleanup (NULL_TREE, expr);
+ tf_warning_or_error);
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo)))
+ {
+ expr = build3 (COND_EXPR, void_type_node, cond,
+ expr, void_zero_node);
+ finish_decl_cleanup (NULL_TREE, expr);
+ }
}
}
}
@@ -4082,8 +4105,8 @@ push_base_cleanups (void)
for (binfo = TYPE_BINFO (current_class_type), i = 0;
BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
{
- if (TYPE_HAS_TRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo))
- || BINFO_VIRTUAL_P (base_binfo))
+ if (BINFO_VIRTUAL_P (base_binfo)
+ || !type_build_dtor_call (BINFO_TYPE (base_binfo)))
continue;
expr = build_special_member_call (current_class_ref,
@@ -4091,7 +4114,8 @@ push_base_cleanups (void)
NULL, base_binfo,
LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
tf_warning_or_error);
- finish_decl_cleanup (NULL_TREE, expr);
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo)))
+ finish_decl_cleanup (NULL_TREE, expr);
}
/* Don't automatically destroy union members. */
@@ -4108,7 +4132,7 @@ push_base_cleanups (void)
continue;
if (ANON_UNION_TYPE_P (this_type))
continue;
- if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (this_type))
+ if (type_build_dtor_call (this_type))
{
tree this_member = (build_class_member_access_expr
(current_class_ref, member,
@@ -4119,7 +4143,8 @@ push_base_cleanups (void)
sfk_complete_destructor,
LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_NORMAL,
0, tf_warning_or_error);
- finish_decl_cleanup (NULL_TREE, expr);
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (this_type))
+ finish_decl_cleanup (NULL_TREE, expr);
}
}
}
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 4ac533e..593a4a6 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1265,8 +1265,9 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
class versions and other properties of the type. But a subobject
class can be trivially copyable and yet have overload resolution
choose a template constructor for initialization, depending on
- rvalueness and cv-quals. So we can't exit early for copy/move
- methods in C++0x. The same considerations apply in C++98/03, but
+ rvalueness and cv-quals. And furthermore, a member in a base might
+ be trivial but deleted or otherwise not callable. So we can't exit
+ early in C++0x. The same considerations apply in C++98/03, but
there the definition of triviality does not consider overload
resolution, so a constructor can be trivial even if it would otherwise
call a non-trivial constructor. */
@@ -1282,7 +1283,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
inform (input_location, "defaulted default constructor does "
"not initialize any non-static data member");
}
- if (!diag)
+ if (!diag && cxx_dialect < cxx11)
return;
}
@@ -1323,7 +1324,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
process_subob_fn (rval, spec_p, trivial_p, deleted_p,
constexpr_p, diag, basetype);
- if (ctor_p && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (basetype))
+ if (ctor_p)
{
/* In a constructor we also need to check the subobject
destructors for cleanup of partially constructed objects. */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index e56052d..052746c 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2521,6 +2521,10 @@ finish_compound_literal (tree type, tree compound_literal,
decl = pushdecl_top_level (decl);
DECL_NAME (decl) = make_anon_name ();
SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
+ /* Make sure the destructor is callable. */
+ tree clean = cxx_maybe_build_cleanup (decl, complain);
+ if (clean == error_mark_node)
+ return error_mark_node;
return decl;
}
else
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 011406c..4b71a76 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -640,12 +640,13 @@ split_nonconstant_init_1 (tree dest, tree init)
code = build_stmt (input_location, EXPR_STMT, code);
code = maybe_cleanup_point_expr_void (code);
add_stmt (code);
- if (!TYPE_HAS_TRIVIAL_DESTRUCTOR (inner_type))
+ if (type_build_dtor_call (inner_type))
{
code = (build_special_member_call
(sub, complete_dtor_identifier, NULL, inner_type,
LOOKUP_NORMAL, tf_warning_or_error));
- finish_eh_cleanup (code);
+ if (!TYPE_HAS_TRIVIAL_DESTRUCTOR (inner_type))
+ finish_eh_cleanup (code);
}
num_split_elts++;
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted19.C b/gcc/testsuite/g++.dg/cpp0x/defaulted19.C
index 5603632..f7de073 100644
--- a/gcc/testsuite/g++.dg/cpp0x/defaulted19.C
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted19.C
@@ -1,5 +1,6 @@
-// We allocate a cookie to help us run the destructor even if it's deleted.
-// { dg-options -std=c++11 }
+// We don't allocate a cookie to help us run the destructor if it's trivial,
+// even if it's deleted.
+// { dg-options "-std=c++11" }
// { dg-do run }
struct A
@@ -17,5 +18,5 @@ void *operator new[](__SIZE_TYPE__ t)
int main()
{
A* ap = new A[5];
- return ap == p;
+ return ap != p;
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted19a.C b/gcc/testsuite/g++.dg/cpp0x/defaulted19a.C
new file mode 100644
index 0000000..6d2a26a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted19a.C
@@ -0,0 +1,24 @@
+// We allocate a cookie to help us run the destructor if it's non-trivial,
+// even if it's deleted.
+// { dg-options "-std=c++0x" }
+// { dg-do run }
+
+struct B { ~B() {} };
+struct A
+{
+ B b;
+ ~A() = delete;
+};
+
+void *p = 0;
+void *operator new[](__SIZE_TYPE__ t)
+{
+ p = ::operator new (t);
+ return p;
+}
+
+int main()
+{
+ A* ap = new A[5];
+ return ap == p;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted2.C b/gcc/testsuite/g++.dg/cpp0x/defaulted2.C
index 8a8c874..3cef600 100644
--- a/gcc/testsuite/g++.dg/cpp0x/defaulted2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted2.C
@@ -62,7 +62,7 @@ int main()
{
F f;
F f2(f); // { dg-error "use" }
- B* b = new const B; // { dg-error "uninitialized const" }
+ const B* b = new const B; // { dg-error "uninitialized const" }
U u; // { dg-error "deleted" }
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted46.C b/gcc/testsuite/g++.dg/cpp0x/defaulted46.C
new file mode 100644
index 0000000..d4562c9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted46.C
@@ -0,0 +1,17 @@
+// { dg-require-effective-target c++11 }
+
+struct A
+{
+protected:
+ A() = default;
+ int i;
+};
+
+struct B: A {
+ B() = default;
+};
+
+int main()
+{
+ B();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/implicit11.C b/gcc/testsuite/g++.dg/cpp0x/implicit11.C
index 3b536e7..9f5841d 100644
--- a/gcc/testsuite/g++.dg/cpp0x/implicit11.C
+++ b/gcc/testsuite/g++.dg/cpp0x/implicit11.C
@@ -12,6 +12,6 @@ struct B: A { }; // { dg-error "deleted" }
extern B eb;
int main()
{
- B* b1 = new B; // { dg-error "use of deleted function" "" { xfail *-*-* } }
+ B* b1 = new B; // { dg-error "use of deleted function" }
B* b2 = new B(eb); // { dg-error "use of deleted function" }
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae21.C b/gcc/testsuite/g++.dg/cpp0x/sfinae21.C
index 3eab43c..62c003a 100644
--- a/gcc/testsuite/g++.dg/cpp0x/sfinae21.C
+++ b/gcc/testsuite/g++.dg/cpp0x/sfinae21.C
@@ -9,6 +9,10 @@ char f(int);
template<class>
char (&f(...))[2];
-struct ND { ND() = delete; };
+struct ND {
+ // Make ND() non-aggregate.
+ virtual void f();
+ ND() = delete;
+};
static_assert(sizeof(f<ND[1]>(0)) != 1, "Error");
diff --git a/gcc/testsuite/g++.dg/ext/anon-struct4.C b/gcc/testsuite/g++.dg/ext/anon-struct4.C
index 5d0bf71..9c8e887 100644
--- a/gcc/testsuite/g++.dg/ext/anon-struct4.C
+++ b/gcc/testsuite/g++.dg/ext/anon-struct4.C
@@ -1,5 +1,5 @@
// PR c++/14401
-struct { struct { int& i ; } bar ; } foo ; // { dg-error "uninitialized" "uninit" }
+struct { struct { int& i ; } bar ; } foo ; // { dg-error "deleted|uninitialized" "uninit" }
// { dg-warning "anonymous" "anon" { target c++98 } 3 }
-// { dg-message "should be initialized" "ref-uninit" { target *-*-* } 3 }
+// { dg-message "should be initialized" "ref-uninit" { target c++98 } 3 }
diff --git a/gcc/testsuite/g++.dg/init/ctor8.C b/gcc/testsuite/g++.dg/init/ctor8.C
index 3491f6a..7eb72eb 100644
--- a/gcc/testsuite/g++.dg/init/ctor8.C
+++ b/gcc/testsuite/g++.dg/init/ctor8.C
@@ -1,9 +1,10 @@
// PR c++/29039
-typedef struct S {
+typedef struct S { // { dg-error "reference" "" { target c++11 } }
int &r;
}; // { dg-warning "'typedef' was ignored" }
+
S f () {
- return S (); // { dg-error "reference" }
+ return S (); // { dg-error "reference|deleted" }
}
diff --git a/gcc/testsuite/g++.dg/init/pr25811.C b/gcc/testsuite/g++.dg/init/pr25811.C
index c906a9b..e8945da 100644
--- a/gcc/testsuite/g++.dg/init/pr25811.C
+++ b/gcc/testsuite/g++.dg/init/pr25811.C
@@ -1,51 +1,51 @@
// PR c++/25811
// { dg-do compile }
-struct A1
+struct A1 // { dg-error "uninitialized" "" { target c++11 } }
{
- int const j; // { dg-message "should be initialized" }
+ int const j; // { dg-message "should be initialized" "" { target c++98 } }
};
-struct A2
+struct A2 // { dg-error "uninitialized" "" { target c++11 } }
{
- int const volatile i; // { dg-message "should be initialized" }
+ int const volatile i; // { dg-message "should be initialized" "" { target c++98 } }
};
-struct A3
+struct A3 // { dg-error "uninitialized" "" { target c++11 } }
{
- int& ref; // { dg-message "should be initialized" }
+ int& ref; // { dg-message "should be initialized" "" { target c++98 } }
};
-struct A4
+struct A4 // { dg-error "uninitialized" "" { target c++11 } }
{
- int const& ref; // { dg-message "should be initialized" }
+ int const& ref; // { dg-message "should be initialized" "" { target c++98 } }
};
-struct A5
+struct A5 // { dg-error "uninitialized" "" { target c++11 } }
{
- int& ref; // { dg-message "should be initialized" }
- int const i; // { dg-message "should be initialized" }
+ int& ref; // { dg-message "should be initialized" "" { target c++98 } }
+ int const i; // { dg-message "should be initialized" "" { target c++98 } }
};
-template <class T> struct S1
+template <class T> struct S1 // { dg-error "uninitialized" "" { target c++11 } }
{
- T const i; // { dg-message "should be initialized" }
+ T const i; // { dg-message "should be initialized" "" { target c++98 } }
};
-template <class T> struct S2
+template <class T> struct S2 // { dg-error "uninitialized" "" { target c++11 } }
{
- T const volatile i; // { dg-message "should be initialized" }
+ T const volatile i; // { dg-message "should be initialized" "" { target c++98 } }
};
-template <class T> struct S3
+template <class T> struct S3 // { dg-error "uninitialized" "" { target c++11 } }
{
- T& ref; // { dg-message "should be initialized" }
+ T& ref; // { dg-message "should be initialized" "" { target c++98 } }
};
-template <class T> struct S4
+template <class T> struct S4 // { dg-error "uninitialized" "" { target c++11 } }
{
- T const i; // { dg-message "should be initialized" }
- T& ref; // { dg-message "should be initialized" }
+ T const i; // { dg-message "should be initialized" "" { target c++98 } }
+ T& ref; // { dg-message "should be initialized" "" { target c++98 } }
};
struct X
@@ -55,44 +55,44 @@ struct X
int const& r;
};
-struct Y11
+struct Y11 // { dg-error "uninitialized" "" { target c++11 } }
{
- int const i; // { dg-message "should be initialized" }
+ int const i; // { dg-message "should be initialized" "" { target c++98 } }
};
-struct Y1
+struct Y1 // { dg-error "deleted" "" { target c++11 } }
{
Y11 a[1];
};
-struct Y22
+struct Y22 // { dg-error "uninitialized" "" { target c++11 } }
{
- int& ref; // { dg-message "should be initialized" }
+ int& ref; // { dg-message "should be initialized" "" { target c++98 } }
};
-struct Y2
+struct Y2 // { dg-error "deleted" "" { target c++11 } }
{
Y22 a[1];
};
-struct Z1
+struct Z1 // { dg-error "uninitialized" "" { target c++11 } }
{
- int const i; // { dg-message "should be initialized" }
+ int const i; // { dg-message "should be initialized" "" { target c++98 } }
};
-struct Z2
+struct Z2 // { dg-error "uninitialized" "" { target c++11 } }
{
- int& ref; // { dg-message "should be initialized" }
+ int& ref; // { dg-message "should be initialized" "" { target c++98 } }
};
-struct Z3
+struct Z3 // { dg-error "uninitialized" "" { target c++11 } }
{
- int const i; // { dg-message "should be initialized" }
+ int const i; // { dg-message "should be initialized" "" { target c++98 } }
};
-struct Z4
+struct Z4 // { dg-error "uninitialized" "" { target c++11 } }
{
- int& ref; // { dg-message "should be initialized" }
+ int& ref; // { dg-message "should be initialized" "" { target c++98 } }
};
struct Z5
@@ -100,7 +100,7 @@ struct Z5
int i;
};
-struct Z
+struct Z // { dg-error "deleted" "" { target c++11 } }
{
Z1 z1;
Z2 z2;
@@ -109,54 +109,54 @@ struct Z
Z5 z5;
};
-union U
+union U // { dg-error "uninitialized" "" { target c++11 } }
{
- int const i; // { dg-message "should be initialized" }
+ int const i; // { dg-message "should be initialized" "" { target c++98 } }
};
void f1 ()
{
- new A1; // { dg-error "uninitialized const member" }
+ new A1; // { dg-error "deleted|uninitialized const member" }
}
void f2 ()
{
- new A2; // { dg-error "uninitialized const member" }
+ new A2; // { dg-error "deleted|uninitialized const member" }
}
void f3 ()
{
- new A3; // { dg-error "uninitialized reference member" }
+ new A3; // { dg-error "deleted|uninitialized reference member" }
}
void f4 ()
{
- new A4; // { dg-error "uninitialized reference member" }
+ new A4; // { dg-error "deleted|uninitialized reference member" }
}
void f5 ()
{
- new A5; // { dg-error "uninitialized reference member|uninitialized const member" }
+ new A5; // { dg-error "deleted|uninitialized reference member|uninitialized const member" }
}
void f6 ()
{
- new S1<int>; // { dg-error "uninitialized const member" }
+ new S1<int>; // { dg-error "deleted|uninitialized const member" }
}
void f7 ()
{
- new S2<int>; // { dg-error "uninitialized const member" }
+ new S2<int>; // { dg-error "deleted|uninitialized const member" }
}
void f8 ()
{
- new S3<int>; // { dg-error "uninitialized reference member" }
+ new S3<int>; // { dg-error "deleted|uninitialized reference member" }
}
void f9 ()
{
- new S4<int>; // { dg-error "uninitialized reference member|uninitialized const member" }
+ new S4<int>; // { dg-error "deleted|uninitialized reference member|uninitialized const member" }
}
void f10 ()
@@ -166,30 +166,30 @@ void f10 ()
void f11 ()
{
- new A1[1]; // { dg-error "uninitialized const member" }
+ new A1[1]; // { dg-error "deleted|uninitialized const member" }
}
void f12 ()
{
- new A3[1]; // { dg-error "uninitialized reference member" }
+ new A3[1]; // { dg-error "deleted|uninitialized reference member" }
}
void f13 ()
{
- new Y1; // { dg-error "uninitialized const member" }
+ new Y1; // { dg-error "deleted|uninitialized const member" }
}
void f14 ()
{
- new Y2; // { dg-error "uninitialized reference member" }
+ new Y2; // { dg-error "deleted|uninitialized reference member" }
}
void f15 ()
{
- new Z; // { dg-error "uninitialized reference member|uninitialized const member" }
+ new Z; // { dg-error "deleted|uninitialized reference member|uninitialized const member" }
}
void f16 ()
{
- new U; // { dg-error "uninitialized const member" }
+ new U; // { dg-error "deleted|uninitialized const member" }
}
diff --git a/gcc/testsuite/g++.dg/init/pr29043.C b/gcc/testsuite/g++.dg/init/pr29043.C
index 6ed31b5..f868dfb 100644
--- a/gcc/testsuite/g++.dg/init/pr29043.C
+++ b/gcc/testsuite/g++.dg/init/pr29043.C
@@ -1,27 +1,27 @@
// PR c++/29043
// { dg-do compile }
-struct S
+struct S // { dg-error "uninitialized" "" { target c++11 } }
{
- int const i; // { dg-message "should be initialized" }
+ int const i; // { dg-message "should be initialized" "" { target c++98 } }
};
class C
{
public:
- C() {} // { dg-error "uninitialized const member" }
+ C() {} // { dg-error "uninitialized const member|deleted" }
S s;
};
-struct S2
+struct S2 // { dg-error "uninitialized" "" { target c++11 } }
{
- int& ref; // { dg-message "should be initialized" }
+ int& ref; // { dg-message "should be initialized" "" { target c++98 } }
};
class C2
{
public:
- C2() {} // { dg-error "uninitialized reference member" }
+ C2() {} // { dg-error "uninitialized reference member|deleted" }
S2 s;
};
@@ -33,14 +33,14 @@ class C3
};
};
-struct S4
+struct S4 // { dg-error "uninitialized" "" { target c++11 } }
{
- int const i; // { dg-message "should be initialized" }
+ int const i; // { dg-message "should be initialized" "" { target c++98 } }
};
struct C4
{
- C4() {} // { dg-error "uninitialized const member" }
+ C4() {} // { dg-error "uninitialized const member|deleted" }
S4 s4[ 1 ];
};
diff --git a/gcc/testsuite/g++.dg/init/pr43719.C b/gcc/testsuite/g++.dg/init/pr43719.C
index d3487c9..13a8221 100644
--- a/gcc/testsuite/g++.dg/init/pr43719.C
+++ b/gcc/testsuite/g++.dg/init/pr43719.C
@@ -1,51 +1,51 @@
// PR c++/43719
// { dg-do compile }
-struct A1
+struct A1 // { dg-error "uninitialized" "" { target c++11 } }
{
- int const j; // { dg-message "should be initialized" }
+ int const j; // { dg-message "should be initialized" "" { target c++98 } }
};
-struct A2
+struct A2 // { dg-error "uninitialized" "" { target c++11 } }
{
- int const volatile i; // { dg-message "should be initialized" }
+ int const volatile i; // { dg-message "should be initialized" "" { target c++98 } }
};
-struct A3
+struct A3 // { dg-error "uninitialized" "" { target c++11 } }
{
- int& ref; // { dg-message "should be initialized" }
+ int& ref; // { dg-message "should be initialized" "" { target c++98 } }
};
-struct A4
+struct A4 // { dg-error "uninitialized" "" { target c++11 } }
{
- int const& ref; // { dg-message "should be initialized" }
+ int const& ref; // { dg-message "should be initialized" "" { target c++98 } }
};
-struct A5
+struct A5 // { dg-error "uninitialized" "" { target c++11 } }
{
- int& ref; // { dg-message "should be initialized" }
- int const i; // { dg-message "should be initialized" }
+ int& ref; // { dg-message "should be initialized" "" { target c++98 } }
+ int const i; // { dg-message "should be initialized" "" { target c++98 } }
};
-template <class T> struct S1
+template <class T> struct S1 // { dg-error "uninitialized" "" { target c++11 } }
{
- T const i; // { dg-message "should be initialized" }
+ T const i; // { dg-message "should be initialized" "" { target c++98 } }
};
-template <class T> struct S2
+template <class T> struct S2 // { dg-error "uninitialized" "" { target c++11 } }
{
- T const volatile i; // { dg-message "should be initialized" }
+ T const volatile i; // { dg-message "should be initialized" "" { target c++98 } }
};
-template <class T> struct S3
+template <class T> struct S3 // { dg-error "uninitialized" "" { target c++11 } }
{
- T& ref; // { dg-message "should be initialized" }
+ T& ref; // { dg-message "should be initialized" "" { target c++98 } }
};
-template <class T> struct S4
+template <class T> struct S4 // { dg-error "uninitialized" "" { target c++11 } }
{
- T const i; // { dg-message "should be initialized" }
- T& ref; // { dg-message "should be initialized" }
+ T const i; // { dg-message "should be initialized" "" { target c++98 } }
+ T& ref; // { dg-message "should be initialized" "" { target c++98 } }
};
struct X
@@ -55,44 +55,44 @@ struct X
int const& r;
};
-struct Y11
+struct Y11 // { dg-error "uninitialized" "" { target c++11 } }
{
- int const i; // { dg-message "should be initialized" }
+ int const i; // { dg-message "should be initialized" "" { target c++98 } }
};
-struct Y1
+struct Y1 // { dg-error "deleted" "" { target c++11 } }
{
Y11 a[1];
};
-struct Y22
+struct Y22 // { dg-error "uninitialized" "" { target c++11 } }
{
- int& ref; // { dg-message "should be initialized" }
+ int& ref; // { dg-message "should be initialized" "" { target c++98 } }
};
-struct Y2
+struct Y2 // { dg-error "deleted" "" { target c++11 } }
{
Y22 a[1];
};
-struct Z1
+struct Z1 // { dg-error "uninitialized" "" { target c++11 } }
{
- int const i; // { dg-message "should be initialized" }
+ int const i; // { dg-message "should be initialized" "" { target c++98 } }
};
-struct Z2
+struct Z2 // { dg-error "uninitialized" "" { target c++11 } }
{
- int& ref; // { dg-message "should be initialized" }
+ int& ref; // { dg-message "should be initialized" "" { target c++98 } }
};
-struct Z3
+struct Z3 // { dg-error "uninitialized" "" { target c++11 } }
{
- int const i; // { dg-message "should be initialized" }
+ int const i; // { dg-message "should be initialized" "" { target c++98 } }
};
-struct Z4
+struct Z4 // { dg-error "uninitialized" "" { target c++11 } }
{
- int& ref; // { dg-message "should be initialized" }
+ int& ref; // { dg-message "should be initialized" "" { target c++98 } }
};
struct Z5
@@ -100,7 +100,7 @@ struct Z5
int i;
};
-struct Z
+struct Z // { dg-error "deleted" "" { target c++11 } }
{
Z1 z1;
Z2 z2;
@@ -109,55 +109,55 @@ struct Z
Z5 z5;
};
-union U
+union U // { dg-error "uninitialized" "" { target c++11 } }
{
- int const i; // { dg-message "should be initialized" }
+ int const i; // { dg-message "should be initialized" "" { target c++98 } }
};
void f1 ()
{
- A1 a1; // { dg-error "uninitialized const member" }
+ A1 a1; // { dg-error "uninitialized const member|deleted" }
}
void f2 ()
{
- A2 a2; // { dg-error "uninitialized const member" }
+ A2 a2; // { dg-error "uninitialized const member|deleted" }
}
void f3 ()
{
- A3 a3; // { dg-error "uninitialized reference member" }
+ A3 a3; // { dg-error "uninitialized reference member|deleted" }
}
void f4 ()
{
- A4 a4; // { dg-error "uninitialized reference member" }
+ A4 a4; // { dg-error "uninitialized reference member|deleted" }
}
void f5 ()
{
- A5 a5; // { dg-error "uninitialized reference member|uninitialized const member" }
+ A5 a5; // { dg-error "uninitialized reference member|uninitialized const member|deleted" }
}
void f6 ()
{
- S1<int> s; // { dg-error "uninitialized const member" }
+ S1<int> s; // { dg-error "uninitialized const member|deleted" }
}
void f7 ()
{
- S2<int> s; // { dg-error "uninitialized const member" }
+ S2<int> s; // { dg-error "uninitialized const member|deleted" }
}
void f8 ()
{
- S3<int> s; // { dg-error "uninitialized reference member" }
+ S3<int> s; // { dg-error "uninitialized reference member|deleted" }
}
void f9 ()
{
- S4<int> s; // { dg-error "uninitialized reference member|uninitialized const member" }
+ S4<int> s; // { dg-error "uninitialized reference member|uninitialized const member|deleted" }
}
void f10 ()
@@ -167,31 +167,31 @@ void f10 ()
void f11 ()
{
- A1 a[ 1 ]; // { dg-error "uninitialized const member" }
+ A1 a[ 1 ]; // { dg-error "uninitialized const member|deleted" }
}
void f12 ()
{
- A3 a[ 1 ]; // { dg-error "uninitialized reference member" }
+ A3 a[ 1 ]; // { dg-error "uninitialized reference member|deleted" }
}
void f13 ()
{
- Y1 y1; // { dg-error "uninitialized const member" }
+ Y1 y1; // { dg-error "uninitialized const member|deleted" }
}
void f14 ()
{
- Y2 y2; // { dg-error "uninitialized reference member" }
+ Y2 y2; // { dg-error "uninitialized reference member|deleted" }
}
void f15 ()
{
- Z z; // { dg-error "uninitialized reference member|uninitialized const member" }
+ Z z; // { dg-error "uninitialized reference member|uninitialized const member|deleted" }
}
void f16 ()
{
- U u; // { dg-error "uninitialized const member" }
+ U u; // { dg-error "uninitialized const member|deleted" }
}
diff --git a/gcc/testsuite/g++.dg/init/pr44086.C b/gcc/testsuite/g++.dg/init/pr44086.C
index e3304f4..b4b0833 100644
--- a/gcc/testsuite/g++.dg/init/pr44086.C
+++ b/gcc/testsuite/g++.dg/init/pr44086.C
@@ -1,15 +1,15 @@
// PR c++/44086
// { dg-do compile }
-struct A
+struct A // { dg-error "uninitialized" "" { target c++11 } }
{
- int const i : 2; // { dg-message "should be initialized" }
+ int const i : 2; // { dg-message "should be initialized" "" { target c++98 } }
};
void f()
{
- A a; // { dg-error "uninitialized const" }
- new A; // { dg-error "uninitialized const" }
- A();
- new A();
+ A a; // { dg-error "deleted|uninitialized const" }
+ new A; // { dg-error "deleted|uninitialized const" }
+ A(); // { dg-error "deleted" "" { target c++11 } }
+ new A(); // { dg-error "deleted" "" { target c++11 } }
}
diff --git a/gcc/testsuite/g++.dg/init/ref14.C b/gcc/testsuite/g++.dg/init/ref14.C
index 212e6e9..6ac4241 100644
--- a/gcc/testsuite/g++.dg/init/ref14.C
+++ b/gcc/testsuite/g++.dg/init/ref14.C
@@ -1,4 +1,6 @@
// PR c++/33459
+// { dg-prune-output "uninitialized" }
+// { dg-prune-output "deleted" }
union A
{
diff --git a/gcc/testsuite/g++.dg/init/uninitialized1.C b/gcc/testsuite/g++.dg/init/uninitialized1.C
index 200c424..1e4f7ae 100644
--- a/gcc/testsuite/g++.dg/init/uninitialized1.C
+++ b/gcc/testsuite/g++.dg/init/uninitialized1.C
@@ -1,12 +1,12 @@
// PR c++/58126
-struct A {
+struct A { // { dg-error "uninitialized" "" { target c++11 } }
const int value1;
int& value2;
};
-struct B : A { };
+struct B : A { }; // { dg-error "deleted" "" { target c++11 } }
-A a; // { dg-error "uninitialized const member in 'struct A'|uninitialized reference member in 'struct A'" }
+A a; // { dg-error "deleted|uninitialized const member in 'struct A'|uninitialized reference member in 'struct A'" }
-B b; // { dg-error "uninitialized const member in base 'struct A' of 'struct B'|uninitialized reference member in base 'struct A' of 'struct B'" }
+B b; // { dg-error "deleted|uninitialized const member in base 'struct A' of 'struct B'|uninitialized reference member in base 'struct A' of 'struct B'" }