Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 21 Jan 2018 08:56:48 -0800
From:      Mark Millard <marklmi26-fbsd@yahoo.com>
To:        Pedro Giffuni <pfg@FreeBSD.org>
Cc:        FreeBSD Toolchain <freebsd-toolchain@freebsd.org>, FreeBSD Hackers <freebsd-hackers@freebsd.org>
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
Message-ID:  <9DE674C6-EAA3-4E8A-906F-446E74D82FC4@yahoo.com>
In-Reply-To: <8c4c5985-885a-abf7-93df-0698c645d36e@FreeBSD.org>
References:  <1AA0993D-81E4-4DC0-BBD9-CC42B26ADB1C@yahoo.com> <F227842D-6BE2-4680-82E7-07906AF61CD7@yahoo.com> <8c4c5985-885a-abf7-93df-0698c645d36e@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
[May be an __alloc_size2(n,s) should be added and used?]

On 2018-Jan-20, at 5:05 PM, Pedro Giffuni <pfg@FreeBSD.org> 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 <marklmi26-fbsd@yahoo.com> =
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 <stdlib.h>
>>> #include <stdio.h>
>>>=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)




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9DE674C6-EAA3-4E8A-906F-446E74D82FC4>