Bug 82599 - Assignments from statically initialized flexible arrays copy too much
Summary: Assignments from statically initialized flexible arrays copy too much
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 7.2.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid, wrong-code
Depends on:
Blocks: flexmembers
  Show dependency treegraph
 
Reported: 2017-10-18 06:57 UTC by Tom Karzes
Modified: 2024-03-14 22:08 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2024-03-14 00:00:00


Attachments
C program that demonstrates the bug (194 bytes, text/x-csrc)
2017-10-18 06:57 UTC, Tom Karzes
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Tom Karzes 2017-10-18 06:57:02 UTC
Created attachment 42388 [details]
C program that demonstrates the bug

I am running on a 32-bit Ubuntu system.

The attached file, fa4.c, shows a problem with the gcc extension which allows static initialization of flexible array members.

The problem is in main, with the declaration and initialization of second:

    s second = first;

The compiler isn't allocating space for the flexible array member in second, which makes sense.  However, it is copying *all* of first into second, including the space that was allocated for the flexible array member.  The result is that it writes past the end of second, and continues writing into the array v.  When v is printed, instead of printing <xxxxxxxx>, it instead prints the tail of the string that was copied from first, which comes out as <defgh>.

The same behavior is seen if the declaration of and assignment to s are split into:

    s second;
    second = first;

I believe the assignment should only copy sizeof(s) bytes, rather than including the storage allocated for the flexible array member.

Note that if the declaration and static initialization of first is moved to a separate file, the problem disappears, and the structure copy behaves as it should.  But when gcc sees the true allocated size of first, it copies too much in the assignment.  It should always copy the same amount regardless of where first is defined.
Comment 1 Richard Biener 2017-10-18 09:15:27 UTC
Confirmed.  I think the issue is that we make the new type created by constructing the object compatible (or the same) as the second.  Then we get to invalid GIMPLE
being simply

  second = first;

which ends up using expr_size from the source.  Iff the C FE wants to support
this kind of assignments (not sure if it really should!) then it needs to
tack appropriate WITH_SIZE_EXPRs on the decls.
Comment 2 Andrew Pinski 2024-03-14 22:08:56 UTC
Both the C and C++ front-end now produce the wrong code.