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:
parent
c3e50bc4e4
commit
38285dd719
|
@ -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>
|
2017-01-05 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
PR c++/78931
|
PR c++/78931
|
||||||
|
|
|
@ -1281,6 +1281,10 @@ struct GTY(()) saved_scope {
|
||||||
BOOL_BITFIELD x_processing_explicit_instantiation : 1;
|
BOOL_BITFIELD x_processing_explicit_instantiation : 1;
|
||||||
BOOL_BITFIELD need_pop_function_context : 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 unevaluated_operand;
|
||||||
int inhibit_evaluation_warnings;
|
int inhibit_evaluation_warnings;
|
||||||
int noexcept_operand;
|
int noexcept_operand;
|
||||||
|
@ -1341,6 +1345,8 @@ extern GTY(()) struct saved_scope *scope_chain;
|
||||||
#define processing_specialization scope_chain->x_processing_specialization
|
#define processing_specialization scope_chain->x_processing_specialization
|
||||||
#define processing_explicit_instantiation scope_chain->x_processing_explicit_instantiation
|
#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
|
/* RAII sentinel to handle clearing processing_template_decl and restoring
|
||||||
it when done. */
|
it when done. */
|
||||||
|
|
||||||
|
|
|
@ -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 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;
|
return true;
|
||||||
|
|
||||||
DECL_ODR_USED (decl) = 1;
|
DECL_ODR_USED (decl) = 1;
|
||||||
|
|
|
@ -11147,12 +11147,12 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p,
|
||||||
|
|
||||||
/* Outside a template, the non-selected branch of a constexpr
|
/* Outside a template, the non-selected branch of a constexpr
|
||||||
if is a 'discarded statement', i.e. unevaluated. */
|
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
|
bool discard_then = (cx && !processing_template_decl
|
||||||
&& integer_zerop (condition));
|
&& integer_zerop (condition));
|
||||||
if (discard_then)
|
if (discard_then)
|
||||||
{
|
{
|
||||||
parser->in_discarded_stmt = true;
|
in_discarded_stmt = true;
|
||||||
++c_inhibit_evaluation_warnings;
|
++c_inhibit_evaluation_warnings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11166,7 +11166,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p,
|
||||||
if (discard_then)
|
if (discard_then)
|
||||||
{
|
{
|
||||||
THEN_CLAUSE (statement) = NULL_TREE;
|
THEN_CLAUSE (statement) = NULL_TREE;
|
||||||
parser->in_discarded_stmt = was_discarded;
|
in_discarded_stmt = was_discarded;
|
||||||
--c_inhibit_evaluation_warnings;
|
--c_inhibit_evaluation_warnings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11178,7 +11178,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p,
|
||||||
&& integer_nonzerop (condition));
|
&& integer_nonzerop (condition));
|
||||||
if (discard_else)
|
if (discard_else)
|
||||||
{
|
{
|
||||||
parser->in_discarded_stmt = true;
|
in_discarded_stmt = true;
|
||||||
++c_inhibit_evaluation_warnings;
|
++c_inhibit_evaluation_warnings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11235,7 +11235,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p,
|
||||||
if (discard_else)
|
if (discard_else)
|
||||||
{
|
{
|
||||||
ELSE_CLAUSE (statement) = NULL_TREE;
|
ELSE_CLAUSE (statement) = NULL_TREE;
|
||||||
parser->in_discarded_stmt = was_discarded;
|
in_discarded_stmt = was_discarded;
|
||||||
--c_inhibit_evaluation_warnings;
|
--c_inhibit_evaluation_warnings;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12143,7 +12143,7 @@ cp_parser_jump_statement (cp_parser* parser)
|
||||||
expression. */
|
expression. */
|
||||||
expr = NULL_TREE;
|
expr = NULL_TREE;
|
||||||
/* Build the return-statement. */
|
/* 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. */;
|
/* Don't deduce from a discarded return statement. */;
|
||||||
else
|
else
|
||||||
statement = finish_return_stmt (expr);
|
statement = finish_return_stmt (expr);
|
||||||
|
|
|
@ -336,10 +336,6 @@ struct GTY(()) cp_parser {
|
||||||
a local class. */
|
a local class. */
|
||||||
bool in_function_body;
|
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
|
/* Nonzero if we're processing a __transaction_atomic or
|
||||||
__transaction_relaxed statement. */
|
__transaction_relaxed statement. */
|
||||||
unsigned char in_transaction;
|
unsigned char in_transaction;
|
||||||
|
|
|
@ -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)>();
|
||||||
|
}
|
|
@ -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" }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue