Re: [C++11 Patch] NSMI and aggregate type

2011-11-04 Thread Jason Merrill
We don't want to check DECL_INITIAL up there, as it might still be a 
bit-field size.  So I moved the check down a bit and checked it in.  Thanks!


Jason
commit 5b18fa4cd800c94783b70c1cef1b711b424afe0d
Author: jason 
Date:   Fri Nov 4 17:15:02 2011 +

	PR c++/50965
	* class.c (check_field_decls): NSDMI makes a class non-aggregate.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180965 138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 41d182a..1775868 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -3189,6 +3189,12 @@ check_field_decls (tree t, tree *access_decls,
 			  no_const_asn_ref_p,
 			  &any_default_members);
 
+  /* Now that we've removed bit-field widths from DECL_INITIAL,
+	 anything left in DECL_INITIAL is an NSDMI that makes the class
+	 non-aggregate.  */
+  if (DECL_INITIAL (x))
+	CLASSTYPE_NON_AGGREGATE (t) = true;
+
   /* If any field is const, the structure type is pseudo-const.  */
   if (CP_TYPE_CONST_P (type))
 	{
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index dc52d29..c941abc 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3205,8 +3205,9 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 
 /* [dcl.init.aggr]
 
-   An aggregate is an array or a class with no user-declared
-   constructors, no private or protected non-static data members, no
+   An aggregate is an array or a class with no user-provided
+   constructors, no brace-or-equal-initializers for non-static data
+   members, no private or protected non-static data members, no
base classes, and no virtual functions.
 
As an extension, we also treat vectors as aggregates.  Keep these
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi1.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi1.C
index f6381d0..159c16d 100644
--- a/gcc/testsuite/g++.dg/cpp0x/nsdmi1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi1.C
@@ -31,8 +31,8 @@ int main()
 {
   A a1;
   if (a1.i != 42) return 1;
-  A a2 = { 24 };
-  if (a2.i != 24) return 2;
+  A a2{};
+  if (a2.i != 42) return 2;
   A a3[1];
   if (a3[0].i != 42) return 3;
 
@@ -43,7 +43,7 @@ int main()
 
   C c1;
   if (c1.m != 3) return 5;
-  C c2 { 5 };
+  C c2 {};
   if (c2.m != 5) return 6;
 
   D d1;


[C++11 Patch] NSMI and aggregate type

2011-11-02 Thread Olivier Goffart
Hi,

I tried GCC trunk to test the non static member initializer, and noticed a 
bug:  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50965

I noticed that the reason is that Some code path test if the test is an 
aggregate type before running the constructors.
But in C++11 the definition of aggregate type has changed to exclude the types 
with NSMI.

Hence the patch.

It means that code like that in the test
A a2 = { 24 };
Are not allowed.

Please CC me
-- 
Olivier>From c799ec19b7f9c68f4721c4c5979c4707dad1bc61 Mon Sep 17 00:00:00 2001
From: Olivier Goffart 
Date: Wed, 2 Nov 2011 17:42:48 +0100
Subject: [PATCH] Fix NSMI with brace initializer

Code like this:

struct A {
  int i = 42;
};

int main() {
  A a{};
  std::cout << a.i << std::endl;
}

would show 0

After investigating, I noticed that this is due to the change of meaning
of aggregate type.

Which means that you cannot initialize A with {10} anymore.
I don't know if it is intended by the standard, but it is the case.
---
 gcc/cp/class.c  |2 +-
 gcc/cp/cp-tree.h|5 +++--
 gcc/testsuite/g++.dg/cpp0x/nsdmi1.C |6 +++---
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 41d182a..72ea9b6 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -3083,7 +3083,7 @@ check_field_decls (tree t, tree *access_decls,
 
   /* Now it can only be a FIELD_DECL.  */
 
-  if (TREE_PRIVATE (x) || TREE_PROTECTED (x))
+  if (TREE_PRIVATE (x) || TREE_PROTECTED (x) || DECL_INITIAL (x))
 	CLASSTYPE_NON_AGGREGATE (t) = 1;
 
   /* If at least one non-static data member is non-literal, the whole
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index ac42e0e..effe18c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3205,8 +3205,9 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 
 /* [dcl.init.aggr]
 
-   An aggregate is an array or a class with no user-declared
-   constructors, no private or protected non-static data members, no
+   An aggregate is an array or a class with no user-provided
+   constructors, no brace-or-equal-initializers for non-static data
+   members, no private or protected non-static data members, no
base classes, and no virtual functions.
 
As an extension, we also treat vectors as aggregates.  Keep these
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi1.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi1.C
index f6381d0..159c16d 100644
--- a/gcc/testsuite/g++.dg/cpp0x/nsdmi1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi1.C
@@ -31,8 +31,8 @@ int main()
 {
   A a1;
   if (a1.i != 42) return 1;
-  A a2 = { 24 };
-  if (a2.i != 24) return 2;
+  A a2{};
+  if (a2.i != 42) return 2;
   A a3[1];
   if (a3[0].i != 42) return 3;
 
@@ -43,7 +43,7 @@ int main()
 
   C c1;
   if (c1.m != 3) return 5;
-  C c2 { 5 };
+  C c2 {};
   if (c2.m != 5) return 6;
 
   D d1;
-- 
1.7.7.1