aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-01-08 01:36:10 -0500
committerJason Merrill <jason@gcc.gnu.org>2017-01-08 01:36:10 -0500
commit38285dd71996a0020d3bd24fb0c366e8859368af (patch)
tree602aa0c8a01de98b3ea3c63aa538579a42858263
parentc3e50bc4e45a3429b8a97bee03dd967cf0c7311f (diff)
downloadgcc-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/ChangeLog11
-rw-r--r--gcc/cp/cp-tree.h6
-rw-r--r--gcc/cp/decl2.c2
-rw-r--r--gcc/cp/parser.c12
-rw-r--r--gcc/cp/parser.h4
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/constexpr-if10.C16
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/constexpr-if11.C16
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" }
+ }
+}