Commit dcdbc004 by Jason Merrill Committed by Jason Merrill

Expand PTRMEM_CST only when necessary.

	* 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
parent 13b380a3
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> 2015-10-17 Jason Merrill <jason@redhat.com>
PR c++/68006 PR c++/68006
......
...@@ -1863,6 +1863,8 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t, ...@@ -1863,6 +1863,8 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
tree whole = cxx_eval_constant_expression (ctx, orig_whole, tree whole = cxx_eval_constant_expression (ctx, orig_whole,
lval, lval,
non_constant_p, overflow_p); non_constant_p, overflow_p);
if (TREE_CODE (whole) == PTRMEM_CST)
whole = cplus_expand_constant (whole);
if (whole == orig_whole) if (whole == orig_whole)
return t; return t;
if (lval) if (lval)
...@@ -3129,9 +3131,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, ...@@ -3129,9 +3131,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
} }
if (CONSTANT_CLASS_P (t)) if (CONSTANT_CLASS_P (t))
{ {
if (TREE_CODE (t) == PTRMEM_CST) if (TREE_OVERFLOW (t) && (!flag_permissive || ctx->quiet))
t = cplus_expand_constant (t);
else if (TREE_OVERFLOW (t) && (!flag_permissive || ctx->quiet))
*overflow_p = true; *overflow_p = true;
return t; return t;
} }
...@@ -3545,7 +3545,11 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, ...@@ -3545,7 +3545,11 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
non_constant_p, overflow_p); non_constant_p, overflow_p);
if (*non_constant_p) if (*non_constant_p)
return t; 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 && TREE_CODE (op) == INTEGER_CST
&& !integer_zerop (op)) && !integer_zerop (op))
{ {
...@@ -3559,7 +3563,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, ...@@ -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 /* We didn't fold at the top so we could check for ptr-int
conversion. */ conversion. */
return fold (t); 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 /* Conversion of an out-of-range value has implementation-defined
behavior; the language considers it different from arithmetic behavior; the language considers it different from arithmetic
overflow, which is undefined. */ overflow, which is undefined. */
......
...@@ -6714,6 +6714,9 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, ...@@ -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 to put statics on the list so we can deal with the label
address extension. FIXME. */ address extension. FIXME. */
add_local_decl (cfun, decl); 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 /* Convert the initializer to the type of DECL, if we have not
...@@ -14887,10 +14890,6 @@ complete_vars (tree type) ...@@ -14887,10 +14890,6 @@ complete_vars (tree type)
cp_apply_type_quals_to_decl (cp_type_quals (type), var); 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. */ /* Remove this entry from the list. */
incomplete_vars->unordered_remove (ix); incomplete_vars->unordered_remove (ix);
} }
......
...@@ -4484,6 +4484,22 @@ maybe_warn_sized_delete () ...@@ -4484,6 +4484,22 @@ maybe_warn_sized_delete ()
maybe_warn_sized_delete (VEC_DELETE_EXPR); 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. /* This routine is called at the end of compilation.
Its job is to create all the code needed to initialize and Its job is to create all the code needed to initialize and
destroy the global aggregates. We do the destruction destroy the global aggregates. We do the destruction
...@@ -4793,6 +4809,8 @@ c_parse_final_cleanups (void) ...@@ -4793,6 +4809,8 @@ c_parse_final_cleanups (void)
} }
while (reconsider); while (reconsider);
lower_var_init ();
generate_mangling_aliases (); generate_mangling_aliases ();
/* All used inline functions must have a definition at this point. */ /* All used inline functions must have a definition at this point. */
......
...@@ -1059,22 +1059,11 @@ digest_init_r (tree type, tree init, bool nested, int flags, ...@@ -1059,22 +1059,11 @@ digest_init_r (tree type, tree init, bool nested, int flags,
|| BRACE_ENCLOSED_INITIALIZER_P (init)) || BRACE_ENCLOSED_INITIALIZER_P (init))
&& (SCALAR_TYPE_P (type) || code == REFERENCE_TYPE)) && (SCALAR_TYPE_P (type) || code == REFERENCE_TYPE))
{ {
tree *exp;
if (nested) if (nested)
flags |= LOOKUP_NO_NARROWING; flags |= LOOKUP_NO_NARROWING;
init = convert_for_initialization (0, type, init, flags, init = convert_for_initialization (0, type, init, flags,
ICR_INIT, NULL_TREE, 0, ICR_INIT, NULL_TREE, 0,
complain); 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; return init;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment