mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 05:00:16 +03:00
Fix bugzilla 24594 - ImportC: Packed struct has wrong layout (#16611)
Packed structs were already implemented with the Microsoft syntax (e.g. `#pragma pack(push, 1)`), but the GCC syntax was ignored.
This commit is contained in:
parent
1917164050
commit
557e1d5eea
4 changed files with 58 additions and 3 deletions
|
@ -3634,6 +3634,12 @@ final class CParser(AST) : Parser!AST
|
|||
* type on the target machine. It's the opposite of __attribute__((packed))
|
||||
*/
|
||||
}
|
||||
else if (token.ident == Id.packed)
|
||||
{
|
||||
specifier.packalign.set(1);
|
||||
specifier.packalign.setPack(true);
|
||||
nextToken();
|
||||
}
|
||||
else if (token.ident == Id.always_inline) // https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
|
||||
{
|
||||
specifier.scw |= SCW.xinline;
|
||||
|
@ -3982,7 +3988,7 @@ final class CParser(AST) : Parser!AST
|
|||
members = new AST.Dsymbols(); // so `members` will be non-null even with 0 members
|
||||
while (token.value != TOK.rightCurly)
|
||||
{
|
||||
cparseStructDeclaration(members);
|
||||
cparseStructDeclaration(members, packalign);
|
||||
|
||||
if (token.value == TOK.endOfFile)
|
||||
break;
|
||||
|
@ -3996,6 +4002,24 @@ final class CParser(AST) : Parser!AST
|
|||
* struct-declarator (opt)
|
||||
*/
|
||||
}
|
||||
|
||||
/* GNU Extensions
|
||||
* Parse the postfix gnu-attributes (opt)
|
||||
*/
|
||||
Specifier specifier;
|
||||
if (token.value == TOK.__attribute__)
|
||||
cparseGnuAttributes(specifier);
|
||||
if (!specifier.packalign.isUnknown)
|
||||
{
|
||||
packalign.set(specifier.packalign.get());
|
||||
packalign.setPack(specifier.packalign.isPack());
|
||||
foreach (ref d; (*members)[])
|
||||
{
|
||||
auto decls = new AST.Dsymbols(1);
|
||||
(*decls)[0] = d;
|
||||
d = new AST.AlignDeclaration(d.loc, specifier.packalign, decls);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!tag)
|
||||
error("missing tag `identifier` after `%s`", Token.toChars(structOrUnion));
|
||||
|
@ -4027,8 +4051,9 @@ final class CParser(AST) : Parser!AST
|
|||
* declarator (opt) : constant-expression
|
||||
* Params:
|
||||
* members = where to put the fields (members)
|
||||
* packalign = alignment to use for struct members
|
||||
*/
|
||||
void cparseStructDeclaration(AST.Dsymbols* members)
|
||||
void cparseStructDeclaration(AST.Dsymbols* members, structalign_t packalign)
|
||||
{
|
||||
//printf("cparseStructDeclaration()\n");
|
||||
if (token.value == TOK._Static_assert)
|
||||
|
@ -4039,7 +4064,7 @@ final class CParser(AST) : Parser!AST
|
|||
}
|
||||
|
||||
Specifier specifier;
|
||||
specifier.packalign = this.packalign;
|
||||
specifier.packalign = packalign.isUnknown ? this.packalign : packalign;
|
||||
auto tspec = cparseSpecifierQualifierList(LVL.member, specifier);
|
||||
if (!tspec)
|
||||
{
|
||||
|
|
|
@ -8799,6 +8799,7 @@ struct Id final
|
|||
static Identifier* define;
|
||||
static Identifier* undef;
|
||||
static Identifier* ident;
|
||||
static Identifier* packed;
|
||||
static void initialize();
|
||||
Id()
|
||||
{
|
||||
|
|
|
@ -574,6 +574,7 @@ immutable Msgtable[] msgtable =
|
|||
{ "define" },
|
||||
{ "undef" },
|
||||
{ "ident" },
|
||||
{ "packed" },
|
||||
];
|
||||
|
||||
|
||||
|
|
28
compiler/test/compilable/test24594.c
Normal file
28
compiler/test/compilable/test24594.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include <stdint.h>
|
||||
|
||||
struct S1
|
||||
{
|
||||
uint32_t a;
|
||||
uint64_t b;
|
||||
} __attribute__((packed));
|
||||
|
||||
_Static_assert(sizeof(S1) == 12, "S1 size");
|
||||
_Static_assert(&((struct S1*)0)->b == 4, "S1::b offset");
|
||||
|
||||
struct __attribute__((packed)) S2
|
||||
{
|
||||
uint8_t a;
|
||||
uint16_t b;
|
||||
};
|
||||
|
||||
_Static_assert(sizeof(S2) == 3, "S2 size");
|
||||
_Static_assert(&((struct S2*)0)->b == 1, "S2::b offset");
|
||||
|
||||
struct __attribute__((packed)) S3
|
||||
{
|
||||
uint32_t a;
|
||||
uint8_t b;
|
||||
};
|
||||
|
||||
_Static_assert(sizeof(S3) == 5, "S3 size");
|
||||
_Static_assert(&((struct S3*)0)->b == 4, "S3::b offset");
|
Loading…
Add table
Add a link
Reference in a new issue