aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/class.c6
-rw-r--r--gcc/cp/init.c5
-rw-r--r--gcc/testsuite/ChangeLog2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/regress/abi-empty7.C20
5 files changed, 34 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f247933..26de2b6e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2011-02-09 Jason Merrill <jason@redhat.com>
+ * class.c (type_has_constexpr_default_constructor): Make sure the
+ caller stripped an enclosing array.
+ * init.c (perform_member_init): Strip arrays before calling it.
+
PR c++/47511
* semantics.c (potential_constant_expression_1): Handle TEMPLATE_DECL.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 03951cf..66c85bd 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -4349,7 +4349,11 @@ type_has_constexpr_default_constructor (tree t)
tree fns;
if (!CLASS_TYPE_P (t))
- return false;
+ {
+ /* The caller should have stripped an enclosing array. */
+ gcc_assert (TREE_CODE (t) != ARRAY_TYPE);
+ return false;
+ }
if (CLASSTYPE_LAZY_DEFAULT_CTOR (t))
return synthesized_default_constructor_is_constexpr (t);
fns = locate_ctor (t);
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 6ffdc2f..e590118 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -535,8 +535,10 @@ perform_member_init (tree member, tree init)
"uninitialized member %qD with %<const%> type %qT",
member, type);
+ core_type = strip_array_types (type);
+
if (DECL_DECLARED_CONSTEXPR_P (current_function_decl)
- && !type_has_constexpr_default_constructor (type))
+ && !type_has_constexpr_default_constructor (core_type))
{
if (!DECL_TEMPLATE_INSTANTIATION (current_function_decl))
error ("uninitialized member %qD in %<constexpr%> constructor",
@@ -544,7 +546,6 @@ perform_member_init (tree member, tree init)
DECL_DECLARED_CONSTEXPR_P (current_function_decl) = false;
}
- core_type = strip_array_types (type);
if (CLASS_TYPE_P (core_type)
&& (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type)
|| CLASSTYPE_REF_FIELDS_NEED_INIT (core_type)))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c37a273..8d7e387 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,7 @@
2011-02-09 Jason Merrill <jason@redhat.com>
+ * g++.dg/cpp0x/regress/abi-empty7.C: New.
+
* g++.dg/cpp0x/regress: New directory.
* g++.dg/cpp0x/constexpr-regress1.C: Move to regress/regress1.C.
* g++.dg/cpp0x/constexpr-regress2.C: Move to regress/regress2.C.
diff --git a/gcc/testsuite/g++.dg/cpp0x/regress/abi-empty7.C b/gcc/testsuite/g++.dg/cpp0x/regress/abi-empty7.C
new file mode 100644
index 0000000..adc7127
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/regress/abi-empty7.C
@@ -0,0 +1,20 @@
+// Copy of abi/empty7.C.
+// { dg-do run { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target ilp32 }
+// { dg-options "-fabi-version=0 -std=c++0x" }
+
+struct S1 {};
+struct S2 { virtual void f () {} S1 s1[4]; };
+struct S3 : virtual public S2 {};
+struct S4 : virtual public S2 { int i; };
+struct S5 : public S3, virtual public S4 {};
+struct S6 { S5 s5; };
+struct S7 { S1 s1[5]; };
+struct S8 : public S1, public S6, virtual public S7 { };
+
+S8 s8;
+
+int main () {
+ if ((char *)(S7 *)&s8 - (char *)&s8 != 24)
+ return 1;
+}