[clang] [Clang] Handle structs with inner structs and no fields (PR #89126)

Bill Wendling via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 18 02:55:13 PDT 2024


================
@@ -844,7 +847,18 @@ const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberField(
       if (const FieldDecl *Field =
----------------
bwendling wrote:

> FieldNo and Layout are referring to fields of "RD"; the "Field" found in the recursive visit is a member of Record (or some subobject of Record). So the code is doing math on completely unrelated offsets. Checking getFieldCount is just masking the issue.

That's not the issue. What's happening is when an inner struct is declared/defined, we recurse within it to try to find the `Field` offset. If we do find it, then `Offset` has the offset value within `Record`. At this point, what we need is the offset up to the `RecordDecl`, but since those may or may not have a field number associated with them, we use the last `FieldNo` to get that offset.

A bit clearer:

```
struct foo {        /* <- Passed in as RD */
  struct bar {      /* <- Not a field, so FieldNo isn't incremented. Recurse on struct bar */
    int array[];    /* <- FAM found at offset 0 of struct bar */
  };
                    /* <- Returning with the array FieldDecl, we want to add on any
                          offset associated with the placement of the struct bar
                          definition, but there are no FieldDecls, and so we can't
                          call 'Layout.getFieldOffset()' */
};
```

This has obvious issues with virtual classes and the like, which is why C++ doesn't officially support FAMs (I believe it's an extension).

To be fair, I had the same question you had. I should document this better.

> Maybe instead of looking for RecordDecls, this code should be looking for fields where the type of the field is an anonymous struct/union.

We want to look into all inner structs to find a FAM that may be lurking deep down within the bowels of the struct, which may involve non-anonymous structs.

https://github.com/llvm/llvm-project/pull/89126


More information about the cfe-commits mailing list