[cfe-dev] Flexible array members in ObjC classes

John McCall via cfe-dev cfe-dev at lists.llvm.org
Wed Sep 20 18:51:00 PDT 2017


> On Sep 20, 2017, at 6:16 PM, Volodymyr Sapsai <vsapsai at apple.com> wrote:
> Hello all,
> 
> Currently clang hits an assertion
> 
> Assertion failed: (!fieldType->isArrayType() && "ivar of non-constant array type?"), function visitField, file llvm-project/clang/lib/CodeGen/CGObjCMac.cpp, line 5092.
> 
> when one of ObjC class instance variables is a struct with a flexible array member and ARC is enabled. This happens only with ARC because in this case we are building ivar layout and for MRC we skip it. And ivar layout supports only constant arrays.
> 
> I am considering the following options to fix this issue:
> 
> 1. Prohibit ivars with flexible array members both for ARC and MRC. Pointers to such structs are still acceptable and preferred.
> 2. Prohibit ivars with flexible array members only for ARC.
> 3. Add support for ivars with flexible array members. We already accept ivars with 0-size array members and at cursory glance it looks similar. This option has 2 sub options
>  3.1 Allow ivars with flexible array members anywhere.
>  3.2 Allow ivars with flexible array members only as the last ivar.
> 
> My preferred option is option 1 because to my understanding structs with flexible array members are supposed to be allocated dynamically, reserving memory for the flexible array. And having them as ObjC class ivar will cause flexible arrays being 0-sized all the time.

Objective-C objects are allocated dynamically, and it's absolutely possible to allocate extra storage in an object and then access that via a trailing flexible or zero-length array.  It is, of course, somewhat perilous, but that's true of flexible/zero-length array members of structs, too.

> The biggest downside of this approach is that it can cause rejecting some code that is accepted today.
> 
> The most user-friendly option seems option 3 with warnings. It is permissive but still warns about the risk of overwriting other ivars. The downside is that it is extra work for code that nobody might be writing, such code is still error-prone despite the warnings, maintenance cost is potentially higher.
> 
> Incomplete code illustrating option 1 can be found at https://reviews.llvm.org/D38114 What is your opinion? What would you recommend?

I think option 3 is the right way to go: at a minimum, fix the bug in the layout-string computation by just ignoring flexible array members.  Adding additional semantic checks to ensure that the flexible array is the last ivar (whether explicit or synthesized) seems like a good idea, too, but it's not mandatory.

John.



More information about the cfe-dev mailing list