From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 44248 invoked by alias); 3 Nov 2015 16:53:44 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 44168 invoked by uid 89); 3 Nov 2015 16:53:43 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Tue, 03 Nov 2015 16:53:41 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 92C43C0D61AF for ; Tue, 3 Nov 2015 16:53:39 +0000 (UTC) Received: from redhat.com (ovpn-204-28.brq.redhat.com [10.40.204.28]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3GrYxY007326 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Tue, 3 Nov 2015 11:53:37 -0500 Date: Tue, 03 Nov 2015 16:53:00 -0000 From: Marek Polacek To: GCC Patches , Jason Merrill Subject: [c++-delayed-folding] Introduce convert_to_real_nofold Message-ID: <20151103165334.GN3185@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.24 (2015-08-30) X-SW-Source: 2015-11/txt/msg00249.txt.bz2 The last piece for convert.c. Since convert_to_real uses fold () rather than fold_buildN, I defined a new macro to keep the code more compact. With this committed, convert.c should be dealt with. If there's anything else I could help with, please let me know. Bootstrapped/regtested on x86_64-linux, ok for branch? diff --git gcc/convert.c gcc/convert.c index ec6ff37..3e593db 100644 --- gcc/convert.c +++ gcc/convert.c @@ -37,6 +37,8 @@ along with GCC; see the file COPYING3. If not see #include "builtins.h" #include "ubsan.h" +#define maybe_fold(FOLD_P, EXPR) \ + ((FOLD_P) ? fold (EXPR) : (EXPR)) #define maybe_fold_build1_loc(FOLD_P, LOC, CODE, TYPE, EXPR) \ ((FOLD_P) ? fold_build1_loc (LOC, CODE, TYPE, EXPR) \ : build1_loc (LOC, CODE, TYPE, EXPR)) @@ -119,17 +121,19 @@ convert_to_pointer_nofold (tree type, tree expr) /* Convert EXPR to some floating-point type TYPE. EXPR must be float, fixed-point, integer, or enumeral; - in other cases error is called. */ + in other cases error is called. If FOLD_P is true, try to fold + the expression. */ -tree -convert_to_real (tree type, tree expr) +static tree +convert_to_real_1 (tree type, tree expr, bool fold_p) { enum built_in_function fcode = builtin_mathfn_code (expr); tree itype = TREE_TYPE (expr); + location_t loc = EXPR_LOCATION (expr); if (TREE_CODE (expr) == COMPOUND_EXPR) { - tree t = convert_to_real (type, TREE_OPERAND (expr, 1)); + tree t = convert_to_real_1 (type, TREE_OPERAND (expr, 1), fold_p); if (t == TREE_OPERAND (expr, 1)) return expr; return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR, TREE_TYPE (t), @@ -237,14 +241,13 @@ convert_to_real (tree type, tree expr) || TYPE_MODE (newtype) == TYPE_MODE (float_type_node))) { tree fn = mathfn_built_in (newtype, fcode); - if (fn) - { - tree arg = fold (convert_to_real (newtype, arg0)); - expr = build_call_expr (fn, 1, arg); - if (newtype == type) - return expr; - } + { + tree arg = convert_to_real_1 (newtype, arg0, fold_p); + expr = build_call_expr (fn, 1, maybe_fold (fold_p, arg)); + if (newtype == type) + return expr; + } } } default: @@ -263,9 +266,11 @@ convert_to_real (tree type, tree expr) if (!flag_rounding_math && FLOAT_TYPE_P (itype) && TYPE_PRECISION (type) < TYPE_PRECISION (itype)) - return build1 (TREE_CODE (expr), type, - fold (convert_to_real (type, - TREE_OPERAND (expr, 0)))); + { + tree arg = convert_to_real_1 (type, TREE_OPERAND (expr, 0), + fold_p); + return build1 (TREE_CODE (expr), type, maybe_fold (fold_p, arg)); + } break; /* Convert (outertype)((innertype0)a+(innertype1)b) into ((newtype)a+(newtype)b) where newtype @@ -301,8 +306,14 @@ convert_to_real (tree type, tree expr) || newtype == dfloat128_type_node) { expr = build2 (TREE_CODE (expr), newtype, - fold (convert_to_real (newtype, arg0)), - fold (convert_to_real (newtype, arg1))); + maybe_fold (fold_p, + convert_to_real_1 (newtype, + arg0, + fold_p)), + maybe_fold (fold_p, + convert_to_real_1 (newtype, + arg1, + fold_p))); if (newtype == type) return expr; break; @@ -341,8 +352,14 @@ convert_to_real (tree type, tree expr) && !excess_precision_type (newtype)))) { expr = build2 (TREE_CODE (expr), newtype, - fold (convert_to_real (newtype, arg0)), - fold (convert_to_real (newtype, arg1))); + maybe_fold (fold_p, + convert_to_real_1 (newtype, + arg0, + fold_p)), + maybe_fold (fold_p, + convert_to_real_1 (newtype, + arg1, + fold_p))); if (newtype == type) return expr; } @@ -373,20 +390,39 @@ convert_to_real (tree type, tree expr) case COMPLEX_TYPE: return convert (type, - fold_build1 (REALPART_EXPR, - TREE_TYPE (TREE_TYPE (expr)), expr)); + maybe_fold_build1_loc (fold_p, loc, REALPART_EXPR, + TREE_TYPE (TREE_TYPE (expr)), + expr)); case POINTER_TYPE: case REFERENCE_TYPE: error ("pointer value used where a floating point value was expected"); - return convert_to_real (type, integer_zero_node); + return convert_to_real_1 (type, integer_zero_node, fold_p); default: error ("aggregate value used where a float was expected"); - return convert_to_real (type, integer_zero_node); + return convert_to_real_1 (type, integer_zero_node, fold_p); } } +/* A wrapper around convert_to_real_1 that always folds the + expression. */ + +tree +convert_to_real (tree type, tree expr) +{ + return convert_to_real_1 (type, expr, true); +} + +/* A wrapper around convert_to_real_1 that only folds the + expression if it is CONSTANT_CLASS_P. */ + +tree +convert_to_real_nofold (tree type, tree expr) +{ + return convert_to_real_1 (type, expr, CONSTANT_CLASS_P (expr)); +} + /* Convert EXPR to some integer (or enum) type TYPE. EXPR must be pointer, integer, discrete (enum, char, or bool), float, diff --git gcc/convert.h gcc/convert.h index 6cb439e..7cc3168 100644 --- gcc/convert.h +++ gcc/convert.h @@ -25,6 +25,7 @@ extern tree convert_to_integer_nofold (tree, tree); extern tree convert_to_pointer (tree, tree); extern tree convert_to_pointer_nofold (tree, tree); extern tree convert_to_real (tree, tree); +extern tree convert_to_real_nofold (tree, tree); extern tree convert_to_fixed (tree, tree); extern tree convert_to_complex (tree, tree); extern tree convert_to_complex_nofold (tree, tree); diff --git gcc/cp/call.c gcc/cp/call.c index 79f8cfa..5b21b9f 100644 --- gcc/cp/call.c +++ gcc/cp/call.c @@ -6742,7 +6742,7 @@ convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain) "implicit conversion from %qT to %qT when passing " "argument to function", arg_type, double_type_node); - arg = convert_to_real (double_type_node, arg); + arg = convert_to_real_nofold (double_type_node, arg); } else if (NULLPTR_TYPE_P (arg_type)) arg = null_pointer_node; diff --git gcc/cp/cvt.c gcc/cp/cvt.c index 1368f15..97b0b89 100644 --- gcc/cp/cvt.c +++ gcc/cp/cvt.c @@ -846,7 +846,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags, TREE_TYPE (e)); } if (code == REAL_TYPE) - return convert_to_real (type, e); + return convert_to_real_nofold (type, e); else if (code == COMPLEX_TYPE) return convert_to_complex_nofold (type, e); } Marek