[May be an __alloc_size2(n,s) should be added and used?]

On 2018-Jan-20, at 5:05 PM, Pedro Giffuni <p...@freebsd.org> wrote:

> Very interesting , thanks for running such tests ...
> 
> 
> 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.]
>> 
>> On 2018-Jan-20, at 3:27 PM, Mark Millard <marklmi26-f...@yahoo.com> wrote:
>> 
>>> [Bugzilla 225197 indirectly lead to this.
>>> Avoiding continuing there.]
>>> 
>>> 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.
>>> 
>>> This is an FYI since I do not know how important
>>> the distinctions that I found are.
>>> 
>>> Here is the quick program:
>>> 
>>> # more alloc_size_attr_test.c
>>> #include <stdlib.h>
>>> #include <stdio.h>
>>> 
>>> __attribute__((alloc_size(1,2)))
>>> void* my_calloc_alt0(size_t n, size_t s)
>>> {
>>>   void* p = 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;
>>> }
>>> 
>>> __attribute__((alloc_size(1))) __attribute__((alloc_size(2)))
>>> void* my_calloc_alt1(size_t n, size_t s)
>>> {
>>>   void* p = 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;
>>> }
>>> 
>>> int main()
>>> {
>>>   void* p = 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 = 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:
>> 
>> printf("my_calloc_alt1 __builtin_object_size 0,1,2,3: %ld, %ld, %ld, %ld\n"
>> 
>>>         ,(long) __builtin_object_size(q, 0)
>>>         ,(long) __builtin_object_size(q, 1)
>>>         ,(long) __builtin_object_size(q, 2)
>>>         ,(long) __builtin_object_size(q, 3)
>>>         );
>>> }
>>> 
>>> # uname -apKU
>>> FreeBSD FBSDFSSD 12.0-CURRENT FreeBSD 12.0-CURRENT  r327485M  amd64 amd64 
>>> 1200054 1200054
>>> 
>>> The system-clang 5.0.1 result was:
>>> 
>>> # clang -O2 alloc_size_attr_test.c
>> The later outputs are edited for clarity:
>> 
>>> # ./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:
>>> 
>>> # gcc7 -O2 alloc_size_attr_test.c
>>> 
>>> # ./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.
>>> 
>>> Pairing the other lines for easy comparison, with
>>> some notes mixed in:
>>> 
>>> __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)
>>> 
>>> __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))) != __attribute__((alloc_size(1))) 
> __attribute__((alloc_size(2)))
> 
> 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.
> 
> 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. . .
>>> 
>>> For __attribute__((alloc_size(1))) __attribute__((alloc_size(2))):
>>> __builtin_object_size(p,1) is not equivalent (clang vs. gcc7)
>>> 
>>> For both of the alloc_size usage styles:
>>> __builtin_object_size(p,3) is not equivalent (clang vs. gcc7)
>>> 
>>> This means that the two style of alloc_size use are not
>>> equivalent across some major compilers/toolchains.
> 
> 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).
> 
> 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=size depends on them (I have never tested that 
> though).
> 
> 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.
> 
> 
> 
> 
>>> But I do not know if either of the differences is a problem or
>>> not.
>>> 
>>> 
>>> Note: without a sufficient -O<?> all the figures can be
>>> the mix of -1's and 0's.

===
Mark Millard
marklmi at yahoo.com
( markmi at dsl-only.net is
going away in 2018-Feb, late)

_______________________________________________
freebsd-toolchain@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-toolchain
To unsubscribe, send any mail to "freebsd-toolchain-unsubscr...@freebsd.org"

Reply via email to