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
This commit is contained in:
Jason Merrill 2017-01-08 01:36:10 -05:00 committed by Jason Merrill
parent c3e50bc4e4
commit 38285dd719
7 changed files with 56 additions and 11 deletions

View File

@ -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

View File

@ -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. */

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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)>();
}

View File

@ -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" }
}
}