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
7 changed files with 56 additions and 11 deletions
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
16
gcc/testsuite/g++.dg/cpp1z/constexpr-if10.C
Normal file
16
gcc/testsuite/g++.dg/cpp1z/constexpr-if10.C
Normal 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)>();
|
||||
}
|
16
gcc/testsuite/g++.dg/cpp1z/constexpr-if11.C
Normal file
16
gcc/testsuite/g++.dg/cpp1z/constexpr-if11.C
Normal 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" }
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue