diff options
author | Jason Merrill <jason@redhat.com> | 2017-01-08 01:36:10 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2017-01-08 01:36:10 -0500 |
commit | 38285dd71996a0020d3bd24fb0c366e8859368af (patch) | |
tree | 602aa0c8a01de98b3ea3c63aa538579a42858263 | |
parent | c3e50bc4e45a3429b8a97bee03dd967cf0c7311f (diff) | |
download | gcc-38285dd71996a0020d3bd24fb0c366e8859368af.zip gcc-38285dd71996a0020d3bd24fb0c366e8859368af.tar.gz gcc-38285dd71996a0020d3bd24fb0c366e8859368af.tar.bz2 |
PR c++/78948 - instantiation from discarded statement
PR c++/78948 - instantiation from discarded statement
* parser.h (struct cp_parser): Remove in_discarded_stmt field.
* cp-tree.h (in_discarded_stmt): Declare it.
(struct saved_scope): Add discarded_stmt bitfield.
(in_discarded_stmt): New macro.
* decl2.c (mark_used): Check it.
* parser.c (cp_parser_selection_statement): Adjust.
(cp_parser_jump_statement): Adjust.
From-SVN: r244206
-rw-r--r-- | gcc/cp/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 6 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 2 | ||||
-rw-r--r-- | gcc/cp/parser.c | 12 | ||||
-rw-r--r-- | gcc/cp/parser.h | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/constexpr-if10.C | 16 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/constexpr-if11.C | 16 |
7 files changed, 56 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1d87845..aa1fd0c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2017-01-07 Jason Merrill <jason@redhat.com> + + PR c++/78948 - instantiation from discarded statement + * parser.h (struct cp_parser): Remove in_discarded_stmt field. + * cp-tree.h (in_discarded_stmt): Declare it. + (struct saved_scope): Add discarded_stmt bitfield. + (in_discarded_stmt): New macro. + * decl2.c (mark_used): Check it. + * parser.c (cp_parser_selection_statement): Adjust. + (cp_parser_jump_statement): Adjust. + 2017-01-05 Jakub Jelinek <jakub@redhat.com> PR c++/78931 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 39f5d79..24de346 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1281,6 +1281,10 @@ struct GTY(()) saved_scope { BOOL_BITFIELD x_processing_explicit_instantiation : 1; BOOL_BITFIELD need_pop_function_context : 1; +/* Nonzero if we are parsing the discarded statement of a constexpr + if-statement. */ + BOOL_BITFIELD discarded_stmt : 1; + int unevaluated_operand; int inhibit_evaluation_warnings; int noexcept_operand; @@ -1341,6 +1345,8 @@ extern GTY(()) struct saved_scope *scope_chain; #define processing_specialization scope_chain->x_processing_specialization #define processing_explicit_instantiation scope_chain->x_processing_explicit_instantiation +#define in_discarded_stmt scope_chain->discarded_stmt + /* RAII sentinel to handle clearing processing_template_decl and restoring it when done. */ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index a0375ad..435f51f 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -5112,7 +5112,7 @@ mark_used (tree decl, tsubst_flags_t complain) } /* If we don't need a value, then we don't need to synthesize DECL. */ - if (cp_unevaluated_operand != 0) + if (cp_unevaluated_operand || in_discarded_stmt) return true; DECL_ODR_USED (decl) = 1; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 57ae064..e8c0642 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -11147,12 +11147,12 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p, /* Outside a template, the non-selected branch of a constexpr if is a 'discarded statement', i.e. unevaluated. */ - bool was_discarded = parser->in_discarded_stmt; + bool was_discarded = in_discarded_stmt; bool discard_then = (cx && !processing_template_decl && integer_zerop (condition)); if (discard_then) { - parser->in_discarded_stmt = true; + in_discarded_stmt = true; ++c_inhibit_evaluation_warnings; } @@ -11166,7 +11166,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p, if (discard_then) { THEN_CLAUSE (statement) = NULL_TREE; - parser->in_discarded_stmt = was_discarded; + in_discarded_stmt = was_discarded; --c_inhibit_evaluation_warnings; } @@ -11178,7 +11178,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p, && integer_nonzerop (condition)); if (discard_else) { - parser->in_discarded_stmt = true; + in_discarded_stmt = true; ++c_inhibit_evaluation_warnings; } @@ -11235,7 +11235,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p, if (discard_else) { ELSE_CLAUSE (statement) = NULL_TREE; - parser->in_discarded_stmt = was_discarded; + in_discarded_stmt = was_discarded; --c_inhibit_evaluation_warnings; } } @@ -12143,7 +12143,7 @@ cp_parser_jump_statement (cp_parser* parser) expression. */ expr = NULL_TREE; /* Build the return-statement. */ - if (current_function_auto_return_pattern && parser->in_discarded_stmt) + if (current_function_auto_return_pattern && in_discarded_stmt) /* Don't deduce from a discarded return statement. */; else statement = finish_return_stmt (expr); diff --git a/gcc/cp/parser.h b/gcc/cp/parser.h index f242f4c..0994e1e 100644 --- a/gcc/cp/parser.h +++ b/gcc/cp/parser.h @@ -336,10 +336,6 @@ struct GTY(()) cp_parser { a local class. */ bool in_function_body; - /* TRUE if we are parsing a C++17 discarded statement (the non-taken branch - of an if constexpr). */ - bool in_discarded_stmt; - /* Nonzero if we're processing a __transaction_atomic or __transaction_relaxed statement. */ unsigned char in_transaction; diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if10.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if10.C new file mode 100644 index 0000000..64de53f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if10.C @@ -0,0 +1,16 @@ +// PR c++/79848 +// { dg-options -std=c++1z } + +template <int T> +void sizeof_mismatch() +{ + static_assert(T == 0, "sizeof mismatch"); +} + +int main() +{ + if constexpr(sizeof(long long) == sizeof(char*)) + ; + else + sizeof_mismatch<sizeof(long long)>(); +} diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if11.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if11.C new file mode 100644 index 0000000..1c6247e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if11.C @@ -0,0 +1,16 @@ +// Test that discarded statements differ from unevaluated operands in some +// ways. +// { dg-options -std=c++1z } + +struct A { int i; }; + +int main() +{ + if constexpr(true) + ; + else + { + []{}(); + A::i; // { dg-error "non-static" } + } +} |