Received: by 10.213.65.68 with SMTP id h4csp129105imn; Wed, 21 Mar 2018 14:12:31 -0700 (PDT) X-Google-Smtp-Source: AG47ELvxN+ftru1acbCmChfGh8UlIhCm/bH3TVVFnzvOOtNEAoMIR/BLr4UtiFlHyHj7tkY5BIBy X-Received: by 10.98.5.71 with SMTP id 68mr17934019pff.241.1521666751204; Wed, 21 Mar 2018 14:12:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521666751; cv=none; d=google.com; s=arc-20160816; b=Wc7z1/TVrEA20Ft2Bu6LISpGPkOq5+hTdA8wDPG2fVYvJAM9xk6gp6zE/B4BF6YLMn nqag5gIb/RgfEOkvZgPoC4PlBNizMNmwXYOYuR+qBEdXkFkraTDhke7BYPM1JCkapec5 k7lGLRYS7Ye7YWHzL5I4rPAW/XwnChYvpCqom2RgYxog/8t849iFgbFNVnXBGCW3cIJW O4bClkuRXi+ALpiOJit2vlut8ucoc+S6HIycSX9OD9b9BK5Q6b4Tw5CKRR7XAQ4UZuv1 8V82QdFmqWmVHrc5I+j+5gyN7Rr6g//INNsAvTs7MYMK3TMurRz7DNPTcVot71ep9w2O IJjQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:dkim-signature :arc-authentication-results; bh=UE569lbC4wgn6xUyNKxfmBm4ccmYjj6sA8ymqTG9IDI=; b=buA9gM3TvLAaU9tOw+vHXtystjozNuKxu8JgZknMoALAKjTT7qk2keGOzlYnstYxov anKty5sMLZBbtxPBBaLb6L8XnBBujC/sH26CxnrbbHO2nQvt7eB5OpC1QAOSYinX8Lmq q5Dpm2M0dDSioz3a2MMmyMxDhNfWldHTjrA/HGlDleQuEIjrSOwQPXfFQAJjMcb/nBe8 6KyCuxWydsh7qtIaHFl3J0Ma9YOasoMmEvrxiIp/pNiWKHoH/g82D9MiSZUPTrSpX7De KemratIkgcAltU2v64VCzNTeUNyCVFqK7VOELKJoe1M2kO3JYLepLk5FbuR4YtyDIs6J Yssg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@rasmusvillemoes.dk header.s=google header.b=MD187HgS; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a128si3696981pfb.286.2018.03.21.14.11.51; Wed, 21 Mar 2018 14:12:31 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@rasmusvillemoes.dk header.s=google header.b=MD187HgS; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753414AbeCUVKi (ORCPT + 99 others); Wed, 21 Mar 2018 17:10:38 -0400 Received: from mail-wm0-f46.google.com ([74.125.82.46]:35072 "EHLO mail-wm0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753210AbeCUVKf (ORCPT ); Wed, 21 Mar 2018 17:10:35 -0400 Received: by mail-wm0-f46.google.com with SMTP id r82so12439900wme.0 for ; Wed, 21 Mar 2018 14:10:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rasmusvillemoes.dk; s=google; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=UE569lbC4wgn6xUyNKxfmBm4ccmYjj6sA8ymqTG9IDI=; b=MD187HgStI6q9qz2rweUAP+P92VEwQI54FU8Uzirg0AG2/og9atmWnPqU3vfCxuPf7 mUbOKffG7/1mouTlxS9X6aPPv7s7UUwHSOnXPvwCmukT75GJOAy86fD2lGQN0GGq2oOR MbZciDlCy6UVRlypZNYiXsl7kfAPaJgpe/smc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=UE569lbC4wgn6xUyNKxfmBm4ccmYjj6sA8ymqTG9IDI=; b=DnI7Aiu6TQCsgFOG4KSv/ZGnbsAjJzo32h9qdobTkP5EvXuDQyl3tQSfx/vGonPnn+ 4UF4lF9e+kbY84s5CGdIujJhbGRCbdFNR2f8EkA+VC9LvSXMoTueFy/rK13IBdKTqOXb 9hnzcmtpoUFod/mAmMKRAVDK35W5fg/FlCKaScz3AAjIvZcc2/XWjaXsFEGEZsPXkZbA nbvgCvBlKJU7vVPzcbqx8Qs9Roor0tZMPZdgmTGmbGPnhKV0vfZqxHl1jOGH1EUa87SH lysCYzOm66FeQfbO3G8miAMtTSylLipUqVJysVx+5PQcfdaxQX5LPlocoIKhHLMCD55z kohQ== X-Gm-Message-State: AElRT7FffDFSDB+lMB3LQMaO611uHjUh3/WKfVcScIQYNjpyNRKi0Tw/ XdAhkmxn1s73LSIeA9q6gz8JJEYggrc= X-Received: by 10.80.169.89 with SMTP id m25mr3887247edc.244.1521666633747; Wed, 21 Mar 2018 14:10:33 -0700 (PDT) Received: from [192.168.0.189] (dhcp-5-186-126-104.cgn.ip.fibianet.dk. [5.186.126.104]) by smtp.gmail.com with ESMTPSA id m31sm3775827ede.35.2018.03.21.14.10.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Mar 2018 14:10:33 -0700 (PDT) Subject: Re: detecting integer constant expressions in macros To: Linus Torvalds , "Uecker, Martin" Cc: "linux-kernel@vger.kernel.org" References: <1521584015.31174.3.camel@med.uni-goettingen.de> From: Rasmus Villemoes Message-ID: <6d771077-bee3-07c9-61c3-440dfed8e567@rasmusvillemoes.dk> Date: Wed, 21 Mar 2018 22:10:31 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 2018-03-21 00:08, Linus Torvalds wrote: > On Tue, Mar 20, 2018 at 3:13 PM, Uecker, Martin > wrote: >> >> here is an idea: > > That's not "an idea". > > That is either genius, or a seriously diseased mind. > > I can't quite tell which. > >> a test for integer constant expressions which returns an >> integer constant expression itself which should be suitable >> for passing to __builtin_choose_expr might be: >> >> #define ICE_P(x) (sizeof(int) == sizeof(*(1 ? ((void*)((x) * 0l)) : (int*)1))) Wow. This is absolutely awesome. >> This also does not evaluate x itself on gcc although this is >> not guaranteed by the standard. (And I haven't tried any older >> gcc.) > > Oh, I think it's guaranteed by the standard that 'sizeof()' doesn't > evaluate the argument value, only the type. Even if there's some hypothetical scenario where x ends up containing something of variably-modified type, could one just use 0? instead of 1? . That doesn't affect the type of the whole expression. > I'm in awe of your truly marvelously disgusting hack. That is truly a > work of art. I'm not really worthy of commenting or trying to improve on this, but I think it's important that 'git blame' will forever give Martin the credit for this, so two minor suggestions: - Cast (x) to (long) to allow x to have type u64 on a 32-bit platform without giving "warning: cast to pointer from integer of different size". That also allows x to have pointer type (it's theoretically useful to take max() of two pointers into an array), and not so important for the kernel, floating point type. - Maybe use (int*)4 to avoid the compiler complaining about creating a non-aligned pointer. > I'm sure it doesn't work or causes warnings for various reasons, but > it's still a thing of beaty. I tried putting the below ugly test code through various gcc versions. In no cases could I get different optimization options to generate different results. I also couldn't get -Wall -Wextra to produce any warnings that wasn't just due to the silly input (i.e., yes, I know I have a comma expression with no side effects....). Most importantly, ICE_P was always accepted as an ICE itself. Everything from 4.6 onwards gives the same and expected output, namely 1 in the first four lines, 0 otherwise. gcc 4.4 instead produces this: 4 1 sizeof(long) 1 5ull - 3u 1 3.2 1 square(2) 0 square(argc) 0 squarec(2) 1 squarec(argc) 1 1+argc-argc 1 1+argc+argc+1-argc-argc 1 bignum() - 1 0 0*bignum() 0 0*bignumc() 1 sizeof(foo) 0 p 1 p < q 1 p++ 0 main 1 malloc(8) 0 v = malloc(8) 0 v 1 x++ 0 y++ 0 (3, 2, 1) 0 ({x++; 0; }) 0 ({square(y--); 0; }) 0 (square(x), 3) 0 (squarec(x), 3) 0 ({squarec(x); 3;}) 0 ({squarec(x);}) 1 So it seems to accept/treat (x)*0l as NULL as long as x has no side-effects - where a function call is treated as having side effects unless the function is declared with the const attribute, comma-expressions are hard-coded as having side-effects [and what else would they be good for, so that's not totally unreasonable...], and statement expressions have side effects if they have more than one statement. Rasmus #include #include static inline __attribute__((__const__)) unsigned squarec(unsigned n) { return n*n; } static inline unsigned square(unsigned n) { return n*n; } static inline unsigned long long bignum(void) { return 1000000000000ULL; } static inline __attribute__((__const__)) unsigned long long bignumc(void) { return 1000000000000ULL; } /* #define ICE_P(x) (sizeof(int) == sizeof(*(1 ? ((void*)((long)(x) * 0l)) : (int*)1))) */ #define ICE_P(x) (__builtin_types_compatible_p(typeof(0 ? ((void*)((long)(x) * 0l)) : (int*)1), int*)) #define t(x) printf("%-20s\t%d\n", #x, __builtin_choose_expr(ICE_P(x), 1, 0)) int main(int argc, char *argv[]) { char foo[argc++]; char **p, **q; int x = 5, y = 8; void *v; p = &argv[3]; q = &argv[6]; t(4); t(sizeof(long)); t(5ull - 3u); t(3.2); t(square(2)); t(square(argc)); t(squarec(2)); t(squarec(argc)); t(1+argc-argc); t(1+argc+argc+1-argc-argc); t(bignum() - 1); t(0*bignum()); t(0*bignumc()); t(sizeof(foo)); t(p); t(p < q); t(p++); t(main); t(malloc(8)); t(v = malloc(8)); t(v); t(x++); t(y++); t((3, 2, 1)); t(({x++; 0; })); t(({square(y--); 0; })); t((square(x), 3)); t((squarec(x), 3)); t(({squarec(x); 3;})); t(({squarec(x);})); /* Shutup distracting warnings. */ if (argc > 100000) { printf("%llu", square(argc) + squarec(argc) + bignum() + bignumc()); } return 0; }