From patchwork Wed Jan 22 00:36:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Oliva X-Patchwork-Id: 1226843 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-517949-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=adacore.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha1 header.s=default header.b=PVsHkYjm; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 482RLH2MDMz9sRG for ; Wed, 22 Jan 2020 11:36:53 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version:content-type; q=dns; s=default; b=ij+s8JZ+cqhpfp0MJcumZqx2jeIP9gdBCwtknYrfhL6DRGLH1g zvjYtQ8XsnPsrdxlH8Kxf+7WsN7EYXNU89ICq/oCJy8gsjndPe2J6MZmKsX6MxJ/ aIIDrFIBtLTZjEGL5yiuKBNKZCdgpYyRIGfMlGHQNdHAhQ/+UJGtvjofQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version:content-type; s= default; bh=2XCc3G8x7yRwE8gx7F6dOujHzXw=; b=PVsHkYjmArLFwk0FKg26 w9HTIWw3TjJ28Xhc6vONK+m4TEkMrpmTYTQlwuLifjC9gNuAQznMzAc3w0ddhFAW BlhDs5eCccnEsEM/qrymfELMhWOzSJMKGveEq0XnC3sqGfiUZBkYJB808pou38qC NJLULrx2ZOoj00T0BB8UoTc= Received: (qmail 75320 invoked by alias); 22 Jan 2020 00:36:44 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 75299 invoked by uid 89); 22 Jan 2020 00:36:43 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=Evangelist, evangelist, blogs, him X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 22 Jan 2020 00:36:42 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id BD23011631A; Tue, 21 Jan 2020 19:36:40 -0500 (EST) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id PzypcArmAnQs; Tue, 21 Jan 2020 19:36:40 -0500 (EST) Received: from free.home (tron.gnat.com [IPv6:2620:20:4000:0:46a8:42ff:fe0e:e294]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by rock.gnat.com (Postfix) with ESMTPS id 7F25A116315; Tue, 21 Jan 2020 19:36:40 -0500 (EST) Received: from livre.home (livre.home [172.31.160.2]) by free.home (8.15.2/8.15.2) with ESMTPS id 00M0aS3D1646144 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 21 Jan 2020 21:36:29 -0300 From: Alexandre Oliva To: gcc-patches@gcc.gnu.org Cc: libstdc++@gcc.gnu.org Subject: tolerate padding in mbstate_t Date: Tue, 21 Jan 2020 21:36:28 -0300 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Padding in mbstate_t objects may get the memcmp to fail. Attempt to avoid the failure with zero initialization. Regstrapped on x86_64-linux-gnu, and also tested on a platform that used to fail because of padding in std::mbstate_t. Ok to install? for libstdc++-v3/ChangeLog * testsuite/27_io/fpos/mbstate_t/1.cc: Zero-init mbstate_t. --- testsuite/27_io/fpos/mbstate_t/1.cc | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git libstdc++-v3/testsuite/27_io/fpos/mbstate_t/1.cc libstdc++-v3/testsuite/27_io/fpos/mbstate_t/1.cc index f92d68f..559bd8d 100644 --- libstdc++-v3/testsuite/27_io/fpos/mbstate_t/1.cc +++ libstdc++-v3/testsuite/27_io/fpos/mbstate_t/1.cc @@ -28,8 +28,24 @@ void test01() { typedef std::mbstate_t state_type; - state_type state01 = state_type(); - state_type state02 = state_type(); + // Use zero-initialization of the underlying memory so that padding + // bytes, if any, stand a better chance of comparing the same. + // Zero-initialized memory is guaranteed to be a valid initial + // state. This doesn't quite guarantee that any padding bits won't + // be overwritten when copying from other instances that haven't + // been fully initialized: this data type is compatible with C, so + // it is likely plain old data, but it could have a default ctor + // that initializes only the relevant fields, whereas copy-ctor and + // operator= could be implemented as a full-object memcpy, including + // padding bits, rather than fieldwise copying. However, since + // we're comparing two values copied from the same state_type + // instance (or was this meant to take one of them from pos02 rather + // than both from pos01?), if padding bits are copied, we'll get the + // same for both of them, and if they aren't, we'll keep the values + // we initialized them with, so this should be good. + state_type state[2]; + std::memset(state, 0, sizeof (state)); + std::streampos pos01(0); std::streampos pos02(0); @@ -39,13 +55,13 @@ void test01() // state_type state(); // XXX Need to have better sanity checking for the mbstate_t type, - // or whatever the insantiating type for class fpos happens to be + // or whatever the instantiating type for class fpos happens to be // for streampos, as things like equality operators and assignment // operators, increment and deincrement operators need to be in // place. - pos01.state(state02); - state01 = pos01.state(); - VERIFY( std::memcmp(&state01, &state02, sizeof(state_type)) == 0 ); + pos01.state(state[1]); + state[0] = pos01.state(); + VERIFY( std::memcmp(&state[0], &state[1], sizeof(state_type)) == 0 ); } int main()