aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/call.c2
-rw-r--r--gcc/cp/cp-gimplify.c2
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/cvt.c13
5 files changed, 23 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5d7b9c0..894a33e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2018-03-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/84978, ICE with NRVO.
+ * cvt.c (cp_get_fndecl_from_callee): Add fold parameter.
+ (cp_get_callee_fndecl_nofold): New.
+ * cp-gimplify.c (cp_genericize_r): Use it instead.
+ * call.c (check_self_delegation): Likewise.
+
2018-03-20 Nathan Sidwell <nathan@acm.org>
PR c++/84962
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 23d4f82..dbdb8d5 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -8739,7 +8739,7 @@ check_self_delegation (tree ret)
{
if (TREE_CODE (ret) == TARGET_EXPR)
ret = TARGET_EXPR_INITIAL (ret);
- tree fn = cp_get_callee_fndecl (ret);
+ tree fn = cp_get_callee_fndecl_nofold (ret);
if (fn && DECL_ABSTRACT_ORIGIN (fn) == current_function_decl)
error ("constructor delegates to itself");
}
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 332ff2b..3edecf24 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -1521,7 +1521,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
version is inlinable, a direct call to this version can be made
otherwise the call should go through the dispatcher. */
{
- tree fn = cp_get_callee_fndecl (stmt);
+ tree fn = cp_get_callee_fndecl_nofold (stmt);
if (fn && DECL_FUNCTION_VERSIONED (fn)
&& (current_function_decl == NULL
|| !targetm.target_option.can_inline_p (current_function_decl,
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 077ef2d..4df16e2 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6110,7 +6110,8 @@ extern tree cp_convert_and_check (tree, tree, tsubst_flags_t);
extern tree cp_fold_convert (tree, tree);
extern tree cp_get_callee (tree);
extern tree cp_get_callee_fndecl (tree);
-extern tree cp_get_fndecl_from_callee (tree);
+extern tree cp_get_callee_fndecl_nofold (tree);
+extern tree cp_get_fndecl_from_callee (tree, bool fold = true);
extern tree convert_to_void (tree, impl_conv_void,
tsubst_flags_t);
extern tree convert_force (tree, tree, int,
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 40e7576..9b53fa3 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -941,7 +941,7 @@ cp_get_callee (tree call)
if we can. */
tree
-cp_get_fndecl_from_callee (tree fn)
+cp_get_fndecl_from_callee (tree fn, bool fold /* = true */)
{
if (fn == NULL_TREE)
return fn;
@@ -951,7 +951,8 @@ cp_get_fndecl_from_callee (tree fn)
if (type == unknown_type_node)
return NULL_TREE;
gcc_assert (POINTER_TYPE_P (type));
- fn = maybe_constant_init (fn);
+ if (fold)
+ fn = maybe_constant_init (fn);
STRIP_NOPS (fn);
if (TREE_CODE (fn) == ADDR_EXPR)
{
@@ -971,6 +972,14 @@ cp_get_callee_fndecl (tree call)
return cp_get_fndecl_from_callee (cp_get_callee (call));
}
+/* As above, but not using the constexpr machinery. */
+
+tree
+cp_get_callee_fndecl_nofold (tree call)
+{
+ return cp_get_fndecl_from_callee (cp_get_callee (call), false);
+}
+
/* Subroutine of convert_to_void. Warn if we're discarding something with
attribute [[nodiscard]]. */