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
This commit is contained in:
parent
d4c579b561
commit
eca7fc5755
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
167
gcc/cp/init.c
167
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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" }
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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" }
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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" }
|
||||
}
|
||||
|
|
|
@ -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" }
|
||||
}
|
||||
|
|
|
@ -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 ];
|
||||
};
|
||||
|
||||
|
|
|
@ -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" }
|
||||
}
|
||||
|
||||
|
|
|
@ -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 } }
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// PR c++/33459
|
||||
// { dg-prune-output "uninitialized" }
|
||||
// { dg-prune-output "deleted" }
|
||||
|
||||
union A
|
||||
{
|
||||
|
|
|
@ -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'" }
|
||||
|
|
Loading…
Reference in New Issue