diff options
author | Gabriel Dos Reis <gdr@cs.tamu.edu> | 2010-10-27 15:04:06 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2010-10-27 15:04:06 -0400 |
commit | 3b49d762b5d6845f6c09926a0a6b2d5e0471a755 (patch) | |
tree | 20c0a5070bcb65304f258d5cd324f9c98af07721 /gcc/cp | |
parent | 61f8d16512a62120c29e1cc82cddbc4d3816a1c4 (diff) | |
download | gcc-3b49d762b5d6845f6c09926a0a6b2d5e0471a755.zip gcc-3b49d762b5d6845f6c09926a0a6b2d5e0471a755.tar.gz gcc-3b49d762b5d6845f6c09926a0a6b2d5e0471a755.tar.bz2 |
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
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/cp/class.c | 49 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 11 | ||||
-rw-r--r-- | gcc/cp/decl.c | 4 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 2 |
5 files changed, 76 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c752736..95a2f8b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +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> * call.c (build_integral_nontype_arg_conv): New. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index f76c2be..00af0ae 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1269,6 +1269,10 @@ check_bases (tree t, 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 here because the case of virtual functions but non-virtual dtor is handled in finish_struct_1. */ @@ -3051,6 +3055,11 @@ check_field_decls (tree t, tree *access_decls, if (TREE_PRIVATE (x) || TREE_PROTECTED (x)) 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: ... has the same access control (Clause 11) for all non-static data members, @@ -4455,6 +4464,41 @@ type_requires_array_cookie (tree type) 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 implicitly-generated functions (like copy-constructors and assignment operators). Compute various flag bits (like @@ -4611,6 +4655,10 @@ check_bases_and_members (tree t) 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 and destructors. */ clone_constructors_and_destructors (t); @@ -5445,6 +5493,7 @@ finish_struct_1 (tree t) CLASSTYPE_EMPTY_P (t) = 1; CLASSTYPE_NEARLY_EMPTY_P (t) = 1; CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 0; + CLASSTYPE_LITERAL_P (t) = true; /* Do end-of-class semantic processing: checking the validity of the bases and members and add implicitly generated methods. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ec026a4..8c0c9b1 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1324,6 +1324,7 @@ struct GTY(()) lang_type_class { unsigned lazy_move_assign : 1; unsigned has_complex_move_ctor : 1; unsigned has_complex_move_assign : 1; + unsigned has_constexpr_ctor : 1; /* When adding a flag here, consider whether or not it ought to apply to a template instance if it applies to the template. If @@ -1332,7 +1333,7 @@ struct GTY(()) lang_type_class { /* 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 remove a flag. */ - unsigned dummy : 4; + unsigned dummy : 3; tree primary_base; VEC(tree_pair_s,gc) *vcall_indices; @@ -1457,6 +1458,12 @@ struct GTY((variable_size)) lang_type { #define TYPE_HAS_LIST_CTOR(NODE) \ (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 operator new [] doesn't count.) */ #define TYPE_HAS_NEW_OPERATOR(NODE) \ @@ -2334,7 +2341,7 @@ struct GTY((variable_size)) lang_decl { /* True if DECL is declared 'constexpr'. */ #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 template function. */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e513bc0..e27a64d 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -10292,6 +10292,10 @@ grok_special_member_properties (tree decl) TYPE_HAS_COMPLEX_MOVE_CTOR (class_type) = 1; else if (is_list_ctor (decl)) 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) { diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 0012bdd..4e73068 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5245,6 +5245,7 @@ float_const_decimal64_p (void) return 0; } + /* Return true if T is a literal type. */ bool @@ -5259,7 +5260,6 @@ literal_type_p (tree t) return false; } - /* If DECL is a variable declared `constexpr', require its type be literal. Return the DECL if OK, otherwise NULL. */ |