From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 820AB385840A for ; Mon, 24 Oct 2022 07:27:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 820AB385840A Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1666596461; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type; bh=9WDcj4GulQCci1C9CQxnwVMM2CvfcCKYGE71bFeHqao=; b=eNtqo+e+31Apz7iR97WcqWl5uNXC/Ao/mHj6tL0R2e7hbb+LsuwkByri5N24GBNdRT5NfA IAYRLLfIYh6IvvJFoJFGnfHCeh1vzjN59yZrqR0bTMTfrr0V/vDI6BcQ/dAs28mvQon3SK NNRCtunvutMaZVaPZXU8cmGFs5Br1ds= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-135-d9TtLcl7PL-BhOS26aXMQA-1; Mon, 24 Oct 2022 03:27:31 -0400 X-MC-Unique: d9TtLcl7PL-BhOS26aXMQA-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id D30111C07552 for ; Mon, 24 Oct 2022 07:27:30 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.193.252]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8B4CC39DB3; Mon, 24 Oct 2022 07:27:28 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 29O7RQmd3042803 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Mon, 24 Oct 2022 09:27:26 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 29O7RPQQ3042802; Mon, 24 Oct 2022 09:27:25 +0200 Date: Mon, 24 Oct 2022 09:27:25 +0200 From: Jakub Jelinek To: Jason Merrill Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] c++: Fix up constexpr handling of char/signed char/short pre/post inc/decrement [PR105774] Message-ID: Reply-To: Jakub Jelinek MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-4.5 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Hi! 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. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 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. --- gcc/cp/constexpr.cc.jj 2022-10-21 18:04:47.869797312 +0200 +++ gcc/cp/constexpr.cc 2022-10-23 18:43:27.003390282 +0200 @@ -6234,6 +6234,18 @@ cxx_eval_increment_expression (const con 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) --- gcc/testsuite/g++.dg/cpp1y/constexpr-105774.C.jj 2022-10-23 18:44:15.587729613 +0200 +++ gcc/testsuite/g++.dg/cpp1y/constexpr-105774.C 2022-10-23 18:33:54.754170726 +0200 @@ -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 (); Jakub