This is an archive of the discontinued LLVM Phabricator instance.

[clang] Change builtin object size to be compatible with GCC when sub-object is invalid
ClosedPublic

Authored by jtmott-intel on Dec 8 2020, 3:07 PM.

Details

Summary

Motivating example:

struct { int v[10]; } t[10];

__builtin_object_size(
    &t[0].v[11], // access past end of subobject
    1            // request remaining bytes of closest surrounding subobject
);

In GCC, this returns 0. https://godbolt.org/z/7TeGs7

In current clang, however, this returns 356, the number of bytes remaining in the whole variable, as if the type was 0 instead of 1. https://godbolt.org/z/6Kffox

This patch checks for the specific case where we're requesting a subobject's size (type 1) but the subobject is invalid.

Diff Detail

Event Timeline

jtmott-intel requested review of this revision.Dec 8 2020, 3:07 PM
jtmott-intel created this revision.

Adding some reviewers and subscribing the mailing lists. FWIW, the changes seem reasonable to me.

george.burgess.iv accepted this revision.Jan 6 2021, 9:23 AM

thanks for working on this!

just one tiny nit and lgtm

clang/lib/AST/ExprConstant.cpp
11410–11411

nit: the new part of this condition makes this comment somewhat outdated. should it say something like "outside of" instead of "before"?

This revision is now accepted and ready to land.Jan 6 2021, 9:23 AM

Updated comments to reflect "outside of" instead of "before".

jtmott-intel marked an inline comment as done.Jan 6 2021, 12:50 PM

Seems I don't have commit access. I'll look into it. For now, could someone push this commit? Thanks.

Herald added a project: Restricted Project. · View Herald TranscriptJan 7 2021, 12:38 PM
pcc added a subscriber: pcc.Jan 15 2021, 6:07 PM

This causes us to reject the following (reduced from AOSP):

int sprintf(char* __s, const char* __fmt, ...)
    __attribute__((__format__(printf, 2, 3))) ;
int sprintf(char* dest, const char* format)
    __attribute__((overloadable))
    __attribute__((enable_if(((__builtin_object_size(((dest)), (1))) != ((unsigned long) -1) && (__builtin_object_size(((dest)), (1))) < (__builtin_strlen(format))), "format string will always overflow destination buffer")))

    __attribute__((unavailable("format string will always overflow destination buffer")));

void f() {
  unsigned char number_buffer[26] = {0};
  sprintf((char *)number_buffer, "null");
}

It doesn't seem like we ought to be rejecting this case. Can you please take a look?

tstellar added a subscriber: tstellar.

This CL has caused two issues in Chrome OS :
Compilation fail with FORTIFY: https://bugs.chromium.org/p/chromium/issues/detail?id=1168199
Runtime failures: https://bugs.chromium.org/p/chromium/issues/detail?id=1167504

I have requested George to take a look but will it be ok to revert this meanwhile?

This CL has caused two issues in Chrome OS :
Compilation fail with FORTIFY: https://bugs.chromium.org/p/chromium/issues/detail?id=1168199
Runtime failures: https://bugs.chromium.org/p/chromium/issues/detail?id=1167504

I have requested George to take a look but will it be ok to revert this meanwhile?

Yes, it's fine to revert this until we get these issues ironed out.

reverted in https://github.com/llvm/llvm-project/commit/b270fd59f0a86fe737853abc43e76b9d29a67eea until we can figure out how to address the issues outlined above. thanks!

reverted in https://github.com/llvm/llvm-project/commit/b270fd59f0a86fe737853abc43e76b9d29a67eea until we can figure out how to address the issues outlined above. thanks!

Thank you for this! I've also pinged @jtmott-intel internally in case he's not seen the post-commit feedback.