aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2015-10-19 22:48:43 -0400
committerJason Merrill <jason@gcc.gnu.org>2015-10-19 22:48:43 -0400
commitdcdbc004d531b43e0583f8ac18def1474d64dc05 (patch)
treea3ee54d747eb001c8c79a026521c8920f2221b27 /gcc
parent13b380a3257189e5232010c982b8c691b348482c (diff)
downloadgcc-dcdbc004d531b43e0583f8ac18def1474d64dc05.zip
gcc-dcdbc004d531b43e0583f8ac18def1474d64dc05.tar.gz
gcc-dcdbc004d531b43e0583f8ac18def1474d64dc05.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/constexpr.c14
-rw-r--r--gcc/cp/decl.c7
-rw-r--r--gcc/cp/decl2.c18
-rw-r--r--gcc/cp/typeck2.c11
5 files changed, 41 insertions, 20 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 93ffc73..6bc52c3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 1bb8efa..3d682fd 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -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. */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 5716a13..50bb39c 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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);
}
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index a5b44e0..3b3817e 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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. */
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 2c9143e..e61a57f 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -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;
}