[PATCH] D14274: Add alloc_size attribute to clang
Akira Hatanaka via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 3 13:16:15 PDT 2016
ahatanak added inline comments.
================
Comment at: test/CodeGenCXX/alloc-size.cpp:66
@@ +65,3 @@
+ // CHECK: ret i32 122
+ return __builtin_object_size(my_malloc<int>(), 0) +
+ __builtin_object_size(my_calloc<int>(5), 0) +
----------------
george.burgess.iv wrote:
> ahatanak wrote:
> > Is it necessary to compute __builtin_object_size in the front-end (rather than in some IR passes like instcombine) when it takes the pointer returned by a function marked alloc_size?
> >
> > Also, is the IR optimization smart enough to get the exact object size in the following case?
> >
> > ```
> > void foo(int a, int b) {
> > void *p0 = my_malloc(a);
> > g0 = __builtin_object_size(p0, 0);
> > void *p1 = my_calloc(a, b);
> > g1 = __builtin_object_size(p1, 1);
> > }
> >
> > void foo1() {
> > foo(10, 50);
> > }
> > ```
> > Is it necessary to compute __builtin_object_size in the front-end (rather than in some IR passes like instcombine)
>
> It's necessary to try in the frontend. If that fails, we'll lower calls to __bos to `@llvm.objectsize`, and let LLVM try it.
>
> The main reason that we care for the frontend is, among other reasons, so we can use it with the `enable_if` attribute, like so:
>
> ```
> void strncat(char *buf, int n, const char *from)
> __attribute__((overloadable,
> enable_if(__builtin_object_size(buf, 0) < n, ""),
> unavailable("'n' is larger than the target buffer!")));
>
> void strncat(char *buf, int n, const char *from)
> __attribute__((overloadable));
>
> int main() {
> char buf[4];
> strncat(buf, sizeof(buf)+1, "hi"); // expected-error{{'n' is larger than the target buffer!}}
> }
> ```
>
>
> ----
>
> > Also, is the IR optimization smart enough to get the exact object size in the following case?
>
> `__builtin_object_size` *always* gets lowered to a constant by either clang or LLVM. That is, if `foo` gets inlined into `foo1`, then LLVM should be able to determine accurate values for `g0` and `g1`. If `foo` isn't inlined, then no: you'll get -1 for both.
>
> If you'd like to see what we can and can't get, LLVM already has the `allocsize` attribute (and `@llvm.objectsize` intrinsic) in it. :)
Thanks for the explanation. I see why you want to evaluate it in the front-end.
It looks like llvm optimizes function foo before it gets inlined into function foo1 and, as a result, g0 and g1 both get -1 instead of 10 and 500. I guess llvm should defer optimizing the function until after inliner is run.
https://reviews.llvm.org/D14274
More information about the cfe-commits
mailing list