From patchwork Thu May 23 15:51:41 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Pluzhnikov X-Patchwork-Id: 245973 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 25F6D2C016A for ; Fri, 24 May 2013 01:51:51 +1000 (EST) 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=EHPMw7bqibrN0HjwpZmYLabiLoLGIfNycT3lGTX1cT8lAdDvpo tvrtmQET3Hf/c4/Snl+M/f87dmjthBQe9DtM8pq3ZPhy1kyEieKPY5U7ZI3QQeQL GHvMtOXv3lz6TX7tbzB3hPMd4gO2uBmZ3BSUWpMSIe2E/MpMapxC2rsQs= 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=zrZ1TTMND3f4FVS2vFC3cqieydo=; b=wT3I9dLTuMJb7Hu5EUZi 9HnBmTcS3fBT2QWSFZTDRpwichRWQKH6V3oSxiE2Be0nvobhLObZcarr3ik5B+Dy I47TfXYRU1lwMwCIXEYPXkq9Un5QApq/wPCTnMtPk1IV79P8dTDWZuOtwDaCm+la msAtl8ZRbi6bRy2sdI1tvj4= Received: (qmail 18034 invoked by alias); 23 May 2013 15:51:45 -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 18018 invoked by uid 89); 23 May 2013 15:51:44 -0000 X-Spam-SWARE-Status: No, score=-4.0 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.1 Received: from mail-gg0-f201.google.com (HELO mail-gg0-f201.google.com) (209.85.161.201) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Thu, 23 May 2013 15:51:43 +0000 Received: by mail-gg0-f201.google.com with SMTP id f4so381412ggn.0 for ; Thu, 23 May 2013 08:51:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:mime-version:content-type :x-gm-message-state; bh=DseK85AG0zi2qf2mWUMiiS6kqv4nA1d6vGDvB16zSGg=; b=GwuHftNwxNkcd23MKAlcyTxLRFS9jLlApzhSYpAhgd6PVUk8/Ry1OpNGsfcBrhTRX1 2EcvNlRUi1VnFZui/dC5mvb9Dr73xIr5T/6hOJWAVrUIhziaAW+ZFBXNI3GM1p6S+9dr 2QHRi8BVVJqK58mcKJ5GolYnPFbAgaFeEuY9OWLyJ6rQ/j5V9zki80SGOXpZBc0JnlwR cIoEdN1VF5O0h8TSNjmTwt8lK97zM7vNUsPip2NOdtqt6peCr8l3v7F9VLPu2GIOCxXC ixO96i6hh3MNS4qbqg9rQG53tX4w7QB8KlacQVH3nhHpWQHDwT2O+3aB3PBJGkO05K4v 13jQ== X-Received: by 10.236.170.36 with SMTP id o24mr6805117yhl.2.1369324302093; Thu, 23 May 2013 08:51:42 -0700 (PDT) Received: from corp2gmr1-2.hot.corp.google.com (corp2gmr1-2.hot.corp.google.com [172.24.189.93]) by gmr-mx.google.com with ESMTPS id s48si1065641yhe.6.2013.05.23.08.51.42 for (version=TLSv1.1 cipher=AES128-SHA bits=128/128); Thu, 23 May 2013 08:51:42 -0700 (PDT) Received: from elbrus2.mtv.corp.google.com (elbrus2.mtv.corp.google.com [172.17.128.95]) by corp2gmr1-2.hot.corp.google.com (Postfix) with ESMTP id D990B5A405D; Thu, 23 May 2013 08:51:41 -0700 (PDT) Received: by elbrus2.mtv.corp.google.com (Postfix, from userid 74925) id 7025F1C05DB; Thu, 23 May 2013 08:51:41 -0700 (PDT) From: Paul Pluzhnikov To: dnovillo@google.com Cc: gcc-patches@gcc.gnu.org, ppluzhnikov@google.com, libstdc@gcc.gnu.org Subject: [google gcc-4_7, gcc-4_8, integration] Add bounds checks to vector Date: Thu, 23 May 2013 08:51:41 -0700 Message-ID: MIME-Version: 1.0 X-Gm-Message-State: ALoCoQkj2WL/M+Awxaj/02jP/0zVLdO8qTWHgREBAVw+PumYFriEf2JM7POXhGj/ed4XMTnLDfF4tMlSDkee+x8gnTrxgf/3bgcmAEVpxJLn0g3QzXV4YTvOlZvddYoTRMoE2LAPhSMJNJ5pkENuEPA/YigjjGtwNp52xWkYhHZL7CAZUJWwPIYL/7YMLfdUyj9SA6GKE0FhntU/2SlsOrRVUYfiR/Y/Rh1tW7vAz7jjnqpfEBbjWeo= Greetings, This patch adds (relatively) cheap bounds and dangling checks to vector, similar to the checks I added to vector in r195373, r195356, etc. Ok for google branches (gcc-4_7, gcc-4_8, integration) ? Thanks, Index: libstdc++-v3/include/bits/stl_bvector.h =================================================================== --- libstdc++-v3/include/bits/stl_bvector.h (revision 199261) +++ libstdc++-v3/include/bits/stl_bvector.h (working copy) @@ -438,11 +438,31 @@ #endif ~_Bvector_base() - { this->_M_deallocate(); } + { + this->_M_deallocate(); +#if __google_stl_debug_bvector + __builtin_memset(this, 0xcd, sizeof(*this)); +#endif + } protected: _Bvector_impl _M_impl; +#if __google_stl_debug_bvector + bool _M_is_valid() const + { + return (this->_M_impl._M_start._M_p == 0 + && this->_M_impl._M_finish._M_p == 0 + && this->_M_impl._M_end_of_storage == 0) + || (this->_M_impl._M_start._M_p <= this->_M_impl._M_finish._M_p + && this->_M_impl._M_finish._M_p <= this->_M_impl._M_end_of_storage + && (this->_M_impl._M_start._M_p < this->_M_impl._M_end_of_storage + || (this->_M_impl._M_start._M_p == this->_M_impl._M_end_of_storage + && this->_M_impl._M_start._M_offset == 0 + && this->_M_impl._M_finish._M_offset == 0))); + } +#endif + _Bit_type* _M_allocate(size_t __n) { return _M_impl.allocate(_S_nword(__n)); } @@ -571,6 +591,10 @@ vector& operator=(const vector& __x) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("op=() on corrupt (dangling?) vector"); +#endif if (&__x == this) return *this; if (__x.size() > capacity()) @@ -587,6 +611,10 @@ vector& operator=(vector&& __x) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("op=() on corrupt (dangling?) vector"); +#endif // NB: DR 1204. // NB: DR 675. this->clear(); @@ -608,12 +636,22 @@ // or not the type is an integer. void assign(size_type __n, const bool& __x) - { _M_fill_assign(__n, __x); } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("assign on corrupt (dangling?) vector"); +#endif + _M_fill_assign(__n, __x); + } template void assign(_InputIterator __first, _InputIterator __last) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("assign() on corrupt (dangling?) vector"); +#endif typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_assign_dispatch(__first, __last, _Integral()); } @@ -626,19 +664,43 @@ iterator begin() _GLIBCXX_NOEXCEPT - { return this->_M_impl._M_start; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("begin() on corrupt (dangling?) vector"); +#endif + return this->_M_impl._M_start; + } const_iterator begin() const _GLIBCXX_NOEXCEPT - { return this->_M_impl._M_start; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("begin() on corrupt (dangling?) vector"); +#endif + return this->_M_impl._M_start; + } iterator end() _GLIBCXX_NOEXCEPT - { return this->_M_impl._M_finish; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("end() on corrupt (dangling?) vector"); +#endif + return this->_M_impl._M_finish; + } const_iterator end() const _GLIBCXX_NOEXCEPT - { return this->_M_impl._M_finish; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("end() on corrupt (dangling?) vector"); +#endif + return this->_M_impl._M_finish; + } reverse_iterator rbegin() _GLIBCXX_NOEXCEPT @@ -659,11 +721,23 @@ #ifdef __GXX_EXPERIMENTAL_CXX0X__ const_iterator cbegin() const noexcept - { return this->_M_impl._M_start; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("cbegin() on corrupt (dangling?) vector"); +#endif + return this->_M_impl._M_start; + } const_iterator cend() const noexcept - { return this->_M_impl._M_finish; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("cend() on corrupt (dangling?) vector"); +#endif + return this->_M_impl._M_finish; + } const_reverse_iterator crbegin() const noexcept @@ -681,6 +755,10 @@ size_type max_size() const _GLIBCXX_NOEXCEPT { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("max_size() on corrupt (dangling?) vector"); +#endif const size_type __isize = __gnu_cxx::__numeric_traits::__max - int(_S_word_bit) + 1; @@ -701,6 +779,9 @@ reference operator[](size_type __n) { +#if __google_stl_debug_bvector + _M_range_check(__n); +#endif return *iterator(this->_M_impl._M_start._M_p + __n / int(_S_word_bit), __n % int(_S_word_bit)); } @@ -708,6 +789,9 @@ const_reference operator[](size_type __n) const { +#if __google_stl_debug_bvector + _M_range_check(__n); +#endif return *const_iterator(this->_M_impl._M_start._M_p + __n / int(_S_word_bit), __n % int(_S_word_bit)); } @@ -740,19 +824,39 @@ reference front() - { return *begin(); } + { +#if __google_stl_debug_bvector + _M_range_check(0); +#endif + return *begin(); + } const_reference front() const - { return *begin(); } + { +#if __google_stl_debug_bvector + _M_range_check(0); +#endif + return *begin(); + } reference back() - { return *(end() - 1); } + { +#if __google_stl_debug_bvector + _M_range_check(0); +#endif + return *(end() - 1); + } const_reference back() const - { return *(end() - 1); } + { +#if __google_stl_debug_bvector + _M_range_check(0); +#endif + return *(end() - 1); + } // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 464. Suggestion for new member functions in standard containers. @@ -765,6 +869,10 @@ void push_back(bool __x) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("push_back() on corrupt (dangling?) vector"); +#endif if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) *this->_M_impl._M_finish++ = __x; else @@ -774,6 +882,10 @@ void swap(vector& __x) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid() || !__x._M_is_valid()) + __throw_logic_error("swap() on corrupt (dangling?) vector"); +#endif std::swap(this->_M_impl._M_start, __x._M_impl._M_start); std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); std::swap(this->_M_impl._M_end_of_storage, @@ -811,26 +923,50 @@ insert(iterator __position, _InputIterator __first, _InputIterator __last) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("insert() on corrupt (dangling?) vector"); +#endif typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_insert_dispatch(__position, __first, __last, _Integral()); } void insert(iterator __position, size_type __n, const bool& __x) - { _M_fill_insert(__position, __n, __x); } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("insert() on corrupt (dangling?) vector"); +#endif + _M_fill_insert(__position, __n, __x); + } #ifdef __GXX_EXPERIMENTAL_CXX0X__ void insert(iterator __p, initializer_list __l) - { this->insert(__p, __l.begin(), __l.end()); } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("insert() on corrupt (dangling?) vector"); #endif + this->insert(__p, __l.begin(), __l.end()); + } +#endif void pop_back() - { --this->_M_impl._M_finish; } + { +#if __google_stl_debug_bvector + _M_range_check(0); +#endif + --this->_M_impl._M_finish; + } iterator erase(iterator __position) { +#if __google_stl_debug_bvector + _M_range_check(__position - begin()); +#endif if (__position + 1 != end()) std::copy(__position + 1, end(), __position); --this->_M_impl._M_finish; @@ -840,6 +976,10 @@ iterator erase(iterator __first, iterator __last) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("erase() on corrupt (dangling?) vector"); +#endif if (__first != __last) _M_erase_at_end(std::copy(__last, end(), __first)); return __first; @@ -857,12 +997,22 @@ #ifdef __GXX_EXPERIMENTAL_CXX0X__ void shrink_to_fit() - { _M_shrink_to_fit(); } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("shrink_to_fit() on corrupt (dangling?) vector"); #endif + _M_shrink_to_fit(); + } +#endif void flip() _GLIBCXX_NOEXCEPT { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("flip() on corrupt (dangling?) vector"); +#endif for (_Bit_type * __p = this->_M_impl._M_start._M_p; __p != this->_M_impl._M_end_of_storage; ++__p) *__p = ~*__p;