From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2153) id 28D9F3858439; Mon, 24 Oct 2022 14:26:11 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 28D9F3858439 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1666621572; bh=iYhFY2xij4HCEq3ODX0+Y8vdV8hW/sgSWUCSQW/UYVg=; h=From:To:Subject:Date:From; b=G/7N7N7FqtcLD67itAkpFStTiCnXV+KZJcWdODfFn+9HenJMihc+YxM+vK9rrkuYG QnXfX0pC+x+eNS6RO2Chlwfxd2IE7FVGcm/1hYbeBjxdTZi91bxgK7lpABOPXHDuXn l651AbdX4o/v3gAmMf1RuWGYzw8HHLnplNcEelxA= 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 r13-3458] 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/master X-Git-Oldrev: f44575cb88727193386428e9ced3439e4f98f493 X-Git-Newrev: da8c362c4c18cff2f2dfd5c4706bdda7576899a4 Message-Id: <20221024142612.28D9F3858439@sourceware.org> Date: Mon, 24 Oct 2022 14:26:11 +0000 (GMT) List-Id: https://gcc.gnu.org/g:da8c362c4c18cff2f2dfd5c4706bdda7576899a4 commit r13-3458-gda8c362c4c18cff2f2dfd5c4706bdda7576899a4 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.cc (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. Diff: --- gcc/cp/constexpr.cc | 12 ++++++++++++ gcc/testsuite/g++.dg/cpp1y/constexpr-105774.C | 15 +++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index c3ee970a724..94b54fc71dc 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -6234,6 +6234,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 ();