From patchwork Thu Mar 16 13:02:32 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 739815 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.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3vkTD36THgz9rxm for ; Fri, 17 Mar 2017 00:02:55 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="EZLsECK5"; dkim-atps=neutral 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:cc:subject:message-id:mime-version:content-type; q=dns; s=default; b=FoMNhUp6j1tdC4HXkAkERB1VWjv4OLMHB/uT3ocestOuYIq7f+ 6vPISLl1Qy2IyYPqzPTXmqnqxUE1kALTB4O9A6fbhDmcGnznAVr+M3JNVPtxImtw TMUQK4TpuRgmRYqM07hfmX8/WHeJ/BBC8HOE5wYsNdFgbUmQfCR969qmQ= 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:cc:subject:message-id:mime-version:content-type; s= default; bh=M9OTAdjM2YWASR7ztVPs6xcy3LM=; b=EZLsECK5ryO+rRIS1bWw o/SW0hjjscnwZGdilRVjvbgtQBKvQzgxfgeWr//+NgINNRLyQFLpkfB6QcIUba8s 5zgPsEVvjHO9m5wmnJ+/58q+m7O4Jou9MJq9HpVAU2v6lp/9fX/mt+wPBegMlQz8 t7q5xIOMSe3ymHTVR7d7aQ0= Received: (qmail 54744 invoked by alias); 16 Mar 2017 13:02:46 -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 54715 invoked by uid 89); 16 Mar 2017 13:02:44 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No 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, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=3138 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 16 Mar 2017 13:02:33 +0000 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 640D0C0099E1; Thu, 16 Mar 2017 13:02:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 640D0C0099E1 Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=jwakely@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 640D0C0099E1 Received: from localhost (unknown [10.33.36.22]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0FE2B18862; Thu, 16 Mar 2017 13:02:33 +0000 (UTC) Date: Thu, 16 Mar 2017 13:02:32 +0000 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Cc: Richard Biener Subject: RFC: PR libstdc++/80064 make heap algorithms work with function types Message-ID: <20170316130232.GA2682@redhat.com> MIME-Version: 1.0 Content-Disposition: inline X-Clacks-Overhead: GNU Terry Pratchett User-Agent: Mutt/1.8.0 (2017-02-23) Richi reported a GCC 7 regression for a testcase from Cython that boils down to: void test01(int* first, int* last) { extern bool cmp(int, int); // PR libstdc++/80064 // This is undefined, because [alg.sorting] requires the template argument // Compare to be a function object type, and bool(int, int) is not an // object type. We previously accepted it by accident, so keep doing so. std::make_heap(first, last, cmp); } I can restore support for this with the attached patch (changing the heap algos to use the decayed type of the cmp parameter instead of the original _Compare template argument type), but should we support it? Is this worth fixing, or should we just say it worked by accident before and the user code needs to be fixed? FWIW MSVC accepts the example, libc++ rejects it for similar reasons to GCC 7. PR libstdc++/80064 * include/bits/stl_heap.h (__is_heap, push_heap, __adjust_heap) (pop_heap, make_heap, sort_heap, is_heap_until, is_heap): Cope with invalid instantiations using function types for _Compare argument. * testsuite/25_algorithms/make_heap/80064.cc: New test. commit 873ca61fbfbd5b3a84d1f9c36cd09e8a5c54fbf5 Author: Jonathan Wakely Date: Thu Mar 16 12:24:42 2017 +0000 PR libstdc++/80064 make heap algorithms work with function types PR libstdc++/80064 * include/bits/stl_heap.h (__is_heap, push_heap, __adjust_heap) (pop_heap, make_heap, sort_heap, is_heap_until, is_heap): Cope with invalid instantiations using function types for _Compare argument. * testsuite/25_algorithms/make_heap/80064.cc: New test. diff --git a/libstdc++-v3/include/bits/stl_heap.h b/libstdc++-v3/include/bits/stl_heap.h index 3c102f1..f8cd0c0 100644 --- a/libstdc++-v3/include/bits/stl_heap.h +++ b/libstdc++-v3/include/bits/stl_heap.h @@ -100,7 +100,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline bool __is_heap(_RandomAccessIterator __first, _Compare __comp, _Distance __n) { - __gnu_cxx::__ops::_Iter_comp_iter<_Compare> __cmp(_GLIBCXX_MOVE(__comp)); + typedef __decltype(__comp) _Cmp; + __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp)); return std::__is_heap_until(__first, __n, __cmp) == __n; } @@ -313,8 +314,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__last - __first > 1) { - using __gnu_cxx::__ops::_Iter_comp_iter; - _Iter_comp_iter<_Compare> __cmp(_GLIBCXX_MOVE(__comp)); + typedef __decltype(__comp) _Cmp; + __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp)); --__last; std::__pop_heap(__first, __last, __last, __cmp); } @@ -391,7 +392,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive_pred(__first, __last, __comp); - __gnu_cxx::__ops::_Iter_comp_iter<_Compare> __cmp(_GLIBCXX_MOVE(__comp)); + typedef __decltype(__comp) _Cmp; + __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp)); std::__make_heap(__first, __last, __cmp); } @@ -454,7 +456,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_irreflexive_pred(__first, __last, __comp); __glibcxx_requires_heap_pred(__first, __last, __comp); - __gnu_cxx::__ops::_Iter_comp_iter<_Compare> __cmp(_GLIBCXX_MOVE(__comp)); + typedef __decltype(__comp) _Cmp; + __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp)); std::__sort_heap(__first, __last, __cmp); } @@ -508,7 +511,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive_pred(__first, __last, __comp); - __gnu_cxx::__ops::_Iter_comp_iter<_Compare> __cmp(_GLIBCXX_MOVE(__comp)); + typedef __decltype(__comp) _Cmp; + __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp)); return __first + std::__is_heap_until(__first, std::distance(__first, __last), __cmp); } @@ -545,7 +549,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_irreflexive_pred(__first, __last, __comp); const auto __dist = std::distance(__first, __last); - __gnu_cxx::__ops::_Iter_comp_iter<_Compare> __cmp(_GLIBCXX_MOVE(__comp)); + typedef __decltype(__comp) _Cmp; + __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp)); return std::__is_heap_until(__first, __dist, __cmp) == __dist; } #endif diff --git a/libstdc++-v3/testsuite/25_algorithms/make_heap/80064.cc b/libstdc++-v3/testsuite/25_algorithms/make_heap/80064.cc new file mode 100644 index 0000000..eedcc32 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/make_heap/80064.cc @@ -0,0 +1,31 @@ +// Copyright (C) 2017 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 compile } + +#include + +void +test01(int* first, int* last) +{ + extern bool cmp(int, int); + // PR libstdc++/80064 + // This is undefined, because [alg.sorting] requires the template argument + // Compare to be a function object type, and bool(int, int) is not an + // object type. We previously accepted it by accident, so keep doing so. + std::make_heap(first, last, cmp); +}