This is an archive of the discontinued LLVM Phabricator instance.

Fix PR26741 -- __builtin_object_size is not consistently conservative with C++ inheritance
AbandonedPublic

Authored by george.burgess.iv on Feb 29 2016, 5:40 PM.

Details

Reviewers
rsmith
Summary

This patch fixes PR26741, and makes us handle inheritance more sanely.

Broken code:

struct Foo { char a[1]; };
struct Bar : Foo {};

int break() {
  Bar *b;
  int size = __builtin_object_size(b->a, 1);
  assert(size == -1); // Fires; size is 1.
}

Because we're now handling inheritance, this patch has a few fun things in it (see: the new loop at ExprConstant.cpp:6489) so that we aren't overly conservative when inheritance is involved. I'm not entirely thrilled with how we determine if a base class is considered to be at the end of a derived class; better approaches are appreciated.

Diff Detail

Event Timeline

george.burgess.iv retitled this revision from to Fix PR26741 -- __builtin_object_size is not consistently conservative with C++ inheritance.
george.burgess.iv updated this object.
george.burgess.iv added a reviewer: rsmith.
george.burgess.iv added a subscriber: cfe-commits.
rsmith edited edge metadata.Mar 18 2016, 10:11 AM

Can you explain a bit more about the problem? It seems to me that if I have:

struct Base {
  char k[1];
};
struct Derived : Base {};

... then the 'k' subobject of a Derived object is known to be exactly 1 byte long -- it doesn't seem obviously appropriate for our flexible-sized trailing array support to cover this case.

I don't feel strongly about how we should handle this, to be honest. Feeding your example into GCC 4.8 like so:

#include <stdio.h>

struct Foo { char k[1]; };

struct Bar : Foo {};

int __attribute__((noinline)) bos(Bar *b) {
  return __builtin_object_size(&b->k[0], 1);
}

int main() {
  Bar b;
  printf("%d\n", bos(&b));
  return 0;
}

...The resultant executable prints "1". So, it seems that having this detection would be above and beyond what GCC offers. Given that "above and beyond," in this case implies "less likely to produce an accurate answer," I agree that this probably isn't such a great idea. :)

Thanks for the feedback!