From patchwork Fri Jun 28 23:00:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 1954184 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=EUUaxdLw; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4W9rXS6p1Nz20Xp for ; Sat, 29 Jun 2024 09:01:27 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EEE42386D61B for ; Fri, 28 Jun 2024 23:01:24 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org 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 5934338708C3 for ; Fri, 28 Jun 2024 23:01:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5934338708C3 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 5934338708C3 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719615668; cv=none; b=cgLx3W0N6jSsYn4p3SOziq/+xyx2Mf5gWh6tgBbCXpAbm+fcSa5XB0x/aKPD17FKYNROJQRQWTwmr8xlME0TLYY2X+q7MIUhwBjfOxpgdHmpmAm7SPYpf2WITCIUJTdIBMBhi8MOTeYidMiM8SfzA7TNDtKXEUcUAN0KthPivY4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719615668; c=relaxed/simple; bh=B2yarUiwGWoCqlE1xSk78wOZn4GrBNtelbqf6OZtRbw=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=xOEOlYWrKcRQVSNwrCNCqcGZq5/ArqDRZWMTNCPmC0id0D1H/YryZYC/bIRSOEvJrkvdATx7HIjNjRhcFO/+0C2YONZHzxY4EH2weOL62svNb0zKlxgGcavS0lbBY1QHMvjePp+bi4uChhX6MJf/DWqZcT+OBmzIJm7b0MpRke0= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1719615664; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=eEfmVtaw85En3fnpI+F0ghUQxAJg7VSBgJ1DwPei5qA=; b=EUUaxdLwgyAy4lT6epHuf5bt3j6FITIHR5WbSYmW56RYCQRowREWexMQJ47Mjn4U8IxAic gpyyZrcmx92g0t/Ae78yuIyCyrDYnclx294F6BSWoGBXNmfz70s69y/IGnOf2bQ01Idriu Kis0bHVpUGQKr5an+Tl6aJcBRWdExtg= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-269-DJmBUJMDNaSaaYCKqpMxaQ-1; Fri, 28 Jun 2024 19:01:01 -0400 X-MC-Unique: DJmBUJMDNaSaaYCKqpMxaQ-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 3288D1956087 for ; Fri, 28 Jun 2024 23:00:59 +0000 (UTC) Received: from pdp-11.lan (unknown [10.22.18.13]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 6193219560A3; Fri, 28 Jun 2024 23:00:57 +0000 (UTC) From: Marek Polacek To: Jason Merrill , GCC Patches Subject: [PATCH] c++: DR2627, Bit-fields and narrowing conversions [PR94058] Date: Fri, 28 Jun 2024 19:00:52 -0400 Message-ID: <20240628230052.446907-1-polacek@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, 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 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? -- >8 -- This DR (https://cplusplus.github.io/CWG/issues/2627.html) says that even if we are converting from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, it's not narrowing if "the source is a bit-field whose width w is less than that of its type (or, for an enumeration type, its underlying type) and the target type can represent all the values of a hypothetical extended integer type with width w and with the same signedness as the original type". DR 2627 PR c++/94058 PR c++/104392 gcc/cp/ChangeLog: * typeck2.cc (check_narrowing): Don't warn if the conversion isn't narrowing as per DR 2627. gcc/testsuite/ChangeLog: * g++.dg/DRs/dr2627.C: New test. * g++.dg/cpp0x/Wnarrowing22.C: New test. * g++.dg/cpp2a/spaceship-narrowing1.C: New test. * g++.dg/cpp2a/spaceship-narrowing2.C: New test. --- gcc/cp/typeck2.cc | 12 +++++ gcc/testsuite/g++.dg/DRs/dr2627.C | 13 +++++ gcc/testsuite/g++.dg/cpp0x/Wnarrowing22.C | 49 +++++++++++++++++++ .../g++.dg/cpp2a/spaceship-narrowing1.C | 34 +++++++++++++ .../g++.dg/cpp2a/spaceship-narrowing2.C | 26 ++++++++++ 5 files changed, 134 insertions(+) create mode 100644 gcc/testsuite/g++.dg/DRs/dr2627.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/Wnarrowing22.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/spaceship-narrowing1.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/spaceship-narrowing2.C base-commit: 52370c839edd04df86d3ff2b71fcdca0c7376a7f diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc index 7782f38da43..30a6fbe95c9 100644 --- a/gcc/cp/typeck2.cc +++ b/gcc/cp/typeck2.cc @@ -1012,6 +1012,18 @@ check_narrowing (tree type, tree init, tsubst_flags_t complain, if (TREE_CODE (ftype) == ENUMERAL_TYPE) /* Check for narrowing based on the values of the enumeration. */ ftype = ENUM_UNDERLYING_TYPE (ftype); + /* Undo convert_bitfield_to_declared_type (STRIP_NOPS isn't enough). */ + tree op = init; + while (CONVERT_EXPR_P (op)) + op = TREE_OPERAND (op, 0); + /* Core 2627 says that we shouldn't warn when "the source is a bit-field + whose width w is less than that of its type (or, for an enumeration + type, its underlying type) and the target type can represent all the + values of a hypothetical extended integer type with width w and with + the same signedness as the original type". */ + if (is_bitfield_expr_with_lowered_type (op) + && TYPE_PRECISION (TREE_TYPE (op)) < TYPE_PRECISION (ftype)) + ftype = TREE_TYPE (op); if ((tree_int_cst_lt (TYPE_MAX_VALUE (type), TYPE_MAX_VALUE (ftype)) || tree_int_cst_lt (TYPE_MIN_VALUE (ftype), diff --git a/gcc/testsuite/g++.dg/DRs/dr2627.C b/gcc/testsuite/g++.dg/DRs/dr2627.C new file mode 100644 index 00000000000..fe7f28613ca --- /dev/null +++ b/gcc/testsuite/g++.dg/DRs/dr2627.C @@ -0,0 +1,13 @@ +// DR 2627 - Bit-fields and narrowing conversions +// { dg-do compile { target c++20 } } + +#include + +struct C { + long long i : 8; +}; + +void f() { + C x{1}, y{2}; + x.i <=> y.i; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/Wnarrowing22.C b/gcc/testsuite/g++.dg/cpp0x/Wnarrowing22.C new file mode 100644 index 00000000000..dd30451a7cc --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/Wnarrowing22.C @@ -0,0 +1,49 @@ +// DR 2627 - Bit-fields and narrowing conversions +// PR c++/94058 +// { dg-do compile { target c++11 } } +// { dg-options "-Wno-error=narrowing" } + +using int64_t = __INT64_TYPE__; +using int32_t = __INT32_TYPE__; + +struct A { + int64_t i1 : __CHAR_BIT__; + int64_t i2 : sizeof (int32_t) * __CHAR_BIT__ - 1; + int64_t i3 : sizeof (int32_t) * __CHAR_BIT__; + int64_t i4 : sizeof (int32_t) * __CHAR_BIT__ + 1; + int64_t i5 : sizeof (int64_t) * __CHAR_BIT__ - 1; + int64_t i6 : sizeof (int64_t) * __CHAR_BIT__; +} a; + +int32_t i1{a.i1}; +int32_t i2{a.i2}; +int32_t i3{a.i3}; +int32_t i4{a.i4}; // { dg-warning "narrowing conversion" } +int32_t i5{a.i5}; // { dg-warning "narrowing conversion" } +int32_t i6{a.i6}; // { dg-warning "narrowing conversion" } + +struct B { + bool b1 : sizeof (bool) * __CHAR_BIT__; + bool b2 : sizeof (bool); +} b; + +signed char b1{b.b1}; +signed char b2{b.b2}; + +enum E : int64_t { E1 }; + +struct C { + E e1 : __CHAR_BIT__; + E e2 : sizeof (int32_t) * __CHAR_BIT__ - 1; + E e3 : sizeof (int32_t) * __CHAR_BIT__; + E e4 : sizeof (int32_t) * __CHAR_BIT__ + 1; + E e5 : sizeof (int64_t) * __CHAR_BIT__ - 1; + E e6 : sizeof (int64_t) * __CHAR_BIT__; +} c; + +int32_t e1{c.e1}; +int32_t e2{c.e2}; +int32_t e3{c.e3}; +int32_t e4{c.e4}; // { dg-warning "narrowing conversion" } +int32_t e5{c.e5}; // { dg-warning "narrowing conversion" } +int32_t e6{c.e6}; // { dg-warning "narrowing conversion" } diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-narrowing1.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-narrowing1.C new file mode 100644 index 00000000000..7769f950bed --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-narrowing1.C @@ -0,0 +1,34 @@ +// PR c++/94058 +// { dg-do compile { target c++20 } } + +namespace std { +struct strong_ordering { + int _v; + constexpr strong_ordering (int v) :_v(v) {} + constexpr operator int (void) const { return _v; } + static const strong_ordering less; + static const strong_ordering equal; + static const strong_ordering greater; +}; +constexpr strong_ordering strong_ordering::less = -1; +constexpr strong_ordering strong_ordering::equal = 0; +constexpr strong_ordering strong_ordering::greater = 1; +} + +struct A { + long i : 48; + auto operator <=> (const A&) const = default; +}; + +struct B { + long i : 8; + auto operator <=> (const B&) const = default; +}; + +void +f (B b) +{ + (void) int{b.i}; // Not narrowing anymore + b.i <=> b.i; // Not narrowing anymore + b <=> b; // Not deleted anymore +} diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-narrowing2.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-narrowing2.C new file mode 100644 index 00000000000..cfecce69405 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-narrowing2.C @@ -0,0 +1,26 @@ +// PR c++/104392 +// { dg-do compile { target c++20 } } + +namespace std { +struct strong_ordering { + int _v; + constexpr strong_ordering (int v) :_v(v) {} + constexpr operator int (void) const { return _v; } + static const strong_ordering less; + static const strong_ordering equal; + static const strong_ordering greater; +}; +constexpr strong_ordering strong_ordering::less = -1; +constexpr strong_ordering strong_ordering::equal = 0; +constexpr strong_ordering strong_ordering::greater = 1; +} + +struct A { + unsigned int a:5; +}; + +constexpr std::strong_ordering +operator<=>(const A & left, const A & right) +{ + return left.a <=> right.a; +}