Re: [PATCH] PR c++/51633 - ICEs with constexpr constructor
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
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
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
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
... watch out trailing blank lines ;) Thanks! Paolo
Re: [PATCH] PR c++/51633 - ICEs with constexpr constructor
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