aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2010-10-31 22:04:48 -0400
committerJason Merrill <jason@gcc.gnu.org>2010-10-31 22:04:48 -0400
commit0930cc0ece835ab77a30d8b5894a8910f55d4054 (patch)
treef8e8b942d2e97fd64107a2ee74fb2dc1596e8511 /gcc/cp
parentec52b1115dda4b0e38aa5620b0c3914b69008a24 (diff)
downloadgcc-0930cc0ece835ab77a30d8b5894a8910f55d4054.zip
gcc-0930cc0ece835ab77a30d8b5894a8910f55d4054.tar.gz
gcc-0930cc0ece835ab77a30d8b5894a8910f55d4054.tar.bz2
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
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/class.c41
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/method.c6
4 files changed, 37 insertions, 18 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2b475d0..6462e11 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,12 @@
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.
* typeck.c (convert_for_assignment): Likewise.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 50afc48..1c9fac1 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -2671,20 +2671,10 @@ add_implicitly_declared_members (tree t,
if (! TYPE_HAS_USER_CONSTRUCTOR (t))
{
TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1;
- if (TYPE_HAS_TRIVIAL_DFLT (t))
- {
- /* A trivial default constructor is constexpr
- if there is nothing to initialize. */
- 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;
+ CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1;
+ if (cxx_dialect >= cxx0x)
+ TYPE_HAS_CONSTEXPR_CTOR (t)
+ = synthesized_default_constructor_is_constexpr (t);
}
/* [class.ctor]
@@ -4337,6 +4327,18 @@ type_has_user_provided_default_constructor (tree t)
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. */
bool
@@ -4346,6 +4348,8 @@ type_has_constexpr_default_constructor (tree t)
if (!CLASS_TYPE_P (t))
return false;
+ if (CLASSTYPE_LAZY_DEFAULT_CTOR (t))
+ return synthesized_default_constructor_is_constexpr (t);
fns = get_default_ctor (t);
return (fns && DECL_DECLARED_CONSTEXPR_P (fns));
}
@@ -6824,13 +6828,11 @@ contains_empty_class_p (tree type)
}
/* 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
is_really_empty_class (tree type)
{
- if (is_empty_class (type))
- return true;
if (CLASS_TYPE_P (type))
{
tree field;
@@ -6838,6 +6840,11 @@ is_really_empty_class (tree type)
tree base_binfo;
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;
BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
if (!is_really_empty_class (BINFO_TYPE (base_binfo)))
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 7595b6f..e5ea232 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4722,6 +4722,7 @@ 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 synthesized_default_constructor_is_constexpr (tree);
extern bool type_has_constexpr_default_constructor (tree);
extern bool type_has_virtual_destructor (tree);
extern bool type_has_move_constructor (tree);
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 6687c75..ca5964e 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1157,7 +1157,11 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
methods in C++0x. */
if (expected_trivial
&& (!copy_arg_p || cxx_dialect < cxx0x))
- return;
+ {
+ if (constexpr_p && sfk == sfk_constructor)
+ *constexpr_p = synthesized_default_constructor_is_constexpr (ctype);
+ return;
+ }
#endif
++cp_unevaluated_operand;