PR c++/78948 - instantiation from discarded statement
authorJason Merrill <jason@redhat.com>
Sun, 8 Jan 2017 06:36:10 +0000 (01:36 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 8 Jan 2017 06:36:10 +0000 (01:36 -0500)
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

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/cp/parser.c
gcc/cp/parser.h
gcc/testsuite/g++.dg/cpp1z/constexpr-if10.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1z/constexpr-if11.C [new file with mode: 0644]

index 1d87845a882b33f84668b134c035f621ad5facfd..aa1fd0c03c8bb51097fef8129c6031479dadd48e 100644 (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
index 39f5d790cdc469515e13d2b807a42b79147d11f6..24de3462bb7711ba0880038e627561bc01a32c6d 100644 (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.  */
 
index a0375ad4cc41218a43e43e8562a2d601573ffb94..435f51fe5644f9360c0123d349fdda9a19ab9aee 100644 (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;
index 57ae064719524400def7fda23d9a2392691b994c..e8c06424e29f515c0aeca26d017025bdd476904d 100644 (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);
index f242f4c6153cd186aec08b8f5d500adf5a5e6573..0994e1e7f4fc88150d61118190cfe54ace9180fe 100644 (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;
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if10.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if10.C
new file mode 100644 (file)
index 0000000..64de53f
--- /dev/null
@@ -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 (file)
index 0000000..1c6247e
--- /dev/null
@@ -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" }
+    }
+}