Commit eca7fc57 by Jason Merrill Committed by Jason Merrill

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
parent d4c579b5
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> 2013-10-23 Edward Smith-Rowland <3dw4rd@verizon.net>
Implement C++14 [[deprecated]] modulo [[gnu::deprecated]] bugs. 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, ...@@ -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 = tree_cons (NULL_TREE, var,
static_aggregates); static_aggregates);
} }
else
/* Check whether the dtor is callable. */
cxx_maybe_build_cleanup (var, tf_warning_or_error);
} }
*initp = init; *initp = init;
......
...@@ -4674,15 +4674,8 @@ deduce_noexcept_on_destructors (tree t) ...@@ -4674,15 +4674,8 @@ deduce_noexcept_on_destructors (tree t)
if (!CLASSTYPE_METHOD_VEC (t)) if (!CLASSTYPE_METHOD_VEC (t))
return; 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)) for (tree fns = CLASSTYPE_DESTRUCTORS (t); fns; fns = OVL_NEXT (fns))
deduce_noexcept_on_destructor (OVL_CURRENT (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 /* Subroutine of set_one_vmethod_tm_attributes. Search base classes
...@@ -4884,7 +4877,8 @@ user_provided_p (tree fn) ...@@ -4884,7 +4877,8 @@ user_provided_p (tree fn)
return true; return true;
else else
return (!DECL_ARTIFICIAL (fn) 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. */ /* Returns true iff class T has a user-provided constructor. */
...@@ -5149,7 +5143,7 @@ type_has_user_declared_move_assign (tree t) ...@@ -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 /* 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 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 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 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) ...@@ -5165,8 +5159,46 @@ type_build_ctor_call (tree t)
if (TYPE_NEEDS_CONSTRUCTING (t)) if (TYPE_NEEDS_CONSTRUCTING (t))
return true; return true;
inner = strip_array_types (t); inner = strip_array_types (t);
return (CLASS_TYPE_P (inner) && !TYPE_HAS_DEFAULT_CONSTRUCTOR (inner) if (!CLASS_TYPE_P (inner) || ANON_AGGR_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. */ /* Remove all zero-width bit-fields from T. */
......
...@@ -5115,6 +5115,7 @@ extern bool type_has_move_assign (tree); ...@@ -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_constructor (tree);
extern bool type_has_user_declared_move_assign(tree); extern bool type_has_user_declared_move_assign(tree);
extern bool type_build_ctor_call (tree); extern bool type_build_ctor_call (tree);
extern bool type_build_dtor_call (tree);
extern void explain_non_literal_class (tree); extern void explain_non_literal_class (tree);
extern void defaulted_late_check (tree); extern void defaulted_late_check (tree);
extern bool defaultable_fn_check (tree); extern bool defaultable_fn_check (tree);
......
...@@ -6897,7 +6897,11 @@ expand_static_init (tree decl, tree init) ...@@ -6897,7 +6897,11 @@ expand_static_init (tree decl, tree init)
/* Some variables require no dynamic initialization. */ /* Some variables require no dynamic initialization. */
if (!init if (!init
&& TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl))) && 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) if (DECL_THREAD_LOCAL_P (decl) && DECL_GNU_TLS_P (decl)
&& !DECL_FUNCTION_SCOPE_P (decl)) && !DECL_FUNCTION_SCOPE_P (decl))
...@@ -14296,7 +14300,7 @@ cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain) ...@@ -14296,7 +14300,7 @@ cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain)
} }
/* Handle ordinary C++ destructors. */ /* Handle ordinary C++ destructors. */
type = TREE_TYPE (decl); type = TREE_TYPE (decl);
if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) if (type_build_dtor_call (type))
{ {
int flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR; int flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR;
bool has_vbases = (TREE_CODE (type) == RECORD_TYPE bool has_vbases = (TREE_CODE (type) == RECORD_TYPE
...@@ -14317,6 +14321,8 @@ cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain) ...@@ -14317,6 +14321,8 @@ cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain)
sfk_complete_destructor, flags, 0, complain); sfk_complete_destructor, flags, 0, complain);
if (call == error_mark_node) if (call == error_mark_node)
cleanup = error_mark_node; cleanup = error_mark_node;
else if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
/* Discard the call. */;
else if (cleanup) else if (cleanup)
cleanup = cp_build_compound_expr (cleanup, call, complain); cleanup = cp_build_compound_expr (cleanup, call, complain);
else else
......
...@@ -868,17 +868,21 @@ build_throw (tree exp) ...@@ -868,17 +868,21 @@ build_throw (tree exp)
throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object))); 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); complete_dtor_identifier, 0);
cleanup = BASELINK_FUNCTIONS (cleanup); fn = BASELINK_FUNCTIONS (fn);
mark_used (cleanup); mark_used (fn);
cxx_mark_addressable (cleanup); if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (object)))
/* Pretend it's a normal function. */ {
cleanup = build1 (ADDR_EXPR, cleanup_type, cleanup); 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); cleanup = build_int_cst (cleanup_type, 0);
/* ??? Indicate that this function call throws throw_type. */ /* ??? Indicate that this function call throws throw_type. */
......
...@@ -1265,8 +1265,9 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, ...@@ -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 versions and other properties of the type. But a subobject
class can be trivially copyable and yet have overload resolution class can be trivially copyable and yet have overload resolution
choose a template constructor for initialization, depending on choose a template constructor for initialization, depending on
rvalueness and cv-quals. So we can't exit early for copy/move rvalueness and cv-quals. And furthermore, a member in a base might
methods in C++0x. The same considerations apply in C++98/03, but 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 there the definition of triviality does not consider overload
resolution, so a constructor can be trivial even if it would otherwise resolution, so a constructor can be trivial even if it would otherwise
call a non-trivial constructor. */ call a non-trivial constructor. */
...@@ -1282,7 +1283,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, ...@@ -1282,7 +1283,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
inform (input_location, "defaulted default constructor does " inform (input_location, "defaulted default constructor does "
"not initialize any non-static data member"); "not initialize any non-static data member");
} }
if (!diag) if (!diag && cxx_dialect < cxx11)
return; return;
} }
...@@ -1323,7 +1324,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, ...@@ -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, process_subob_fn (rval, spec_p, trivial_p, deleted_p,
constexpr_p, diag, basetype); 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 /* In a constructor we also need to check the subobject
destructors for cleanup of partially constructed objects. */ destructors for cleanup of partially constructed objects. */
......
...@@ -2521,6 +2521,10 @@ finish_compound_literal (tree type, tree compound_literal, ...@@ -2521,6 +2521,10 @@ finish_compound_literal (tree type, tree compound_literal,
decl = pushdecl_top_level (decl); decl = pushdecl_top_level (decl);
DECL_NAME (decl) = make_anon_name (); DECL_NAME (decl) = make_anon_name ();
SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl)); 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; return decl;
} }
else else
......
...@@ -640,12 +640,13 @@ split_nonconstant_init_1 (tree dest, tree init) ...@@ -640,12 +640,13 @@ split_nonconstant_init_1 (tree dest, tree init)
code = build_stmt (input_location, EXPR_STMT, code); code = build_stmt (input_location, EXPR_STMT, code);
code = maybe_cleanup_point_expr_void (code); code = maybe_cleanup_point_expr_void (code);
add_stmt (code); add_stmt (code);
if (!TYPE_HAS_TRIVIAL_DESTRUCTOR (inner_type)) if (type_build_dtor_call (inner_type))
{ {
code = (build_special_member_call code = (build_special_member_call
(sub, complete_dtor_identifier, NULL, inner_type, (sub, complete_dtor_identifier, NULL, inner_type,
LOOKUP_NORMAL, tf_warning_or_error)); LOOKUP_NORMAL, tf_warning_or_error));
finish_eh_cleanup (code); if (!TYPE_HAS_TRIVIAL_DESTRUCTOR (inner_type))
finish_eh_cleanup (code);
} }
num_split_elts++; num_split_elts++;
......
// We allocate a cookie to help us run the destructor even if it's deleted. // We don't allocate a cookie to help us run the destructor if it's trivial,
// { dg-options -std=c++11 } // even if it's deleted.
// { dg-options "-std=c++11" }
// { dg-do run } // { dg-do run }
struct A struct A
...@@ -17,5 +18,5 @@ void *operator new[](__SIZE_TYPE__ t) ...@@ -17,5 +18,5 @@ void *operator new[](__SIZE_TYPE__ t)
int main() int main()
{ {
A* ap = new A[5]; A* ap = new A[5];
return ap == p; return ap != p;
} }
// 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() ...@@ -62,7 +62,7 @@ int main()
{ {
F f; F f;
F f2(f); // { dg-error "use" } 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" } U u; // { dg-error "deleted" }
} }
......
// { 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" } ...@@ -12,6 +12,6 @@ struct B: A { }; // { dg-error "deleted" }
extern B eb; extern B eb;
int main() 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" } B* b2 = new B(eb); // { dg-error "use of deleted function" }
} }
...@@ -9,6 +9,10 @@ char f(int); ...@@ -9,6 +9,10 @@ char f(int);
template<class> template<class>
char (&f(...))[2]; 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"); static_assert(sizeof(f<ND[1]>(0)) != 1, "Error");
// PR c++/14401 // 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-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 }
// PR c++/29039 // PR c++/29039
typedef struct S { typedef struct S { // { dg-error "reference" "" { target c++11 } }
int &r; int &r;
}; // { dg-warning "'typedef' was ignored" } }; // { dg-warning "'typedef' was ignored" }
S f () { S f () {
return S (); // { dg-error "reference" } return S (); // { dg-error "reference|deleted" }
} }
// PR c++/25811 // PR c++/25811
// { dg-do compile } // { 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& ref; // { dg-message "should be initialized" "" { target c++98 } }
int const i; // { dg-message "should be initialized" } 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 const i; // { dg-message "should be initialized" "" { target c++98 } }
T& ref; // { dg-message "should be initialized" } T& ref; // { dg-message "should be initialized" "" { target c++98 } }
}; };
struct X struct X
...@@ -55,44 +55,44 @@ struct X ...@@ -55,44 +55,44 @@ struct X
int const& r; 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]; 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]; 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 struct Z5
...@@ -100,7 +100,7 @@ struct Z5 ...@@ -100,7 +100,7 @@ struct Z5
int i; int i;
}; };
struct Z struct Z // { dg-error "deleted" "" { target c++11 } }
{ {
Z1 z1; Z1 z1;
Z2 z2; Z2 z2;
...@@ -109,54 +109,54 @@ struct Z ...@@ -109,54 +109,54 @@ struct Z
Z5 z5; 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 () void f1 ()
{ {
new A1; // { dg-error "uninitialized const member" } new A1; // { dg-error "deleted|uninitialized const member" }
} }
void f2 () void f2 ()
{ {
new A2; // { dg-error "uninitialized const member" } new A2; // { dg-error "deleted|uninitialized const member" }
} }
void f3 () void f3 ()
{ {
new A3; // { dg-error "uninitialized reference member" } new A3; // { dg-error "deleted|uninitialized reference member" }
} }
void f4 () void f4 ()
{ {
new A4; // { dg-error "uninitialized reference member" } new A4; // { dg-error "deleted|uninitialized reference member" }
} }
void f5 () 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 () void f6 ()
{ {
new S1<int>; // { dg-error "uninitialized const member" } new S1<int>; // { dg-error "deleted|uninitialized const member" }
} }
void f7 () void f7 ()
{ {
new S2<int>; // { dg-error "uninitialized const member" } new S2<int>; // { dg-error "deleted|uninitialized const member" }
} }
void f8 () void f8 ()
{ {
new S3<int>; // { dg-error "uninitialized reference member" } new S3<int>; // { dg-error "deleted|uninitialized reference member" }
} }
void f9 () 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 () void f10 ()
...@@ -166,30 +166,30 @@ void f10 () ...@@ -166,30 +166,30 @@ void f10 ()
void f11 () void f11 ()
{ {
new A1[1]; // { dg-error "uninitialized const member" } new A1[1]; // { dg-error "deleted|uninitialized const member" }
} }
void f12 () void f12 ()
{ {
new A3[1]; // { dg-error "uninitialized reference member" } new A3[1]; // { dg-error "deleted|uninitialized reference member" }
} }
void f13 () void f13 ()
{ {
new Y1; // { dg-error "uninitialized const member" } new Y1; // { dg-error "deleted|uninitialized const member" }
} }
void f14 () void f14 ()
{ {
new Y2; // { dg-error "uninitialized reference member" } new Y2; // { dg-error "deleted|uninitialized reference member" }
} }
void f15 () 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 () void f16 ()
{ {
new U; // { dg-error "uninitialized const member" } new U; // { dg-error "deleted|uninitialized const member" }
} }
// PR c++/29043 // PR c++/29043
// { dg-do compile } // { 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 class C
{ {
public: public:
C() {} // { dg-error "uninitialized const member" } C() {} // { dg-error "uninitialized const member|deleted" }
S s; 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 class C2
{ {
public: public:
C2() {} // { dg-error "uninitialized reference member" } C2() {} // { dg-error "uninitialized reference member|deleted" }
S2 s; S2 s;
}; };
...@@ -33,14 +33,14 @@ class C3 ...@@ -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 struct C4
{ {
C4() {} // { dg-error "uninitialized const member" } C4() {} // { dg-error "uninitialized const member|deleted" }
S4 s4[ 1 ]; S4 s4[ 1 ];
}; };
......
// PR c++/43719 // PR c++/43719
// { dg-do compile } // { 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& ref; // { dg-message "should be initialized" "" { target c++98 } }
int const i; // { dg-message "should be initialized" } 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 const i; // { dg-message "should be initialized" "" { target c++98 } }
T& ref; // { dg-message "should be initialized" } T& ref; // { dg-message "should be initialized" "" { target c++98 } }
}; };
struct X struct X
...@@ -55,44 +55,44 @@ struct X ...@@ -55,44 +55,44 @@ struct X
int const& r; 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]; 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]; 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 struct Z5
...@@ -100,7 +100,7 @@ struct Z5 ...@@ -100,7 +100,7 @@ struct Z5
int i; int i;
}; };
struct Z struct Z // { dg-error "deleted" "" { target c++11 } }
{ {
Z1 z1; Z1 z1;
Z2 z2; Z2 z2;
...@@ -109,55 +109,55 @@ struct Z ...@@ -109,55 +109,55 @@ struct Z
Z5 z5; 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 () void f1 ()
{ {
A1 a1; // { dg-error "uninitialized const member" } A1 a1; // { dg-error "uninitialized const member|deleted" }
} }
void f2 () void f2 ()
{ {
A2 a2; // { dg-error "uninitialized const member" } A2 a2; // { dg-error "uninitialized const member|deleted" }
} }
void f3 () void f3 ()
{ {
A3 a3; // { dg-error "uninitialized reference member" } A3 a3; // { dg-error "uninitialized reference member|deleted" }
} }
void f4 () void f4 ()
{ {
A4 a4; // { dg-error "uninitialized reference member" } A4 a4; // { dg-error "uninitialized reference member|deleted" }
} }
void f5 () 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 () void f6 ()
{ {
S1<int> s; // { dg-error "uninitialized const member" } S1<int> s; // { dg-error "uninitialized const member|deleted" }
} }
void f7 () void f7 ()
{ {
S2<int> s; // { dg-error "uninitialized const member" } S2<int> s; // { dg-error "uninitialized const member|deleted" }
} }
void f8 () void f8 ()
{ {
S3<int> s; // { dg-error "uninitialized reference member" } S3<int> s; // { dg-error "uninitialized reference member|deleted" }
} }
void f9 () 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 () void f10 ()
...@@ -167,31 +167,31 @@ void f10 () ...@@ -167,31 +167,31 @@ void f10 ()
void f11 () void f11 ()
{ {
A1 a[ 1 ]; // { dg-error "uninitialized const member" } A1 a[ 1 ]; // { dg-error "uninitialized const member|deleted" }
} }
void f12 () void f12 ()
{ {
A3 a[ 1 ]; // { dg-error "uninitialized reference member" } A3 a[ 1 ]; // { dg-error "uninitialized reference member|deleted" }
} }
void f13 () void f13 ()
{ {
Y1 y1; // { dg-error "uninitialized const member" } Y1 y1; // { dg-error "uninitialized const member|deleted" }
} }
void f14 () void f14 ()
{ {
Y2 y2; // { dg-error "uninitialized reference member" } Y2 y2; // { dg-error "uninitialized reference member|deleted" }
} }
void f15 () 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 () void f16 ()
{ {
U u; // { dg-error "uninitialized const member" } U u; // { dg-error "uninitialized const member|deleted" }
} }
// PR c++/44086 // PR c++/44086
// { dg-do compile } // { 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() void f()
{ {
A a; // { dg-error "uninitialized const" } A a; // { dg-error "deleted|uninitialized const" }
new A; // { dg-error "uninitialized const" } new A; // { dg-error "deleted|uninitialized const" }
A(); A(); // { dg-error "deleted" "" { target c++11 } }
new A(); new A(); // { dg-error "deleted" "" { target c++11 } }
} }
// PR c++/33459 // PR c++/33459
// { dg-prune-output "uninitialized" }
// { dg-prune-output "deleted" }
union A union A
{ {
......
// PR c++/58126 // PR c++/58126
struct A { struct A { // { dg-error "uninitialized" "" { target c++11 } }
const int value1; const int value1;
int& value2; 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'" }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment