Re: [PATCH] PR c++/51633 - ICEs with constexpr constructor

2012-01-12 Thread Jason Merrill

On 01/11/2012 05:57 PM, Dodji Seketeli wrote:

+  list = cur_stmt_list;
if (TREE_CODE (list) == BIND_EXPR)
list = BIND_EXPR_BODY (list);
if (TREE_CODE (list) == STATEMENT_LIST


cur_stmt_list should always be a STATEMENT_LIST, so these tests are 
unnecessary.


Jason



Re: [PATCH] PR c++/51633 - ICEs with constexpr constructor

2012-01-12 Thread Dodji Seketeli
Jason Merrill ja...@redhat.com writes:

 On 01/11/2012 05:57 PM, Dodji Seketeli wrote:
 +  list = cur_stmt_list;
 if (TREE_CODE (list) == BIND_EXPR)
  list = BIND_EXPR_BODY (list);
 if (TREE_CODE (list) == STATEMENT_LIST

 cur_stmt_list should always be a STATEMENT_LIST, so these tests are
 unnecessary.

This is the udpated patch that I have tested and am about to bootstrap.

gcc/cp/

* semantics.c (cp_parser_ctor_initializer_opt_and_function_body):
Set the pointer to the last block of the constructor to the
current statement.
(build_constexpr_constructor_member_initializers): Get
build_data_member_initialization a chance to deal with more
statements before we choke.

gcc/testsuite/

* g++.dg/cpp0x/constexpr-diag4.C: New test.
---
 gcc/cp/parser.c  |7 +---
 gcc/cp/semantics.c   |2 +
 gcc/testsuite/g++.dg/cpp0x/constexpr-diag4.C |   25 +
 gcc/testsuite/g++.dg/cpp0x/constexpr-diag5.C |   48 ++
 4 files changed, 77 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-diag4.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-diag5.C

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 0ae55a2..0bff244 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -17418,11 +17418,8 @@ cp_parser_ctor_initializer_opt_and_function_body 
(cp_parser *parser)
  cp_parser_function_body changed its state.  */
   if (check_body_p)
 {
-  list = body;
-  if (TREE_CODE (list) == BIND_EXPR)
-   list = BIND_EXPR_BODY (list);
-  if (TREE_CODE (list) == STATEMENT_LIST
-  STATEMENT_LIST_TAIL (list) != NULL)
+  list = cur_stmt_list;
+  if (STATEMENT_LIST_TAIL (list))
last = STATEMENT_LIST_TAIL (list)-stmt;
 }
   /* Parse the function-body.  */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index fbb74e1..9369179 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -5930,6 +5930,8 @@ build_constexpr_constructor_member_initializers (tree 
type, tree body)
break;
}
 }
+  else if (EXPR_P (body))
+ok = build_data_member_initialization (body, vec);
   else
 gcc_assert (errorcount  0);
   if (ok)
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-diag4.C 
b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag4.C
new file mode 100644
index 000..371190e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag4.C
@@ -0,0 +1,25 @@
+// Origin: PR c++/51633
+// { dg-options -std=c++11 }
+
+struct A
+{
+~A();
+};
+
+struct B
+{
+A a;
+constexpr B() {}
+};
+
+struct A1
+{
+int a;
+~A1();
+};
+
+struct B1
+{
+A1 a1;
+constexpr B1() {} // { dg-error uninitialized member }
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-diag5.C 
b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag5.C
new file mode 100644
index 000..c0cbfdd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag5.C
@@ -0,0 +1,48 @@
+// Origin: PR c++/51633
+// { dg-options -std=c++11 }
+
+struct A
+{
+constexpr A() {}
+~A();
+};
+
+struct B
+{
+A a;
+A b;
+A c;
+constexpr B() {}
+};
+
+struct C
+{
+A a;
+constexpr C() {}
+};
+
+struct D
+{
+constexpr D() { return;} // { dg-error does not have empty body }
+};
+
+struct D1
+{
+A a;
+constexpr D1() { return;} // { dg-error does not have empty body }
+};
+
+struct D2
+{
+A a;
+A b;
+constexpr D2() { return;} // { dg-error does not have empty body }
+};
+
+struct D3
+{
+A a;
+A b;
+A c;
+constexpr D3() { return;} // { dg-error does not have empty body }
+};
-- 
1.7.6.4


-- 
Dodji


Re: [PATCH] PR c++/51633 - ICEs with constexpr constructor

2012-01-12 Thread Jason Merrill

On 01/12/2012 09:21 AM, Dodji Seketeli wrote:

This is the udpated patch that I have tested and am about to bootstrap.


OK.

Jason



[PATCH] PR c++/51633 - ICEs with constexpr constructor

2012-01-11 Thread Dodji Seketeli
Hello,

Consider this short code snippet:

struct A
{
~A();
};

struct B
{
A a;
constexpr B() {}
};

As explained in the audit trail, this is valid code.

G++ ICEs on it because build_constexpr_constructor_member_initializers
chokes on a CLEANUP_STMT.

The CLEANUP_STMT is put into the constructor of B to ensure that the
destructor for 'a' is called.

As this CLEANUP_STMT is not related to the representation of
mem-initializer-list that
build_constexpr_constructor_member_initializers was expecting to see
as part of its analysis of the constructor body my understanding is
that it should just ignore it.

I noted that build_data_member_initialization that is called elsewhere
in build_constexpr_constructor_member_initializers already knows how
to ignore those CLEANUP_STMT, so I tried in this patch to take
advantage of that function.

The other case of ICE reported in this issue is in:

struct A2
{
constexpr A2() {}
~A2();
};

struct B2
{
  A2 a;
constexpr B2() { return;}
};

where check_constexpr_ctor_body fails to recognize that the body of
the constexpr constructor B2 is not empty.  It turned out this is
because it's not passed the proper last statement of the constructor,
before the body (as written in the source code) is parsed.  Fixed
thus.

Bootstrapped and tested on x86_64-unknown-linux-gnu against trunk.

gcc/cp/

* semantics.c (cp_parser_ctor_initializer_opt_and_function_body):
Set the pointer to the last block of the constructor to the
current statement.
(build_constexpr_constructor_member_initializers): Get
build_data_member_initialization a chance to deal with more
statements before we choke.

gcc/testsuite/

* g++.dg/cpp0x/constexpr-diag4.C: New test.
---
 gcc/cp/parser.c  |2 +-
 gcc/cp/semantics.c   |2 +
 gcc/testsuite/g++.dg/cpp0x/constexpr-diag4.C |   28 +++
 gcc/testsuite/g++.dg/cpp0x/constexpr-diag5.C |   48 ++
 4 files changed, 79 insertions(+), 1 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-diag4.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-diag5.C

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 0ae55a2..ea9ccfc 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -17418,7 +17418,7 @@ cp_parser_ctor_initializer_opt_and_function_body 
(cp_parser *parser)
  cp_parser_function_body changed its state.  */
   if (check_body_p)
 {
-  list = body;
+  list = cur_stmt_list;
   if (TREE_CODE (list) == BIND_EXPR)
list = BIND_EXPR_BODY (list);
   if (TREE_CODE (list) == STATEMENT_LIST
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index fbb74e1..9369179 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -5930,6 +5930,8 @@ build_constexpr_constructor_member_initializers (tree 
type, tree body)
break;
}
 }
+  else if (EXPR_P (body))
+ok = build_data_member_initialization (body, vec);
   else
 gcc_assert (errorcount  0);
   if (ok)
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-diag4.C 
b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag4.C
new file mode 100644
index 000..08373c1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag4.C
@@ -0,0 +1,28 @@
+// Origin: PR c++/51633
+// { dg-options -std=c++11 }
+
+struct A
+{
+~A();
+};
+
+struct B
+{
+A a;
+constexpr B() {}
+};
+
+struct A1
+{
+int a;
+~A1();
+};
+
+struct B1
+{
+A1 a1;
+constexpr B1() {} // { dg-error uninitialized member }
+};
+
+
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-diag5.C 
b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag5.C
new file mode 100644
index 000..c0cbfdd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag5.C
@@ -0,0 +1,48 @@
+// Origin: PR c++/51633
+// { dg-options -std=c++11 }
+
+struct A
+{
+constexpr A() {}
+~A();
+};
+
+struct B
+{
+A a;
+A b;
+A c;
+constexpr B() {}
+};
+
+struct C
+{
+A a;
+constexpr C() {}
+};
+
+struct D
+{
+constexpr D() { return;} // { dg-error does not have empty body }
+};
+
+struct D1
+{
+A a;
+constexpr D1() { return;} // { dg-error does not have empty body }
+};
+
+struct D2
+{
+A a;
+A b;
+constexpr D2() { return;} // { dg-error does not have empty body }
+};
+
+struct D3
+{
+A a;
+A b;
+A c;
+constexpr D3() { return;} // { dg-error does not have empty body }
+};
-- 
1.7.6.4


-- 
Dodji


Re: [PATCH] PR c++/51633 - ICEs with constexpr constructor

2012-01-11 Thread Paolo Carlini
... watch out trailing blank lines ;)

Thanks!
Paolo


Re: [PATCH] PR c++/51633 - ICEs with constexpr constructor

2012-01-11 Thread Dodji Seketeli
Paolo Carlini pcarl...@gmail.com writes:

 ... watch out trailing blank lines ;)

Hopefully fixed below.  Thanks for watching.

gcc/cp/

* semantics.c (cp_parser_ctor_initializer_opt_and_function_body):
Set the pointer to the last block of the constructor to the
current statement.
(build_constexpr_constructor_member_initializers): Get
build_data_member_initialization a chance to deal with more
statements before we choke.

gcc/testsuite/

* g++.dg/cpp0x/constexpr-diag4.C: New test.
---
 gcc/cp/parser.c  |2 +-
 gcc/cp/semantics.c   |2 +
 gcc/testsuite/g++.dg/cpp0x/constexpr-diag4.C |   25 +
 gcc/testsuite/g++.dg/cpp0x/constexpr-diag5.C |   48 ++
 4 files changed, 76 insertions(+), 1 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-diag4.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-diag5.C

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 0ae55a2..ea9ccfc 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -17418,7 +17418,7 @@ cp_parser_ctor_initializer_opt_and_function_body 
(cp_parser *parser)
  cp_parser_function_body changed its state.  */
   if (check_body_p)
 {
-  list = body;
+  list = cur_stmt_list;
   if (TREE_CODE (list) == BIND_EXPR)
list = BIND_EXPR_BODY (list);
   if (TREE_CODE (list) == STATEMENT_LIST
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index fbb74e1..9369179 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -5930,6 +5930,8 @@ build_constexpr_constructor_member_initializers (tree 
type, tree body)
break;
}
 }
+  else if (EXPR_P (body))
+ok = build_data_member_initialization (body, vec);
   else
 gcc_assert (errorcount  0);
   if (ok)
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-diag4.C 
b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag4.C
new file mode 100644
index 000..371190e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag4.C
@@ -0,0 +1,25 @@
+// Origin: PR c++/51633
+// { dg-options -std=c++11 }
+
+struct A
+{
+~A();
+};
+
+struct B
+{
+A a;
+constexpr B() {}
+};
+
+struct A1
+{
+int a;
+~A1();
+};
+
+struct B1
+{
+A1 a1;
+constexpr B1() {} // { dg-error uninitialized member }
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-diag5.C 
b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag5.C
new file mode 100644
index 000..c0cbfdd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag5.C
@@ -0,0 +1,48 @@
+// Origin: PR c++/51633
+// { dg-options -std=c++11 }
+
+struct A
+{
+constexpr A() {}
+~A();
+};
+
+struct B
+{
+A a;
+A b;
+A c;
+constexpr B() {}
+};
+
+struct C
+{
+A a;
+constexpr C() {}
+};
+
+struct D
+{
+constexpr D() { return;} // { dg-error does not have empty body }
+};
+
+struct D1
+{
+A a;
+constexpr D1() { return;} // { dg-error does not have empty body }
+};
+
+struct D2
+{
+A a;
+A b;
+constexpr D2() { return;} // { dg-error does not have empty body }
+};
+
+struct D3
+{
+A a;
+A b;
+A c;
+constexpr D3() { return;} // { dg-error does not have empty body }
+};
-- 
1.7.6.4


-- 
Dodji