aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorGabriel Dos Reis <gdr@cs.tamu.edu>2010-10-27 15:04:06 -0400
committerJason Merrill <jason@gcc.gnu.org>2010-10-27 15:04:06 -0400
commit3b49d762b5d6845f6c09926a0a6b2d5e0471a755 (patch)
tree20c0a5070bcb65304f258d5cd324f9c98af07721 /gcc/cp
parent61f8d16512a62120c29e1cc82cddbc4d3816a1c4 (diff)
downloadgcc-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/ChangeLog13
-rw-r--r--gcc/cp/class.c49
-rw-r--r--gcc/cp/cp-tree.h11
-rw-r--r--gcc/cp/decl.c4
-rw-r--r--gcc/cp/semantics.c2
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. */