Expand PTRMEM_CST only when necessary.
authorJason Merrill <jason@redhat.com>
Tue, 20 Oct 2015 02:48:43 +0000 (22:48 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 20 Oct 2015 02:48:43 +0000 (22:48 -0400)
* constexpr.c (cxx_eval_constant_expression): Expand PTRMEM_CST
only when necessary.
(cxx_eval_component_reference): Like here.
* decl2.c (lower_var_init): And here.
(c_parse_final_cleanups): Call it.
* typeck2.c (digest_init_r): Not here.
* decl.c (complete_vars): Or here.
(cp_finish_decl): Add local statics to symbol table.

From-SVN: r229018

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/typeck2.c

index 93ffc73fcc822d9a17227995ff6d769cb2b2e00f..6bc52c360804f36a98c1eeaed4289f4bc9eb4cb4 100644 (file)
@@ -1,3 +1,14 @@
+2015-10-19  Jason Merrill  <jason@redhat.com>
+
+       * constexpr.c (cxx_eval_constant_expression): Expand PTRMEM_CST
+       only when necessary.
+       (cxx_eval_component_reference): Like here.
+       * decl2.c (lower_var_init): And here.
+       (c_parse_final_cleanups): Call it.
+       * typeck2.c (digest_init_r): Not here.
+       * decl.c (complete_vars): Or here.
+       (cp_finish_decl): Add local statics to symbol table.
+
 2015-10-17  Jason Merrill  <jason@redhat.com>
 
        PR c++/68006
index 1bb8efa90ed22529005942089be5dc36efc56013..3d682fd23f2a01c314ff3be4b5efa9f998eae7c6 100644 (file)
@@ -1863,6 +1863,8 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
   tree whole = cxx_eval_constant_expression (ctx, orig_whole,
                                             lval,
                                             non_constant_p, overflow_p);
+  if (TREE_CODE (whole) == PTRMEM_CST)
+    whole = cplus_expand_constant (whole);
   if (whole == orig_whole)
     return t;
   if (lval)
@@ -3129,9 +3131,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
     }
   if (CONSTANT_CLASS_P (t))
     {
-      if (TREE_CODE (t) == PTRMEM_CST)
-       t = cplus_expand_constant (t);
-      else if (TREE_OVERFLOW (t) && (!flag_permissive || ctx->quiet))
+      if (TREE_OVERFLOW (t) && (!flag_permissive || ctx->quiet))
        *overflow_p = true;
       return t;
     }
@@ -3545,7 +3545,11 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
                                                non_constant_p, overflow_p);
        if (*non_constant_p)
          return t;
-       if (POINTER_TYPE_P (TREE_TYPE (t))
+       tree type = TREE_TYPE (t);
+       if (TREE_CODE (op) == PTRMEM_CST
+           && !TYPE_PTRMEM_P (type))
+         op = cplus_expand_constant (op);
+       if (POINTER_TYPE_P (type)
            && TREE_CODE (op) == INTEGER_CST
            && !integer_zerop (op))
          {
@@ -3559,7 +3563,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
          /* We didn't fold at the top so we could check for ptr-int
             conversion.  */
          return fold (t);
-       r = fold_build1 (TREE_CODE (t), TREE_TYPE (t), op);
+       r = fold_build1 (TREE_CODE (t), type, op);
        /* Conversion of an out-of-range value has implementation-defined
           behavior; the language considers it different from arithmetic
           overflow, which is undefined.  */
index 5716a13bcfc759dde146dbd9fb5ee59a25ff661d..50bb39c8f9a7c71962c402dc23566c9fb83d9cdf 100644 (file)
@@ -6714,6 +6714,9 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
               to put statics on the list so we can deal with the label
               address extension.  FIXME.  */
            add_local_decl (cfun, decl);
+         /* And make sure it's in the symbol table for
+            c_parse_final_cleanups to find.  */
+         varpool_node::get_create (decl);
        }
 
       /* Convert the initializer to the type of DECL, if we have not
@@ -14887,10 +14890,6 @@ complete_vars (tree type)
              cp_apply_type_quals_to_decl (cp_type_quals (type), var);
            }
 
-         if (DECL_INITIAL (var)
-             && decl_constant_var_p (var))
-           DECL_INITIAL (var) = cplus_expand_constant (DECL_INITIAL (var));
-
          /* Remove this entry from the list.  */
          incomplete_vars->unordered_remove (ix);
        }
index a5b44e02c141a66d6e319028fc4de004043743eb..3b3817e6da9febde9d9574186b44308ea3be1682 100644 (file)
@@ -4484,6 +4484,22 @@ maybe_warn_sized_delete ()
   maybe_warn_sized_delete (VEC_DELETE_EXPR);
 }
 
+/* Earlier we left PTRMEM_CST in variable initializers alone so that we could
+   look them up when evaluating non-type template parameters.  Now we need to
+   lower them to something the back end can understand.  */
+
+static void
+lower_var_init ()
+{
+  varpool_node *node;
+  FOR_EACH_VARIABLE (node)
+    {
+      tree d = node->decl;
+      if (tree init = DECL_INITIAL (d))
+       DECL_INITIAL (d) = cplus_expand_constant (init);
+    }
+}
+
 /* This routine is called at the end of compilation.
    Its job is to create all the code needed to initialize and
    destroy the global aggregates.  We do the destruction
@@ -4793,6 +4809,8 @@ c_parse_final_cleanups (void)
     }
   while (reconsider);
 
+  lower_var_init ();
+
   generate_mangling_aliases ();
 
   /* All used inline functions must have a definition at this point.  */
index 2c9143e63a2960cff3838360200b1082eb4f4d23..e61a57f8b3540bcf8fe3ae2b7bf7dd2132b6bc92 100644 (file)
@@ -1059,22 +1059,11 @@ digest_init_r (tree type, tree init, bool nested, int flags,
        || BRACE_ENCLOSED_INITIALIZER_P (init))
       && (SCALAR_TYPE_P (type) || code == REFERENCE_TYPE))
     {
-      tree *exp;
-
       if (nested)
        flags |= LOOKUP_NO_NARROWING;
       init = convert_for_initialization (0, type, init, flags,
                                         ICR_INIT, NULL_TREE, 0,
                                         complain);
-      exp = &init;
-
-      /* Skip any conversions since we'll be outputting the underlying
-        constant.  */
-      while (CONVERT_EXPR_P (*exp)
-            || TREE_CODE (*exp) == NON_LVALUE_EXPR)
-       exp = &TREE_OPERAND (*exp, 0);
-
-      *exp = cplus_expand_constant (*exp);
 
       return init;
     }