From dfaffca71e70874f64fa18bf952f3e5ea743a7a8 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Mon, 25 Apr 2005 19:58:52 +0000 Subject: [PATCH] re PR c++/20995 (ICE in const_binop, at fold-const.c:1391) PR c++/20995 Partial backport from mainline. 2004-09-27 Mark Mitchell * tree.c (fold_if_not_in_template): New function. * cp-tree.h (fold_if_not_in_template): Prototype here. * call.c (build_conditional_expr): Use fold_if_not_in_template. * typeck.c (build_binary_op): Likewise. * g++.dg/opt/pr20995-1.C: New test case. Co-Authored-By: Mark Mitchell From-SVN: r98736 --- gcc/cp/ChangeLog | 11 +++++++++++ gcc/cp/call.c | 5 +++-- gcc/cp/cp-tree.h | 3 ++- gcc/cp/tree.c | 15 ++++++++++++++- gcc/cp/typeck.c | 4 ++-- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/opt/pr20995-1.C | 8 ++++++++ 7 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/opt/pr20995-1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8b7d0b97d57c..2622d073203b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2005-04-25 Roger Sayle + Mark Mitchell + + PR c++/20995 + Partial backport from mainline. + 2004-09-27 Mark Mitchell + * tree.c (fold_if_not_in_template): New function. + * cp-tree.h (fold_if_not_in_template): Prototype here. + * call.c (build_conditional_expr): Use fold_if_not_in_template. + * typeck.c (build_binary_op): Likewise. + 2005-04-16 Mark Mitchell PR c++/21025 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 968bd45fc268..14b877cc415f 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1,6 +1,6 @@ /* Functions related to invoking methods and overloaded functions. Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) and modified by Brendan Kehoe (brendan@cygnus.com). @@ -3278,7 +3278,8 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3) } valid_operands: - result = fold (build (COND_EXPR, result_type, arg1, arg2, arg3)); + result = fold_if_not_in_template (build (COND_EXPR, result_type, + arg1, arg2, arg3)); /* We can't use result_type below, as fold might have returned a throw_expr. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index bcb63b865870..9bf76bc008ff 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1,6 +1,6 @@ /* Definitions for C++ parsing and type checking. Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GCC. @@ -4194,6 +4194,7 @@ extern int cp_cannot_inline_tree_fn (tree*); extern tree cp_add_pending_fn_decls (void*,tree); extern int cp_is_overload_p (tree); extern int cp_auto_var_in_fn_p (tree,tree); +extern tree fold_if_not_in_template (tree); extern tree cp_copy_res_decl_for_inlining (tree, tree, tree, void*, int*, tree); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 2f078d145b48..c64b4b134c80 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1,6 +1,6 @@ /* Language-dependent node constructors for parse phase of GNU compiler. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GCC. @@ -2526,6 +2526,19 @@ stabilize_init (tree init, tree *initp) return true; } +/* Like "fold", but should be used whenever we might be processing the + body of a template. */ + +tree +fold_if_not_in_template (tree expr) +{ + /* In the body of a template, there is never any need to call + "fold". We will call fold later when actually instantiating the + template. Integral constant expressions in templates will be + evaluated via fold_non_dependent_expr, as necessary. */ + return (processing_template_decl ? expr : fold (expr)); +} + #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) /* Complain that some language-specific thing hanging off a tree diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 648f95f3596c..634ca6685fbf 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1,6 +1,6 @@ /* Build expressions with type checking for C++ compiler. Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GCC. @@ -3458,7 +3458,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, tree result = build (resultcode, build_type, op0, op1); tree folded; - folded = fold (result); + folded = fold_if_not_in_template (result); if (folded == result) TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1); if (final_type != 0) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 110fb3ab4deb..6a0ee4dec07c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-04-25 Roger Sayle + + PR c++/20995 + * g++.dg/opt/pr20995-1.C: New test case. + 2005-04-16 Mark Mitchell PR c++/21025 diff --git a/gcc/testsuite/g++.dg/opt/pr20995-1.C b/gcc/testsuite/g++.dg/opt/pr20995-1.C new file mode 100644 index 000000000000..aa9689639239 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr20995-1.C @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +template void foo() +{ + double d = (N ? 0.0 : 0) + 1; +} + -- 2.47.2