From patchwork Mon Jul 30 17:26:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 951244 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-482672-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="rHz3/udL"; 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 41fRLt2y3Wz9s0R for ; Tue, 31 Jul 2018 03:26:29 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=bWIRfd8K8teV+OM86aeqIcfMZc6HgbTX+Bnc4cRNi/w3JxtxZdQ/S sb+s/pXKoMD28l6UlkIuXC9UD3qG/hOHrYFGHFRtFlXxV43HcKoaQAoOi+iccxAp WHPkM7dRsGnR/UkGbVLRBuCKkvG6M8UFMrzKwTLJREsyPJ0GyQIFOI= 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:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=XR/eEpMm/OprzQ3mijAeYJGga2M=; b=rHz3/udL3tZNBqM4HWer wRaqN8mR1+OBYzio2mT2UAyzHFIUZtdzflRGPMxKYZYZm2mlnRLCQFp45nZYe5Ig DywDCGPKe+vqVbCk03w3jY21MHWt0vDe2EtSVehI4dnFx3fXzMlzphALHvw+AspR 5c5On/bHBqp9DtmnA8QQOKA= Received: (qmail 87356 invoked by alias); 30 Jul 2018 17:26:14 -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 87337 invoked by uid 89); 30 Jul 2018 17:26:14 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, KAM_SHORT, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=NB, nb X-HELO: mx1.redhat.com Received: from mx3-rdu2.redhat.com (HELO mx1.redhat.com) (66.187.233.73) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 30 Jul 2018 17:26:12 +0000 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C6F368197006; Mon, 30 Jul 2018 17:26:10 +0000 (UTC) Received: from localhost (unknown [10.33.36.95]) by smtp.corp.redhat.com (Postfix) with ESMTP id 82D6020389E0; Mon, 30 Jul 2018 17:26:10 +0000 (UTC) Date: Mon, 30 Jul 2018 18:26:09 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [PATCH] PR libstdc++/86734 make reverse_iterator::operator-> more robust Message-ID: <20180730172609.GA23718@redhat.com> MIME-Version: 1.0 Content-Disposition: inline X-Clacks-Overhead: GNU Terry Pratchett User-Agent: Mutt/1.9.2 (2017-12-15) Implement the proposed resolution from LWG 1052, which also resolves DR 2118 by avoiding taking the address in the first place. PR libstdc++/86734 * include/bits/stl_iterator.h (reverse_iterator::operator->): Call _S_to_pointer (LWG 1052, LWG 2118). (reverse_iterator::_S_to_pointer): Define overloaded helper functions. * testsuite/24_iterators/reverse_iterator/dr1052.cc: New test. * testsuite/24_iterators/reverse_iterator/dr2188.cc: New test. Tested powerpc64le-linux, committed to trunk. commit 7e221535ac8ad07732c1ce019dd2c8c889a95dce Author: Jonathan Wakely Date: Mon Jul 30 15:14:11 2018 +0100 PR libstdc++/86734 make reverse_iterator::operator-> more robust Implement the proposed resolution from LWG 1052, which also resolves DR 2118 by avoiding taking the address in the first place. PR libstdc++/86734 * include/bits/stl_iterator.h (reverse_iterator::operator->): Call _S_to_pointer (LWG 1052, LWG 2118). (reverse_iterator::_S_to_pointer): Define overloaded helper functions. * testsuite/24_iterators/reverse_iterator/dr1052.cc: New test. * testsuite/24_iterators/reverse_iterator/dr2188.cc: New test. diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 0d5f20bc2c6..8562f879c16 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -122,6 +122,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ // _GLIBCXX_RESOLVE_LIB_DEFECTS // 235 No specification of default ctor for reverse_iterator + // 1012. reverse_iterator default ctor should value initialize _GLIBCXX17_CONSTEXPR reverse_iterator() : current() { } @@ -182,7 +183,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ _GLIBCXX17_CONSTEXPR pointer operator->() const - { return &(operator*()); } + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 1052. operator-> should also support smart pointers + _Iterator __tmp = current; + --__tmp; + return _S_to_pointer(__tmp); + } /** * @return @c *this @@ -286,6 +293,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX17_CONSTEXPR reference operator[](difference_type __n) const { return *(*this + __n); } + + private: + template + static _GLIBCXX17_CONSTEXPR _Tp* + _S_to_pointer(_Tp* __p) + { return __p; } + + template + static _GLIBCXX17_CONSTEXPR pointer + _S_to_pointer(_Tp __t) + { return __t.operator->(); } }; //@{ diff --git a/libstdc++-v3/testsuite/24_iterators/reverse_iterator/dr1052.cc b/libstdc++-v3/testsuite/24_iterators/reverse_iterator/dr1052.cc new file mode 100644 index 00000000000..2704010a083 --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/reverse_iterator/dr1052.cc @@ -0,0 +1,82 @@ +// Copyright (C) 2018 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do run { target c++11 } } + +// PR libstdc++/86734 +// LWG 1052. reverse_iterator::operator-> should also support smart pointers +// LWG 2775. reverse_iterator is does not compile for fancy pointers + +#include +#include + +void +test01() +{ + // Example 1 from LWG 1052 + + struct X { int m; }; + + static X x; + + struct IterX { + typedef std::bidirectional_iterator_tag iterator_category; + typedef X& reference; + struct pointer + { + pointer(X& v) : value(v) {} + X& value; + X* operator->() const {return &value;} + }; + typedef std::ptrdiff_t difference_type; + typedef X value_type; + // additional iterator requirements not important for this issue + + reference operator*() const { return x; } + pointer operator->() const { return pointer(x); } + IterX& operator--() {return *this;} + + }; + + std::reverse_iterator ix; + VERIFY( &ix->m == &(*ix).m ); +} + +void +test02() +{ + // Example 2 from LWG 1052 + + struct P { + P() : first(10), second(20.0) { } + int first; + double second; + }; + P op; + std::reverse_iterator ri(&op + 1); + VERIFY( ri->first == 10 ); +} + +// N.B. Example 3 from LWG 1052 isn't expected to work, +// because a caching iterator like IterX is not a forward iterator. + +int +main() +{ + test01(); + test02(); +} diff --git a/libstdc++-v3/testsuite/24_iterators/reverse_iterator/dr2188.cc b/libstdc++-v3/testsuite/24_iterators/reverse_iterator/dr2188.cc new file mode 100644 index 00000000000..047334ddf24 --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/reverse_iterator/dr2188.cc @@ -0,0 +1,47 @@ +// Copyright (C) 2018 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do run { target c++11 } } + +// PR libstdc++/86734 + +#include +#include + +void +test01() +{ + // LWG DR 2188 + // Reverse iterator does not fully support targets that overload operator& + struct X { + int val; + int* operator&() { return &val; } + const int* operator&() const { return &val; } + }; + + X x[2] = { {1}, {2} }; + std::reverse_iterator rev(x+2); + VERIFY( rev->val == 2 ); + ++rev; + VERIFY( rev->val == 1 ); +} + +int +main() +{ + test01(); +}