[PATCH] D151148: [clang][ExprConstant] fix __builtin_object_size for compound literal

Nick Desaulniers via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue May 23 10:19:58 PDT 2023


nickdesaulniers abandoned this revision.
nickdesaulniers marked 2 inline comments as done.
nickdesaulniers added a comment.

Merged into https://reviews.llvm.org/D150892.



================
Comment at: clang/lib/AST/ExprConstant.cpp:11737
     bool Ret = HandleSizeof(Info, ExprLoc, Ty, Result);
     if (Ty->isStructureType() &&
         Ty->getAsStructureType()->getDecl()->hasFlexibleArrayMember()) {
----------------
efriedma wrote:
> nickdesaulniers wrote:
> > efriedma wrote:
> > > 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; };"
> > 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?
> 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.
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.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151148/new/

https://reviews.llvm.org/D151148



More information about the cfe-commits mailing list