From owner-freebsd-arch@freebsd.org Sat Feb 13 13:21:41 2016 Return-Path: Delivered-To: freebsd-arch@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 64C8AAA7805 for ; Sat, 13 Feb 2016 13:21:41 +0000 (UTC) (envelope-from ed@nuxi.nl) Received: from mailman.ysv.freebsd.org (mailman.ysv.freebsd.org [IPv6:2001:1900:2254:206a::50:5]) by mx1.freebsd.org (Postfix) with ESMTP id 49C2E1E13 for ; Sat, 13 Feb 2016 13:21:41 +0000 (UTC) (envelope-from ed@nuxi.nl) Received: by mailman.ysv.freebsd.org (Postfix) id 4773AAA7804; Sat, 13 Feb 2016 13:21:41 +0000 (UTC) Delivered-To: arch@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2E241AA7802 for ; Sat, 13 Feb 2016 13:21:41 +0000 (UTC) (envelope-from ed@nuxi.nl) Received: from mail-yk0-x231.google.com (mail-yk0-x231.google.com [IPv6:2607:f8b0:4002:c07::231]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id EFDFC1E12 for ; Sat, 13 Feb 2016 13:21:40 +0000 (UTC) (envelope-from ed@nuxi.nl) Received: by mail-yk0-x231.google.com with SMTP id z13so44660296ykd.0 for ; Sat, 13 Feb 2016 05:21:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nuxi-nl.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=DM6qrHkMLMSY/bHjaFfY8CJmwa5TUBhW462BcWjed8M=; b=l8ZwwpBHoTtt3aR+n7xIzzuWVzD2faEp0f7vnzE/RzH7NeuU2Z7KBfLB/wjNpH9wHd mFWr0AICqZAtqbO2Q8mP+fpu1wvA8Nl1YVCO3Q0Nn32jz++XxmhbLy/UkqtvoXe84zQg f0fsziAhiYi4XfuYz8PZbFRpLEHqMfccxinRyIbS0QTMbn8F4NuePP2l/o3+04SmoQz2 os0mr+VqLSPiYY3LUp0Sev9bwoJSVWQlQeNp+o9Pk94jjdwmvEhhDeuYvKftWydFiujO 3EbJuPgv5VWMRjoFxSNKH7jo+KqvNGfOrAujVw9ynFngu1Si+qqardYr0mOahT8rOvLR 8MBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=DM6qrHkMLMSY/bHjaFfY8CJmwa5TUBhW462BcWjed8M=; b=JDCG++jmqHPgACg/gvihJ33YhvmJDYengzgiWL8cerMuI2mOCpzwJeTpHVS16h/RjK 33J7BDdFfKLeqVCTJF0LqD433U7U2qdvqFBRUjKuRKgsbKRWQy0bs1xZoBcAG0pXEbg0 khgO+/AWAuktSM0i+NGflDgqWyeJKalmhBCNYNm9iHNjOLPIEqyfXRCLdSWI90wZM4eF di2Nl+lpjLdjDGkAxiT7D7xg2/Iv1pTnoqATsAPvcWWukAkkgf395vKxBfIyQHVi3Hn7 EfgawuAbFAcc+xVTr3Xjb5wcfCHjJBsW0Yxau1knWGIAAQ5jb6f6rE7LbjBFZ7Ofajzt qpeg== X-Gm-Message-State: AG10YOTUzAx/RYKOdEzViuSrgfI9RJ47weCxr3Er1RYDArk77vp6U+JRRDNMS5tkSAW0XnDbFG9E5GKSUbNQGA== MIME-Version: 1.0 X-Received: by 10.37.81.137 with SMTP id f131mr3962636ybb.54.1455369699470; Sat, 13 Feb 2016 05:21:39 -0800 (PST) Received: by 10.129.148.6 with HTTP; Sat, 13 Feb 2016 05:21:39 -0800 (PST) In-Reply-To: References: Date: Sat, 13 Feb 2016 14:21:39 +0100 Message-ID: Subject: Re: OpenBSD mallocarray From: Ed Schouten To: C Turt Cc: arch@freebsd.org Content-Type: text/plain; charset=UTF-8 X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 13 Feb 2016 13:21:41 -0000 Hi there, 2016-02-01 20:57 GMT+01:00 C Turt : > if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && > nmemb > 0 && SIZE_MAX / nmemb < size) { In my opinion functions like these are good additions, as long as we make sure that we stop importing garbage expressions like the one above. It's already bad enough that we copy-pasted this gobbledygook into fread(), fwrite(), calloc(), reallocarray(), etc. Both the latest versions of Clang and GCC support the following builtins: bool __builtin_add_overflow(type1 a, type2 b, type3 *res); bool __builtin_sub_overflow(type1 a, type2 b, type3 *res); bool __builtin_mul_overflow(type1 a, type2 b, type3 *res); These functions perform addition, subtraction and multiplication, returning whether overflow has occurred in the process. This is a lot more efficient (and readable) than the expression above, as it simply uses the CPU's mul instruction, followed by a jump-on-overflow. GCC 4.2.1 doesn't support these builtins, but they can easily be emulated by using static inline functions that use the code above. If we want them to be type generic, we can use 's __generic(), which either expands to C11's _Generic() or falls back to GCC's __builtin_types_compatible_p()/__builtin_choose_expr(). I'd say it would make a lot of sense to add a new header file, e.g. , that adds compiler-independent wrappers for these builtins: #if recent version of GCC/Clang #define add_overflow(a, b, res) __builtin_add_overflow(a, b, res) #else #define add_overflow(a, b, res) (__generic(*(res), unsigned int, ..., ...)(a, b, res)) #endif -- Ed Schouten Nuxi, 's-Hertogenbosch, the Netherlands KvK-nr.: 62051717