[prev in list] [next in list] [prev in thread] [next in thread] 

List:       gcc-patches
Subject:    [C++11 Patch] NSMI and aggregate type
From:       Olivier Goffart <olivier () woboq ! com>
Date:       2011-11-02 17:49:22
Message-ID: 1758027.KC7uDKxpWg () l09
[Download RAW message or body]

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
["0001-Fix-NSMI-with-brace-initializer.patch" (0001-Fix-NSMI-with-brace-initializer.patch)]

From c799ec19b7f9c68f4721c4c5979c4707dad1bc61 Mon Sep 17 00:00:00 2001
From: Olivier Goffart <ogoffart@kde.org>
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<int,3> c1;
   if (c1.m != 3) return 5;
-  C<int,3> c2 { 5 };
+  C<int,5> c2 {};
   if (c2.m != 5) return 6;
 
   D<int,3> d1;
-- 
1.7.7.1



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic