From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2153) id E592738582A6; Fri, 4 Nov 2022 08:31:14 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E592738582A6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1667550674; bh=RSvk25XJpszEtC/WcjnU8Fcr8pDDqt8QSLZbtJd2y6A=; h=From:To:Subject:Date:From; b=DjaUa/u7FUL470yzI8t1NbGhosL+CKPlWRSqEHUSg9xys79vUh9LX605lbTSXqbt6 z5afjRGq4UL8KolJ3guwBBFlfu8qVgE5sap4nKTv5nPI86CB2hkSxf2RgGl/1HmWVH s5ZaK3UWAph/aBCBJJp6u60/iebm2Q5Rr4tEylP4= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jakub Jelinek To: gcc-cvs@gcc.gnu.org Subject: [gcc r11-10362] c++: Fix up constexpr handling of char/signed char/short pre/post inc/decrement [PR105774] X-Act-Checkin: gcc X-Git-Author: Jakub Jelinek X-Git-Refname: refs/heads/releases/gcc-11 X-Git-Oldrev: a2423e832d936ab50a2bf1a6b2f0dfb811d0be50 X-Git-Newrev: 11a37955860f8573570aaf8d9fb0b6e02a3d4d5a Message-Id: <20221104083114.E592738582A6@sourceware.org> Date: Fri, 4 Nov 2022 08:31:14 +0000 (GMT) List-Id: https://gcc.gnu.org/g:11a37955860f8573570aaf8d9fb0b6e02a3d4d5a commit r11-10362-g11a37955860f8573570aaf8d9fb0b6e02a3d4d5a Author: Jakub Jelinek Date: Mon Oct 24 16:25:29 2022 +0200 c++: Fix up constexpr handling of char/signed char/short pre/post inc/decrement [PR105774] signed char, char or short int pre/post inc/decrement are represented by normal {PRE,POST}_{INC,DEC}REMENT_EXPRs in the FE and only gimplification ensures that the {PLUS,MINUS}_EXPR is done in unsigned version of those types: case PREINCREMENT_EXPR: case PREDECREMENT_EXPR: case POSTINCREMENT_EXPR: case POSTDECREMENT_EXPR: { tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 0)); if (INTEGRAL_TYPE_P (type) && c_promoting_integer_type_p (type)) { if (!TYPE_OVERFLOW_WRAPS (type)) type = unsigned_type_for (type); return gimplify_self_mod_expr (expr_p, pre_p, post_p, 1, type); } break; } This means during constant evaluation we need to do it similarly (either using unsigned_type_for or using widening to integer_type_node). The following patch does the latter. 2022-10-24 Jakub Jelinek PR c++/105774 * constexpr.c (cxx_eval_increment_expression): For signed types that promote to int, evaluate PLUS_EXPR or MINUS_EXPR in int type. * g++.dg/cpp1y/constexpr-105774.C: New test. (cherry picked from commit da8c362c4c18cff2f2dfd5c4706bdda7576899a4) Diff: --- gcc/cp/constexpr.c | 12 ++++++++++++ gcc/testsuite/g++.dg/cpp1y/constexpr-105774.C | 15 +++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 7be5f25b10f..d7bea558bfb 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -5674,6 +5674,18 @@ cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t, offset = fold_build1 (NEGATE_EXPR, TREE_TYPE (offset), offset); mod = fold_build2 (POINTER_PLUS_EXPR, type, val, offset); } + else if (c_promoting_integer_type_p (type) + && !TYPE_UNSIGNED (type) + && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) + { + offset = fold_convert (integer_type_node, offset); + mod = fold_convert (integer_type_node, val); + tree t = fold_build2 (inc ? PLUS_EXPR : MINUS_EXPR, integer_type_node, + mod, offset); + mod = fold_convert (type, t); + if (TREE_OVERFLOW_P (mod) && !TREE_OVERFLOW_P (t)) + TREE_OVERFLOW (mod) = false; + } else mod = fold_build2 (inc ? PLUS_EXPR : MINUS_EXPR, type, val, offset); if (!ptr) diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-105774.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-105774.C new file mode 100644 index 00000000000..8ca6fce7570 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-105774.C @@ -0,0 +1,15 @@ +// PR c++/105774 +// { dg-do compile { target c++14 } } + +constexpr signed char +foo () +{ +#if __SCHAR_MAX__ < __INT_MAX__ + signed char x = __SCHAR_MAX__; +#else + signed char x = 0; +#endif + return ++x; +} + +constexpr auto a = foo ();