diff options
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/call.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-gimplify.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 13 |
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]]. */ |