Commit 0930cc0e by Jason Merrill Committed by Jason Merrill

class.c (is_really_empty_class): Work when type is not complete.

	* class.c (is_really_empty_class): Work when type is not complete.
	(synthesized_default_constructor_is_constexpr): New.
	(add_implicitly_declared_members): Use it.
	(type_has_constexpr_default_constructor): Likewise.
	* cp-tree.h: Declare it.
	* method.c (synthesized_method_walk): Use it.

From-SVN: r166124
parent ec52b111
2010-10-31 Jason Merrill <jason@redhat.com> 2010-10-31 Jason Merrill <jason@redhat.com>
* class.c (is_really_empty_class): Work when type is not complete.
(synthesized_default_constructor_is_constexpr): New.
(add_implicitly_declared_members): Use it.
(type_has_constexpr_default_constructor): Likewise.
* cp-tree.h: Declare it.
* method.c (synthesized_method_walk): Use it.
* decl.c (pop_switch): Use EXPR_LOC_OR_HERE. * decl.c (pop_switch): Use EXPR_LOC_OR_HERE.
* typeck.c (convert_for_assignment): Likewise. * typeck.c (convert_for_assignment): Likewise.
......
...@@ -2671,20 +2671,10 @@ add_implicitly_declared_members (tree t, ...@@ -2671,20 +2671,10 @@ add_implicitly_declared_members (tree t,
if (! TYPE_HAS_USER_CONSTRUCTOR (t)) if (! TYPE_HAS_USER_CONSTRUCTOR (t))
{ {
TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1; TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1;
if (TYPE_HAS_TRIVIAL_DFLT (t)) CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1;
{ if (cxx_dialect >= cxx0x)
/* A trivial default constructor is constexpr TYPE_HAS_CONSTEXPR_CTOR (t)
if there is nothing to initialize. */ = synthesized_default_constructor_is_constexpr (t);
if (cxx_dialect >= cxx0x && is_really_empty_class (t))
TYPE_HAS_CONSTEXPR_CTOR (t) = 1;
CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1;
}
else if (cxx_dialect >= cxx0x)
/* We need to go ahead and declare this to set
TYPE_HAS_CONSTEXPR_CTOR. */
lazily_declare_fn (sfk_constructor, t);
else
CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1;
} }
/* [class.ctor] /* [class.ctor]
...@@ -4337,6 +4327,18 @@ type_has_user_provided_default_constructor (tree t) ...@@ -4337,6 +4327,18 @@ type_has_user_provided_default_constructor (tree t)
return false; return false;
} }
/* Returns true iff for class T, a synthesized default constructor
would be constexpr. */
bool
synthesized_default_constructor_is_constexpr (tree t)
{
/* A defaulted default constructor is constexpr
if there is nothing to initialize. */
/* FIXME adjust for non-static data member initializers. */
return is_really_empty_class (t);
}
/* Returns true iff class T has a constexpr default constructor. */ /* Returns true iff class T has a constexpr default constructor. */
bool bool
...@@ -4346,6 +4348,8 @@ type_has_constexpr_default_constructor (tree t) ...@@ -4346,6 +4348,8 @@ type_has_constexpr_default_constructor (tree t)
if (!CLASS_TYPE_P (t)) if (!CLASS_TYPE_P (t))
return false; return false;
if (CLASSTYPE_LAZY_DEFAULT_CTOR (t))
return synthesized_default_constructor_is_constexpr (t);
fns = get_default_ctor (t); fns = get_default_ctor (t);
return (fns && DECL_DECLARED_CONSTEXPR_P (fns)); return (fns && DECL_DECLARED_CONSTEXPR_P (fns));
} }
...@@ -6824,13 +6828,11 @@ contains_empty_class_p (tree type) ...@@ -6824,13 +6828,11 @@ contains_empty_class_p (tree type)
} }
/* Returns true if TYPE contains no actual data, just various /* Returns true if TYPE contains no actual data, just various
possible combinations of empty classes. */ possible combinations of empty classes and possibly a vptr. */
bool bool
is_really_empty_class (tree type) is_really_empty_class (tree type)
{ {
if (is_empty_class (type))
return true;
if (CLASS_TYPE_P (type)) if (CLASS_TYPE_P (type))
{ {
tree field; tree field;
...@@ -6838,6 +6840,11 @@ is_really_empty_class (tree type) ...@@ -6838,6 +6840,11 @@ is_really_empty_class (tree type)
tree base_binfo; tree base_binfo;
int i; int i;
/* CLASSTYPE_EMPTY_P isn't set properly until the class is actually laid
out, but we'd like to be able to check this before then. */
if (COMPLETE_TYPE_P (type) && is_empty_class (type))
return true;
for (binfo = TYPE_BINFO (type), i = 0; for (binfo = TYPE_BINFO (type), i = 0;
BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i) BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
if (!is_really_empty_class (BINFO_TYPE (base_binfo))) if (!is_really_empty_class (BINFO_TYPE (base_binfo)))
......
...@@ -4722,6 +4722,7 @@ extern tree in_class_defaulted_default_constructor (tree); ...@@ -4722,6 +4722,7 @@ extern tree in_class_defaulted_default_constructor (tree);
extern bool user_provided_p (tree); extern bool user_provided_p (tree);
extern bool type_has_user_provided_constructor (tree); extern bool type_has_user_provided_constructor (tree);
extern bool type_has_user_provided_default_constructor (tree); extern bool type_has_user_provided_default_constructor (tree);
extern bool synthesized_default_constructor_is_constexpr (tree);
extern bool type_has_constexpr_default_constructor (tree); extern bool type_has_constexpr_default_constructor (tree);
extern bool type_has_virtual_destructor (tree); extern bool type_has_virtual_destructor (tree);
extern bool type_has_move_constructor (tree); extern bool type_has_move_constructor (tree);
......
...@@ -1157,7 +1157,11 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, ...@@ -1157,7 +1157,11 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
methods in C++0x. */ methods in C++0x. */
if (expected_trivial if (expected_trivial
&& (!copy_arg_p || cxx_dialect < cxx0x)) && (!copy_arg_p || cxx_dialect < cxx0x))
return; {
if (constexpr_p && sfk == sfk_constructor)
*constexpr_p = synthesized_default_constructor_is_constexpr (ctype);
return;
}
#endif #endif
++cp_unevaluated_operand; ++cp_unevaluated_operand;
......
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