This is an archive of the discontinued LLVM Phabricator instance.

[clang][ExprConstant] fix __builtin_object_size for compound literal
AbandonedPublic

Authored by nickdesaulniers on May 22 2023, 1:31 PM.

Details

Summary

Fixup to D150892.

Diff Detail

Event Timeline

Herald added a project: Restricted Project. · View Herald TranscriptMay 22 2023, 1:31 PM
nickdesaulniers requested review of this revision.May 22 2023, 1:31 PM
Herald added a project: Restricted Project. · View Herald TranscriptMay 22 2023, 1:31 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
erichkeane accepted this revision.May 22 2023, 1:40 PM
This revision is now accepted and ready to land.May 22 2023, 1:40 PM
efriedma added inline comments.May 22 2023, 3:48 PM
clang/lib/AST/ExprConstant.cpp
11737

For the second call to CheckHandleSizeof (line 11791), is the type of consistent with the type of the variable? If Ty refers to a field, I'm not sure it makes sense to call getFlexibleArrayInitChars(). Something along the lines of "struct Z { struct A { int x, y[]; } z; int a; };"

11740

I think I'd like to check isa<VarDecl> here to be on the safe side, even if I don't have a specific example where it would break.

nickdesaulniers marked an inline comment as done.
  • more dyn_cast
clang/lib/AST/ExprConstant.cpp
11737

Can such an object even be initialized?

cat /tmp/x.c
struct Z { struct A { int x, y[]; } z; int a; };

static struct Z my_z = {
  .z = {
    .x = 42,
    .y = {
      0, 1, 2,
    },
  },
  .a = 42,
};

unsigned long foo (void) {
  return __builtin_object_size(&my_z, 1);
}
$ clang -O2 /tmp/x.c -S -o -
/tmp/x.c:1:37: warning: field 'z' with variable sized type 'struct A' not at the end of a struct or class is a GNU extension [-Wgnu-variable-sized-type-not-at-end]
struct Z { struct A { int x, y[]; } z; int a; };
                                    ^
/tmp/x.c:6:10: error: initialization of flexible array member is not allowed
    .y = {
         ^
/tmp/x.c:1:30: note: initialized flexible array member 'y' is here
struct Z { struct A { int x, y[]; } z; int a; };
                             ^
1 warning and 1 error generated.

or did you have something else in mind?

efriedma added inline comments.May 22 2023, 5:00 PM
clang/lib/AST/ExprConstant.cpp
11737

I was thinking something more along the lines of

struct Z { struct A { int x, y[]; } z; int a; int b[]; };

static struct Z my_z = { .b = {1,2,3} };

unsigned long foo (void) {
  return __builtin_object_size(&my_z.z, 1);
}

The idea being that you're adding the length of the flexible member even though the caller isn't trying to ask about it.

nickdesaulniers abandoned this revision.May 23 2023, 10:19 AM
nickdesaulniers marked 2 inline comments as done.
clang/lib/AST/ExprConstant.cpp
11737

Ah, thanks! You're right, I didn't understand what was meant by "most derived type."

I've fixed this up in the re-opened https://reviews.llvm.org/D150892. PTAL.