This is an archive of the discontinued LLVM Phabricator instance.

[Sema] Add support for flexible array members in Obj-C.
ClosedPublic

Authored by vsapsai on Oct 10 2017, 5:32 PM.

Details

Summary

Allow Obj-C ivars with incomplete array type but only as the last ivar.
Also add a requirement for ivars that contain a flexible array member to
be at the end of class too. It is possible to add in a subclass another
ivar at the end but we'll emit a warning in this case. Also we'll emit a
warning if a variable sized ivar is declared in class extension or in
implementation because subclasses won't know they should avoid adding
new ivars.

In ARC incomplete array objects are treated as __unsafe_unretained so
require them to be marked as such.

Prohibit synthesizing ivars with flexible array members because order of
synthesized ivars is not obvious and tricky to control. Spelling out
ivar explicitly gives control to developers and helps to avoid surprises
with unexpected ivar ordering.

For C and C++ changed diagnostic to tell explicitly a field is not the
last one and point to the next field. It is not as useful as in Obj-C
but it is an improvement and it is consistent with Obj-C. For C for
unions emit more specific err_flexible_array_union instead of generic
err_field_incomplete.

rdar://problem/21054495

Event Timeline

vsapsai created this revision.Oct 10 2017, 5:32 PM

Previous discussion on the mailing list can be found at http://lists.llvm.org/pipermail/cfe-dev/2017-September/055548.html The implementation is not exactly like it was discussed, it has some changes.

There is another case when extra ivar is added at the end, it is for bitfields. But bitfields aren't compatible with flexible array members so I decided not to include them in tests.

I separated CodeGen change in a separate patch that can be found here.

rjmccall added inline comments.Oct 12 2017, 3:50 PM
clang/include/clang/Basic/DiagnosticSemaKinds.td
5226

"Variable sized type" is a bit too close to the C99 variably-sized array type extension. Maybe "unbounded array type" if you're trying to cover both "int x[];" and "int x[0];"?

Well, I guess there's some precedent for using this terminology, but ugh.

clang/lib/Sema/SemaDecl.cpp
15046

"Whether" rather than "If", please. You should also leave a comment about *why* we can't check this here — I assume because you also want to complain about the last explicit ivar if there are synthesized ivars? I think we could at least still check this for @interface ivars.

vsapsai added inline comments.Oct 12 2017, 6:30 PM
clang/include/clang/Basic/DiagnosticSemaKinds.td
5226

I took "variable sized type" entirely from

def ext_variable_sized_type_in_struct : ExtWarn<
  "field %0 with variable sized type %1 not at the end of a struct or class is"
  " a GNU extension">, InGroup<GNUVariableSizedTypeNotAtEnd>;

I'm not covering int x[0];. All the changes are for int x[]; and struct { int x[]; }

clang/lib/Sema/SemaDecl.cpp
15046

Will change s/If/Whether/

Main reason for checking elsewhere is to check after ivars are synthesized, you are right. At some point I had this check done here but for detecting ivar-after-flexible-array on interface/extension, interface/implementation border I am relying on chained ObjCIvarDecl. But here I have ArrayRef<Decl *> Fields so implementation will be different. I decided that it would be cleaner to perform the check only in DiagnoseVariableSizedIvars.

rjmccall added inline comments.Oct 12 2017, 7:33 PM
clang/lib/Sema/SemaDecl.cpp
15046

Is there a reason to do any of the checking here, then?

vsapsai added inline comments.Oct 13 2017, 12:13 PM
clang/lib/Sema/SemaDecl.cpp
15046

No objective reason. I updated isIncompleteArrayType branch to avoid flexible array members rejected at line 15023

} else if (!FDTy->isDependentType() &&
           RequireCompleteType(FD->getLocation(), FD->getType(),
                               diag::err_field_incomplete)) {

and here I've added it for consistency. Will move to DiagnoseVariableSizedIvars and see if it works fine, don't expect any problems.

vsapsai updated this revision to Diff 118990.Oct 13 2017, 4:36 PM
  • Address rjmccall review comment, move warn_variable_sized_ivar_visibility to DiagnoseVariableSizedIvars.
This revision is now accepted and ready to land.Oct 23 2017, 12:20 AM
This revision was automatically updated to reflect the committed changes.