re PR c++/63362 (The c++11 triviality-traits need front-end help)
PR c++/63362 * class.c (type_has_non_user_provided_default_constructor): Rename from type_has_user_provided_default_constructor, reverse sense. (default_init_uninitialized_part, explain_non_literal_class): Adjust. (check_bases_and_members): Set TYPE_HAS_COMPLEX_DFLT. * call.c (build_new_method_call_1): Adjust. * cp-tree.h: Adjust. * decl.c (grok_special_member_properties): Don't set TYPE_HAS_COMPLEX_DFLT. * init.c (build_value_init_noctor): Don't use type_has_user_provided_default_constructor. From-SVN: r215771
This commit is contained in:
parent
c790b7febc
commit
a710f1f83c
7 changed files with 59 additions and 20 deletions
|
@ -1,3 +1,17 @@
|
|||
2014-10-01 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/63362
|
||||
* class.c (type_has_non_user_provided_default_constructor): Rename
|
||||
from type_has_user_provided_default_constructor, reverse sense.
|
||||
(default_init_uninitialized_part, explain_non_literal_class): Adjust.
|
||||
(check_bases_and_members): Set TYPE_HAS_COMPLEX_DFLT.
|
||||
* call.c (build_new_method_call_1): Adjust.
|
||||
* cp-tree.h: Adjust.
|
||||
* decl.c (grok_special_member_properties): Don't set
|
||||
TYPE_HAS_COMPLEX_DFLT.
|
||||
* init.c (build_value_init_noctor): Don't use
|
||||
type_has_user_provided_default_constructor.
|
||||
|
||||
2014-09-30 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* cp-tree.h (cp_trait_kind): Add CPTK_IS_TRIVIALLY_ASSIGNABLE and
|
||||
|
|
|
@ -7941,7 +7941,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
|
|||
&& TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype)
|
||||
/* For a user-provided default constructor, use the normal
|
||||
mechanisms so that protected access works. */
|
||||
&& !type_has_user_provided_default_constructor (basetype)
|
||||
&& type_has_non_user_provided_default_constructor (basetype)
|
||||
&& !processing_template_decl)
|
||||
init = build_value_init (basetype, complain);
|
||||
|
||||
|
|
|
@ -4937,21 +4937,25 @@ type_has_user_provided_constructor (tree t)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Returns true iff class T has a user-provided default constructor. */
|
||||
/* Returns true iff class T has a non-user-provided (i.e. implicitly
|
||||
declared or explicitly defaulted in the class body) default
|
||||
constructor. */
|
||||
|
||||
bool
|
||||
type_has_user_provided_default_constructor (tree t)
|
||||
type_has_non_user_provided_default_constructor (tree t)
|
||||
{
|
||||
tree fns;
|
||||
|
||||
if (!TYPE_HAS_USER_CONSTRUCTOR (t))
|
||||
if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (t))
|
||||
return false;
|
||||
if (CLASSTYPE_LAZY_DEFAULT_CTOR (t))
|
||||
return true;
|
||||
|
||||
for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
|
||||
{
|
||||
tree fn = OVL_CURRENT (fns);
|
||||
if (TREE_CODE (fn) == FUNCTION_DECL
|
||||
&& user_provided_p (fn)
|
||||
&& !user_provided_p (fn)
|
||||
&& sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (fn)))
|
||||
return true;
|
||||
}
|
||||
|
@ -5009,7 +5013,7 @@ default_init_uninitialized_part (tree type)
|
|||
type = strip_array_types (type);
|
||||
if (!CLASS_TYPE_P (type))
|
||||
return type;
|
||||
if (type_has_user_provided_default_constructor (type))
|
||||
if (!type_has_non_user_provided_default_constructor (type))
|
||||
return NULL_TREE;
|
||||
for (binfo = TYPE_BINFO (type), i = 0;
|
||||
BINFO_BASE_ITERATE (binfo, i, t); ++i)
|
||||
|
@ -5383,8 +5387,7 @@ explain_non_literal_class (tree t)
|
|||
inform (0, " %q+T is not an aggregate, does not have a trivial "
|
||||
"default constructor, and has no constexpr constructor that "
|
||||
"is not a copy or move constructor", t);
|
||||
if (TYPE_HAS_DEFAULT_CONSTRUCTOR (t)
|
||||
&& !type_has_user_provided_default_constructor (t))
|
||||
if (type_has_non_user_provided_default_constructor (t))
|
||||
{
|
||||
/* Note that we can't simply call locate_ctor because when the
|
||||
constructor is deleted it just returns NULL_TREE. */
|
||||
|
@ -5528,6 +5531,13 @@ check_bases_and_members (tree t)
|
|||
TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) |= TYPE_CONTAINS_VPTR_P (t);
|
||||
TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_CONTAINS_VPTR_P (t);
|
||||
|
||||
/* If the only explicitly declared default constructor is user-provided,
|
||||
set TYPE_HAS_COMPLEX_DFLT. */
|
||||
if (!TYPE_HAS_COMPLEX_DFLT (t)
|
||||
&& TYPE_HAS_DEFAULT_CONSTRUCTOR (t)
|
||||
&& !type_has_non_user_provided_default_constructor (t))
|
||||
TYPE_HAS_COMPLEX_DFLT (t) = true;
|
||||
|
||||
/* Warn if a public base of a polymorphic type has an accessible
|
||||
non-virtual destructor. It is only now that we know the class is
|
||||
polymorphic. Although a polymorphic base will have a already
|
||||
|
|
|
@ -3484,7 +3484,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
|
|||
/* Nonzero if there is a non-trivial X::X(X&&) for this class. */
|
||||
#define TYPE_HAS_COMPLEX_MOVE_CTOR(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_move_ctor)
|
||||
|
||||
/* Nonzero if there is a non-trivial default constructor for this class. */
|
||||
/* Nonzero if there is no trivial default constructor for this class. */
|
||||
#define TYPE_HAS_COMPLEX_DFLT(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_dflt)
|
||||
|
||||
/* Nonzero if TYPE has a trivial destructor. From [class.dtor]:
|
||||
|
@ -5195,7 +5195,7 @@ extern bool type_has_user_nondefault_constructor (tree);
|
|||
extern tree in_class_defaulted_default_constructor (tree);
|
||||
extern bool user_provided_p (tree);
|
||||
extern bool type_has_user_provided_constructor (tree);
|
||||
extern bool type_has_user_provided_default_constructor (tree);
|
||||
extern bool type_has_non_user_provided_default_constructor (tree);
|
||||
extern bool vbase_has_user_provided_move_assign (tree);
|
||||
extern tree default_init_uninitialized_part (tree);
|
||||
extern bool trivial_default_constructor_is_constexpr (tree);
|
||||
|
|
|
@ -11476,11 +11476,7 @@ grok_special_member_properties (tree decl)
|
|||
TYPE_HAS_CONST_COPY_CTOR (class_type) = 1;
|
||||
}
|
||||
else if (sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (decl)))
|
||||
{
|
||||
TYPE_HAS_DEFAULT_CONSTRUCTOR (class_type) = 1;
|
||||
if (user_provided_p (decl))
|
||||
TYPE_HAS_COMPLEX_DFLT (class_type) = 1;
|
||||
}
|
||||
TYPE_HAS_DEFAULT_CONSTRUCTOR (class_type) = 1;
|
||||
else if (move_fn_p (decl) && user_provided_p (decl))
|
||||
TYPE_HAS_COMPLEX_MOVE_CTOR (class_type) = 1;
|
||||
else if (is_list_ctor (decl))
|
||||
|
|
|
@ -343,13 +343,17 @@ build_value_init (tree type, tsubst_flags_t complain)
|
|||
if (CLASS_TYPE_P (type)
|
||||
&& type_build_ctor_call (type))
|
||||
{
|
||||
tree ctor = build_aggr_init_expr
|
||||
(type,
|
||||
tree ctor =
|
||||
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))
|
||||
complain);
|
||||
if (ctor == error_mark_node)
|
||||
return ctor;
|
||||
tree fn = NULL_TREE;
|
||||
if (TREE_CODE (ctor) == CALL_EXPR)
|
||||
fn = get_callee_fndecl (ctor);
|
||||
ctor = build_aggr_init_expr (type, ctor);
|
||||
if (fn && user_provided_p (fn))
|
||||
return ctor;
|
||||
else if (TYPE_HAS_COMPLEX_DFLT (type))
|
||||
{
|
||||
|
|
15
gcc/testsuite/g++.dg/ext/is_trivially_constructible2.C
Normal file
15
gcc/testsuite/g++.dg/ext/is_trivially_constructible2.C
Normal file
|
@ -0,0 +1,15 @@
|
|||
// { dg-do compile { target c++11 } }
|
||||
|
||||
struct X {
|
||||
X() = default;
|
||||
template<class... U> X(U...);
|
||||
};
|
||||
|
||||
struct Y {
|
||||
template<class... U> Y(U...);
|
||||
};
|
||||
|
||||
#define SA(X) static_assert((X),#X)
|
||||
|
||||
SA(__is_trivially_constructible(X));
|
||||
SA(!__is_trivially_constructible(Y));
|
Loading…
Add table
Reference in a new issue