From patchwork Tue Aug 7 16:10:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 954571 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-483328-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="oazkbXR9"; 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 41lKJK46t1z9rxx for ; Wed, 8 Aug 2018 02:11:11 +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=UUgE7nuV/9WxNG3e760Gaq05DbvXTekQlwMppXFtInU0/1sZVrR9v j+jaF0EBPjVdFHqWN9vkBUmbUKm+oPZHhUaHIKCBAaELNluRtsvzHa51mmoOG7um gTJls0gL3es9TWEdrDsTpOSV3PdxNiVWkiEBuoYh+7qKwpXIuVNiQY= 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=l/TQG+ZtENNEKo6LbKjqgVT+vRg=; b=oazkbXR9MXKzCBEqkSYB 47Zctd/dOrh7GE2hsOa7sbq9ES2EPAVKIAptXPnmeBN525h0+pKKtI3uq+TpEat5 j3cNA8oK3r/vNMe3Pw+jsgA4atktZMPWzsn3CSJ728V3OxNqfRiajT2DBhbmMcgN 3sZDsUG3M8RQSmyW1UH35ao= Received: (qmail 78190 invoked by alias); 7 Aug 2018 16:10:56 -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 78170 invoked by uid 89); 7 Aug 2018 16:10:55 -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, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=Increase 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; Tue, 07 Aug 2018 16:10:54 +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 C20AD40241C0; Tue, 7 Aug 2018 16:10:52 +0000 (UTC) Received: from localhost (unknown [10.33.36.34]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7CEF9213ED6A; Tue, 7 Aug 2018 16:10:52 +0000 (UTC) Date: Tue, 7 Aug 2018 17:10:51 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [PATCH] PR libstdc++/86861 Meet precondition for Solaris memalign Message-ID: <20180807161051.GA25459@redhat.com> MIME-Version: 1.0 Content-Disposition: inline X-Clacks-Overhead: GNU Terry Pratchett User-Agent: Mutt/1.9.2 (2017-12-15) Solaris memalign requires alignment to be at least sizeof(int), so increase it as needed. Also move the check for valid alignments from the fallback implementation of aligned_alloc into operator new, as it's required for all of aligned_alloc, memalign, posix_memalign and __aligned_malloc. This adds a branch to check for undefined behaviour which we could just ignore, so the check could just be removed. It should certainly be removed if PR 86878 is implemented to issue a warning about calls with invalid alignments. PR libstdc++/86861 * libsupc++/new_opa.cc [_GLIBCXX_HAVE_MEMALIGN] (aligned_alloc): Replace macro with inline function. [__sun]: Increase alignment to meet memalign precondition. [!HAVE__ALIGNED_MALLOC && !HAVE_POSIX_MEMALIGN && !HAVE_MEMALIGN] (aligned_alloc): Move check for valid alignment to operator new. Remove redundant check for non-zero size, it's enforced by the caller. (operator new): Move check for valid alignment here. Use __builtin_expect on check for zero size. Tested powerpc64le-linux, committed to trunk. commit 926a15251b85d0b1a8b6bd08a138ad90ec9c83df Author: Jonathan Wakely Date: Mon Aug 6 15:43:43 2018 +0100 PR libstdc++/86861 Meet precondition for Solaris memalign Solaris memalign requires alignment to be at least sizeof(int), so increase it as needed. Also move the check for valid alignments from the fallback implementation of aligned_alloc into operator new, as it's required for all of aligned_alloc, memalign, posix_memalign and __aligned_malloc. This adds a branch to check for undefined behaviour which we could just ignore, so the check could just be removed. It should certainly be removed if PR 86878 is implemented to issue a warning about calls with invalid alignments. PR libstdc++/86861 * libsupc++/new_opa.cc [_GLIBCXX_HAVE_MEMALIGN] (aligned_alloc): Replace macro with inline function. [__sun]: Increase alignment to meet memalign precondition. [!HAVE__ALIGNED_MALLOC && !HAVE_POSIX_MEMALIGN && !HAVE_MEMALIGN] (aligned_alloc): Move check for valid alignment to operator new. Remove redundant check for non-zero size, it's enforced by the caller. (operator new): Move check for valid alignment here. Use __builtin_expect on check for zero size. diff --git a/libstdc++-v3/libsupc++/new_opa.cc b/libstdc++-v3/libsupc++/new_opa.cc index 7c4bb79cdab..5be0cc2ca65 100644 --- a/libstdc++-v3/libsupc++/new_opa.cc +++ b/libstdc++-v3/libsupc++/new_opa.cc @@ -39,6 +39,7 @@ static inline void* aligned_alloc (std::size_t al, std::size_t sz) { void *ptr; + // posix_memalign has additional requirement, not present on aligned_alloc: // The value of alignment shall be a power of two multiple of sizeof(void *). if (al < sizeof(void*)) al = sizeof(void*); @@ -53,20 +54,24 @@ aligned_alloc (std::size_t al, std::size_t sz) #else extern "C" void *memalign(std::size_t boundary, std::size_t size); #endif -#define aligned_alloc memalign -#else +static inline void* +aligned_alloc (std::size_t al, std::size_t sz) +{ +#ifdef __sun + // Solaris 10 memalign requires that alignment is greater than or equal to + // the size of a word. + if (al < sizeof(int)) + al = sizeof(int); +#endif + return memalign (al, sz); +} +#else // !HAVE__ALIGNED_MALLOC && !HAVE_POSIX_MEMALIGN && !HAVE_MEMALIGN #include // The C library doesn't provide any aligned allocation functions, define one. // This is a modified version of code from gcc/config/i386/gmm_malloc.h static inline void* aligned_alloc (std::size_t al, std::size_t sz) { - // Alignment must be a power of two. - if (al & (al - 1)) - return nullptr; - else if (!sz) - return nullptr; - // We need extra bytes to store the original value returned by malloc. if (al < sizeof(void*)) al = sizeof(void*); @@ -90,8 +95,13 @@ operator new (std::size_t sz, std::align_val_t al) void *p; std::size_t align = (std::size_t)al; + /* Alignment must be a power of two. */ + /* XXX This should be checked by the compiler (PR 86878). */ + if (__builtin_expect (align & (align - 1), false)) + _GLIBCXX_THROW_OR_ABORT(bad_alloc()); + /* malloc (0) is unpredictable; avoid it. */ - if (sz == 0) + if (__builtin_expect (sz == 0, false)) sz = 1; #if _GLIBCXX_HAVE_ALIGNED_ALLOC