From owner-freebsd-hackers@freebsd.org Sun Jan 21 16:56:59 2018 Return-Path: Delivered-To: freebsd-hackers@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 87A2DED1A3C for ; Sun, 21 Jan 2018 16:56:59 +0000 (UTC) (envelope-from marklmi26-fbsd@yahoo.com) Received: from sonic313-10.consmr.mail.ne1.yahoo.com (sonic313-10.consmr.mail.ne1.yahoo.com [66.163.185.33]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 5A5C372B05 for ; Sun, 21 Jan 2018 16:56:59 +0000 (UTC) (envelope-from marklmi26-fbsd@yahoo.com) X-YMail-OSG: 3DHC.90VM1lCiYWc0ThMOnR6USw8HlQrQs0rXVcK6C33EmknCr2pFqD.kSK7coH aYA2pvncyIm61JfzzEREpHptJ_OxevNhrhNUoTcodW32kXOdMPyw9xsZkpdFQcAXq4_5Y1x_xkdA y4n_ciPzbgNkKe0YA3yDv_1gMkozQwnkFrv7vMwTQzQNNRJP.cRDgSkaebUeLbgMXzh9JE6Q0hNz GWQ2o9lnN_Ltek2Pei92qrO9bd0bMXjNGyGuvT6U1D5Khp1v70gcBHG5oa1g1F7sGysXJ.FYto9Y Dl3Kv6swYTAjAd7WuPHjELXm8MNCmm1oaNwJcr3Y3kK8RNgGjNkcGDE7aGDGX99Ezky96f6ChIUZ VB._K0wS891rcF7Ns7XKulaypMuEvBEwgbFG6BROf07732RN6rM5LBn95Xqcd9mhrOPRWOfoC3_Q oagI5hXj7nyXqsTnGxEw2HMhH2CNgEDXY2mgpVf2IaiZY5Udy9L23_CTO72VvwAp26vME Received: from sonic.gate.mail.ne1.yahoo.com by sonic313.consmr.mail.ne1.yahoo.com with HTTP; Sun, 21 Jan 2018 16:56:52 +0000 Received: from smtp229.mail.ne1.yahoo.com (EHLO [192.168.1.25]) ([10.218.253.212]) by smtp415.mail.ne1.yahoo.com (JAMES SMTP Server ) with ESMTPA ID fe075fbd47d9537ac5d0ccfac4678709; Sun, 21 Jan 2018 16:56:49 +0000 (UTC) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 10.3 \(3273\)) Subject: Re: Attribute alloc__size use and clang 5.0.1 vs. gcc7 (e.g.): __builtin_object_size(p,1) and __builtin_object_size(p,3) disagreements result From: Mark Millard In-Reply-To: <8c4c5985-885a-abf7-93df-0698c645d36e@FreeBSD.org> Date: Sun, 21 Jan 2018 08:56:48 -0800 Cc: FreeBSD Toolchain , FreeBSD Hackers Content-Transfer-Encoding: quoted-printable Message-Id: <9DE674C6-EAA3-4E8A-906F-446E74D82FC4@yahoo.com> References: <1AA0993D-81E4-4DC0-BBD9-CC42B26ADB1C@yahoo.com> <8c4c5985-885a-abf7-93df-0698c645d36e@FreeBSD.org> To: Pedro Giffuni X-Mailer: Apple Mail (2.3273) X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Jan 2018 16:56:59 -0000 [May be an __alloc_size2(n,s) should be added and used?] On 2018-Jan-20, at 5:05 PM, Pedro Giffuni wrote: > Very interesting , thanks for running such tests ... >=20 >=20 > On 01/20/18 18:59, Mark Millard wrote: >> [Noting a typo in the program source, and >> so in the output text: the 2nd occurance of: "my_calloc_alt0 >> should have been: "my_calloc_alt1 >> . Hand edited corrections below for clarity.] >>=20 >> On 2018-Jan-20, at 3:27 PM, Mark Millard = wrote: >>=20 >>> [Bugzilla 225197 indirectly lead to this. >>> Avoiding continuing there.] >>>=20 >>> I decided to compare some alternate uses of >>> __attribute__((alloc_size(. . .))) compiled >>> and run under clang 5.0.1 and gcc7. I did not >>> get what I expected based on prior discussion >>> material. >>>=20 >>> This is an FYI since I do not know how important >>> the distinctions that I found are. >>>=20 >>> Here is the quick program: >>>=20 >>> # more alloc_size_attr_test.c >>> #include >>> #include >>>=20 >>> __attribute__((alloc_size(1,2))) >>> void* my_calloc_alt0(size_t n, size_t s) >>> { >>> void* p =3D calloc(n,s); >>> printf("calloc __builtin_object_size 0,1,2,3: %ld, %ld, %ld, = %ld\n" >>> ,(long) __builtin_object_size(p, 0) >>> ,(long) __builtin_object_size(p, 1) >>> ,(long) __builtin_object_size(p, 2) >>> ,(long) __builtin_object_size(p, 3) >>> ); >>> return p; >>> } >>>=20 >>> __attribute__((alloc_size(1))) __attribute__((alloc_size(2))) >>> void* my_calloc_alt1(size_t n, size_t s) >>> { >>> void* p =3D calloc(n,s); >>> printf("calloc __builtin_object_size 0,1,2,3: %ld, %ld, %ld, = %ld\n" >>> ,(long) __builtin_object_size(p, 0) >>> ,(long) __builtin_object_size(p, 1) >>> ,(long) __builtin_object_size(p, 2) >>> ,(long) __builtin_object_size(p, 3) >>> ); >>> return p; >>> } >>>=20 >>> int main() >>> { >>> void* p =3D my_calloc_alt0(2,7); >>> printf("my_calloc_alt0 __builtin_object_size 0,1,2,3: %ld, %ld, = %ld, %ld\n" >>> ,(long) __builtin_object_size(p, 0) >>> ,(long) __builtin_object_size(p, 1) >>> ,(long) __builtin_object_size(p, 2) >>> ,(long) __builtin_object_size(p, 3) >>> ); >>> void* q =3D my_calloc_alt1(2,7); >>> printf("my_calloc_alt0 __builtin_object_size 0,1,2,3: %ld, %ld, = %ld, %ld\n" >> The above line should have been: >>=20 >> printf("my_calloc_alt1 __builtin_object_size 0,1,2,3: %ld, %ld, %ld, = %ld\n" >>=20 >>> ,(long) __builtin_object_size(q, 0) >>> ,(long) __builtin_object_size(q, 1) >>> ,(long) __builtin_object_size(q, 2) >>> ,(long) __builtin_object_size(q, 3) >>> ); >>> } >>>=20 >>> # uname -apKU >>> FreeBSD FBSDFSSD 12.0-CURRENT FreeBSD 12.0-CURRENT r327485M amd64 = amd64 1200054 1200054 >>>=20 >>> The system-clang 5.0.1 result was: >>>=20 >>> # clang -O2 alloc_size_attr_test.c >> The later outputs are edited for clarity: >>=20 >>> # ./a.out >>> calloc __builtin_object_size 0,1,2,3: 14, 14, 14, 0 >>> my_calloc_alt0 __builtin_object_size 0,1,2,3: 14, 14, 14, 0 >>> calloc __builtin_object_size 0,1,2,3: 14, 14, 14, 0 >> my_calloc_alt1 __builtin_object_size 0,1,2,3: 14, 14, 14, 0 >>> The lang/gcc7 result was: >>>=20 >>> # gcc7 -O2 alloc_size_attr_test.c >>>=20 >>> # ./a.out >>> calloc __builtin_object_size 0,1,2,3: -1, -1, 0, 0 >>> my_calloc_alt0 __builtin_object_size 0,1,2,3: 14, 14, 14, 14 >>> calloc __builtin_object_size 0,1,2,3: -1, -1, 0, 0 >> my_calloc_alt1 __builtin_object_size 0,1,2,3: 14, 7, 14, 14 >>> I'll ignore that gcc does not provide actual sizes >>> via __builtin_object_size for calloc use. >>>=20 >>> Pairing the other lines for easy comparison, with >>> some notes mixed in: >>>=20 >>> __attribute__((alloc_size(1,2))) style: >>> my_calloc_alt0 __builtin_object_size 0,1,2,3: 14, 14, 14, 0 (system = clang) >>> my_calloc_alt0 __builtin_object_size 0,1,2,3: 14, 14, 14, 14 (gcc7) >>>=20 >>> __attribute__((alloc_size(1))) __attribute__((alloc_size(2))) style: >> my_calloc_alt1 __builtin_object_size 0,1,2,3: 14, 14, 14, 0 (system = clang) >> my_calloc_alt1 __builtin_object_size 0,1,2,3: 14, 7, 14, 14 (gcc7) > So on GCC7 it appears > __attribute__((alloc_size(1,2))) !=3D __attribute__((alloc_size(1))) = __attribute__((alloc_size(2))) >=20 > This is not good as it was the base for r280801 .. related to the old = discussion about deprecating old compilers that don't accept VA_ARGS. >=20 > I am unsure if its a regression but it appears that for clang it is = the same thing though. May be there should be a __alloc_size2(n,s) that translates to __attribute__((alloc_size(n,s))) when it is not a no-op. This avoids the VA_ARGS issue and gcc's documentation makes no mention of a more than 2 argument variant of __attribute__((alloc_size(. . .))) . Looking up glib it has: G_GNUC_ALLOC_SIZE(x) G_GNUC_ALLOC_SIZE2(x,y) but none for any other count of arguments. >>> Thus. . . >>>=20 >>> For __attribute__((alloc_size(1))) __attribute__((alloc_size(2))): >>> __builtin_object_size(p,1) is not equivalent (clang vs. gcc7) >>>=20 >>> For both of the alloc_size usage styles: >>> __builtin_object_size(p,3) is not equivalent (clang vs. gcc7) >>>=20 >>> This means that the two style of alloc_size use are not >>> equivalent across some major compilers/toolchains. >=20 > This is actually not a surprise: GCC and clang implementation of = __alloc_size__ has differences due to limitations on the LLVM IR (or the = fact there is one). >=20 > The alloc_size attribute is basically only used for the so-called = FORTIFY_SOURCE feature that depends on GCC with some support from the = C-library: last time I looked clang didn't support the compile-time = checks very well. The attributes are mostly unused in FreeBSD at this = time but, GCC7 -Walloc-size-larger-than=3Dsize depends on them (I have = never tested that though). >=20 > FWIW, we had an unfinished GSoC that attempted to implement = FORTIFY_SOURCE but we got stuck on the lack of clang support and other = issues. Lately Google has been spending some effort on it but it is more = limited and doesn't match the GCC behavior. >=20 >=20 >=20 >=20 >>> But I do not know if either of the differences is a problem or >>> not. >>>=20 >>>=20 >>> Note: without a sufficient -O all the figures can be >>> the mix of -1's and 0's. =3D=3D=3D Mark Millard marklmi at yahoo.com ( markmi at dsl-only.net is going away in 2018-Feb, late)