Commit 3b49d762 by Gabriel Dos Reis Committed by Jason Merrill

class.c (check_bases): Propagate non-literality.

	* class.c (check_bases): Propagate non-literality.
	(check_field_decls): Likewise.
	(finalize_literal_type_property): New.
	(check_bases_and_members): Call it.
	* cp-tree.h (TYPE_HAS_CONSTEXPR_CTOR): New.
	(lang_type_class): Add has_constexpr_ctor field.
	(DECL_DECLARED_CONSTEXPR_P): Strip template.
	* decl.c (grok_special_member_properties): Set
	TYPE_HAS_CONSTEXPR_CTOR.

Co-Authored-By: Jason Merrill <jason@redhat.com>

From-SVN: r166012
parent 61f8d165
2010-10-27 Gabriel Dos Reis <gdr@cse.tamu.edu>
Jason Merrill <jason@redhat.com>
* class.c (check_bases): Propagate non-literality.
(check_field_decls): Likewise.
(finalize_literal_type_property): New.
(check_bases_and_members): Call it.
* cp-tree.h (TYPE_HAS_CONSTEXPR_CTOR): New.
(lang_type_class): Add has_constexpr_ctor field.
(DECL_DECLARED_CONSTEXPR_P): Strip template.
* decl.c (grok_special_member_properties): Set
TYPE_HAS_CONSTEXPR_CTOR.
2010-10-27 Jason Merrill <jason@redhat.com> 2010-10-27 Jason Merrill <jason@redhat.com>
* call.c (build_integral_nontype_arg_conv): New. * call.c (build_integral_nontype_arg_conv): New.
......
...@@ -1269,6 +1269,10 @@ check_bases (tree t, ...@@ -1269,6 +1269,10 @@ check_bases (tree t,
gcc_assert (COMPLETE_TYPE_P (basetype)); gcc_assert (COMPLETE_TYPE_P (basetype));
/* If any base class is non-literal, so is the derived class. */
if (!CLASSTYPE_LITERAL_P (basetype))
CLASSTYPE_LITERAL_P (t) = false;
/* Effective C++ rule 14. We only need to check TYPE_POLYMORPHIC_P /* Effective C++ rule 14. We only need to check TYPE_POLYMORPHIC_P
here because the case of virtual functions but non-virtual here because the case of virtual functions but non-virtual
dtor is handled in finish_struct_1. */ dtor is handled in finish_struct_1. */
...@@ -3051,6 +3055,11 @@ check_field_decls (tree t, tree *access_decls, ...@@ -3051,6 +3055,11 @@ check_field_decls (tree t, tree *access_decls,
if (TREE_PRIVATE (x) || TREE_PROTECTED (x)) if (TREE_PRIVATE (x) || TREE_PROTECTED (x))
CLASSTYPE_NON_AGGREGATE (t) = 1; CLASSTYPE_NON_AGGREGATE (t) = 1;
/* If at least one non-static data member is non-literal, the whole
class becomes non-literal. */
if (!literal_type_p (type))
CLASSTYPE_LITERAL_P (t) = false;
/* A standard-layout class is a class that: /* A standard-layout class is a class that:
... ...
has the same access control (Clause 11) for all non-static data members, has the same access control (Clause 11) for all non-static data members,
...@@ -4455,6 +4464,41 @@ type_requires_array_cookie (tree type) ...@@ -4455,6 +4464,41 @@ type_requires_array_cookie (tree type)
return has_two_argument_delete_p; return has_two_argument_delete_p;
} }
/* Finish computing the `literal type' property of class type T.
At this point, we have already processed base classes and
non-static data members. We need to check whether the copy
constructor is trivial, the destructor is trivial, and there
is a trivial default constructor or at least one constexpr
constructor other than the copy constructor. */
static void
finalize_literal_type_property (tree t)
{
if (cxx_dialect < cxx0x
|| TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
/* FIXME These constraints seem unnecessary; remove from standard.
|| !TYPE_HAS_TRIVIAL_COPY_CTOR (t)
|| TYPE_HAS_COMPLEX_MOVE_CTOR (t)*/ )
CLASSTYPE_LITERAL_P (t) = false;
else if (CLASSTYPE_LITERAL_P (t) && !TYPE_HAS_TRIVIAL_DFLT (t)
&& !TYPE_HAS_CONSTEXPR_CTOR (t))
CLASSTYPE_LITERAL_P (t) = false;
if (!CLASSTYPE_LITERAL_P (t) && !CLASSTYPE_TEMPLATE_INSTANTIATION (t))
{
tree fn;
for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
if (DECL_DECLARED_CONSTEXPR_P (fn)
&& DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
&& !DECL_CONSTRUCTOR_P (fn))
{
error ("enclosing class of %q+D is not a literal type", fn);
DECL_DECLARED_CONSTEXPR_P (fn) = false;
}
}
}
/* Check the validity of the bases and members declared in T. Add any /* Check the validity of the bases and members declared in T. Add any
implicitly-generated functions (like copy-constructors and implicitly-generated functions (like copy-constructors and
assignment operators). Compute various flag bits (like assignment operators). Compute various flag bits (like
...@@ -4611,6 +4655,10 @@ check_bases_and_members (tree t) ...@@ -4611,6 +4655,10 @@ check_bases_and_members (tree t)
CLASSTYPE_NON_AGGREGATE (t) = 1; CLASSTYPE_NON_AGGREGATE (t) = 1;
} }
/* Compute the 'literal type' property before we
do anything with non-static member functions. */
finalize_literal_type_property (t);
/* Create the in-charge and not-in-charge variants of constructors /* Create the in-charge and not-in-charge variants of constructors
and destructors. */ and destructors. */
clone_constructors_and_destructors (t); clone_constructors_and_destructors (t);
...@@ -5445,6 +5493,7 @@ finish_struct_1 (tree t) ...@@ -5445,6 +5493,7 @@ finish_struct_1 (tree t)
CLASSTYPE_EMPTY_P (t) = 1; CLASSTYPE_EMPTY_P (t) = 1;
CLASSTYPE_NEARLY_EMPTY_P (t) = 1; CLASSTYPE_NEARLY_EMPTY_P (t) = 1;
CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 0; CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 0;
CLASSTYPE_LITERAL_P (t) = true;
/* Do end-of-class semantic processing: checking the validity of the /* Do end-of-class semantic processing: checking the validity of the
bases and members and add implicitly generated methods. */ bases and members and add implicitly generated methods. */
......
...@@ -1324,6 +1324,7 @@ struct GTY(()) lang_type_class { ...@@ -1324,6 +1324,7 @@ struct GTY(()) lang_type_class {
unsigned lazy_move_assign : 1; unsigned lazy_move_assign : 1;
unsigned has_complex_move_ctor : 1; unsigned has_complex_move_ctor : 1;
unsigned has_complex_move_assign : 1; unsigned has_complex_move_assign : 1;
unsigned has_constexpr_ctor : 1;
/* When adding a flag here, consider whether or not it ought to /* When adding a flag here, consider whether or not it ought to
apply to a template instance if it applies to the template. If apply to a template instance if it applies to the template. If
...@@ -1332,7 +1333,7 @@ struct GTY(()) lang_type_class { ...@@ -1332,7 +1333,7 @@ struct GTY(()) lang_type_class {
/* There are some bits left to fill out a 32-bit word. Keep track /* There are some bits left to fill out a 32-bit word. Keep track
of this by updating the size of this bitfield whenever you add or of this by updating the size of this bitfield whenever you add or
remove a flag. */ remove a flag. */
unsigned dummy : 4; unsigned dummy : 3;
tree primary_base; tree primary_base;
VEC(tree_pair_s,gc) *vcall_indices; VEC(tree_pair_s,gc) *vcall_indices;
...@@ -1457,6 +1458,12 @@ struct GTY((variable_size)) lang_type { ...@@ -1457,6 +1458,12 @@ struct GTY((variable_size)) lang_type {
#define TYPE_HAS_LIST_CTOR(NODE) \ #define TYPE_HAS_LIST_CTOR(NODE) \
(LANG_TYPE_CLASS_CHECK (NODE)->has_list_ctor) (LANG_TYPE_CLASS_CHECK (NODE)->has_list_ctor)
/* Nonzero if this class has a constexpr constructor other than a copy/move
constructor. Note that a class can have constexpr constructors for
static initialization even if it isn't a literal class. */
#define TYPE_HAS_CONSTEXPR_CTOR(NODE) \
(LANG_TYPE_CLASS_CHECK (NODE)->has_constexpr_ctor)
/* Nonzero if this class defines an overloaded operator new. (An /* Nonzero if this class defines an overloaded operator new. (An
operator new [] doesn't count.) */ operator new [] doesn't count.) */
#define TYPE_HAS_NEW_OPERATOR(NODE) \ #define TYPE_HAS_NEW_OPERATOR(NODE) \
...@@ -2334,7 +2341,7 @@ struct GTY((variable_size)) lang_decl { ...@@ -2334,7 +2341,7 @@ struct GTY((variable_size)) lang_decl {
/* True if DECL is declared 'constexpr'. */ /* True if DECL is declared 'constexpr'. */
#define DECL_DECLARED_CONSTEXPR_P(DECL) \ #define DECL_DECLARED_CONSTEXPR_P(DECL) \
DECL_LANG_FLAG_8 (VAR_OR_FUNCTION_DECL_CHECK (DECL)) DECL_LANG_FLAG_8 (VAR_OR_FUNCTION_DECL_CHECK (STRIP_TEMPLATE (DECL)))
/* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a /* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a
template function. */ template function. */
......
...@@ -10292,6 +10292,10 @@ grok_special_member_properties (tree decl) ...@@ -10292,6 +10292,10 @@ grok_special_member_properties (tree decl)
TYPE_HAS_COMPLEX_MOVE_CTOR (class_type) = 1; TYPE_HAS_COMPLEX_MOVE_CTOR (class_type) = 1;
else if (is_list_ctor (decl)) else if (is_list_ctor (decl))
TYPE_HAS_LIST_CTOR (class_type) = 1; TYPE_HAS_LIST_CTOR (class_type) = 1;
if (DECL_DECLARED_CONSTEXPR_P (decl)
&& !copy_fn_p (decl) && !move_fn_p (decl))
TYPE_HAS_CONSTEXPR_CTOR (class_type) = 1;
} }
else if (DECL_OVERLOADED_OPERATOR_P (decl) == NOP_EXPR) else if (DECL_OVERLOADED_OPERATOR_P (decl) == NOP_EXPR)
{ {
......
...@@ -5245,6 +5245,7 @@ float_const_decimal64_p (void) ...@@ -5245,6 +5245,7 @@ float_const_decimal64_p (void)
return 0; return 0;
} }
/* Return true if T is a literal type. */ /* Return true if T is a literal type. */
bool bool
...@@ -5259,7 +5260,6 @@ literal_type_p (tree t) ...@@ -5259,7 +5260,6 @@ literal_type_p (tree t)
return false; return false;
} }
/* If DECL is a variable declared `constexpr', require its type /* If DECL is a variable declared `constexpr', require its type
be literal. Return the DECL if OK, otherwise NULL. */ be literal. Return the DECL if OK, otherwise NULL. */
......
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