diff --git a/compiler/src/dmd/cparse.d b/compiler/src/dmd/cparse.d index 86f85e34ce..fd5074f5bf 100644 --- a/compiler/src/dmd/cparse.d +++ b/compiler/src/dmd/cparse.d @@ -1720,6 +1720,34 @@ final class CParser(AST) : Parser!AST /********************************* Declaration Parser ***************************/ //{ + void declareTag(AST.TypeTag tt, ref Specifier specifier, bool generate_enum_id = false) + { + if (!tt.id && (generate_enum_id || tt.tok != TOK.enum_)) tt.id = Identifier.generateId("__tag"); + /* `struct tag;` and `struct tag { ... };` + * always result in a declaration in the current scope + */ + auto stag = (tt.tok == TOK.struct_) ? new AST.StructDeclaration(tt.loc, tt.id, false) : + (tt.tok == TOK.union_) ? new AST.UnionDeclaration(tt.loc, tt.id) : + new AST.EnumDeclaration(tt.loc, tt.id, tt.base); + if (!tt.alignExps && !tt.packalign.isUnknown()) + { + // saw `struct __declspec(align(N)) Tag ...` + auto st = stag.isStructDeclaration(); + st.alignment = tt.packalign; + } + stag.members = tt.members; + tt.members = null; + if (!symbols) + symbols = new AST.Dsymbols(); + AST.Dsymbol stags = stag; + if (tt.alignExps) + { + auto decls = new AST.Dsymbols(1); + (*decls)[0] = stags; + stags = new AST.AlignDeclaration(stags.loc, tt.alignExps, decls); + } + symbols.push(stags); + } /************************************* * C11 6.7 * declaration: @@ -1767,34 +1795,9 @@ final class CParser(AST) : Parser!AST specifier.packalign = this.packalign; auto tspec = cparseDeclarationSpecifiers(level, specifier); - AST.Dsymbol declareTag(AST.TypeTag tt, ref Specifier specifier) - { - /* `struct tag;` and `struct tag { ... };` - * always result in a declaration in the current scope - */ - auto stag = (tt.tok == TOK.struct_) ? new AST.StructDeclaration(tt.loc, tt.id, false) : - (tt.tok == TOK.union_) ? new AST.UnionDeclaration(tt.loc, tt.id) : - new AST.EnumDeclaration(tt.loc, tt.id, tt.base); - if (!tt.alignExps && !tt.packalign.isUnknown()) - { - // saw `struct __declspec(align(N)) Tag ...` - auto st = stag.isStructDeclaration(); - st.alignment = tt.packalign; - } - stag.members = tt.members; - tt.members = null; - if (!symbols) - symbols = new AST.Dsymbols(); - AST.Dsymbol stags = stag; - if (tt.alignExps) - { - auto decls = new AST.Dsymbols(1); - (*decls)[0] = stags; - stags = new AST.AlignDeclaration(stags.loc, tt.alignExps, decls); - } - symbols.push(stags); - return stags; - } + // Defer declaring a tagged type (struct/union/enum) so + // that anonymous types can use a typedef as their id. + /* If a declarator does not follow, it is unnamed */ @@ -1820,12 +1823,13 @@ final class CParser(AST) : Parser!AST !tt.id && (tt.tok == TOK.struct_ || tt.tok == TOK.union_)) return; // legal but meaningless empty declaration, ignore it - auto stags = declareTag(tt, specifier); + if (tt.members || tt.tok != TOK.enum_) + declareTag(tt, specifier); if (0 && tt.tok == TOK.enum_) // C11 proscribes enums with no members, but we allow it { if (!tt.members) - error(tt.loc, "`enum %s` has no members", stags.toChars()); + error(tt.loc, "`enum %s` has no members", tt.toChars()); } return; } @@ -1838,6 +1842,15 @@ final class CParser(AST) : Parser!AST return; } + if (auto tt = tspec.isTypeTag()) + { + if (tt.id && tt.members) + { + // Valid tag decl with name and members, go ahead and declare it now. + declareTag(tt, specifier); + } + } + if (tspec && specifier.mod & MOD.xconst) { tspec = toConst(tspec); @@ -1954,7 +1967,7 @@ final class CParser(AST) : Parser!AST typedefTab.setDim(typedefTabLengthSave); symbols = symbolsSave; if (!symbols) - symbols = new AST.Dsymbols; // lazilly create it + symbols = new AST.Dsymbols; // lazily create it if (level != LVL.global && !tspec && !specifier.scw && !specifier.mod) error("declaration-specifier-seq required"); @@ -1975,38 +1988,33 @@ final class CParser(AST) : Parser!AST bool isalias = true; Identifier idt; - if (auto ts = dt.isTypeStruct()) - { - if (ts.sym.isAnonymous()) - { - // This is a typedef for an anonymous struct-or-union. - // Directly set the ident for the struct-or-union. - ts.sym.ident = id; - isalias = false; - } - idt = ts.sym.ident; - } - else if (auto te = dt.isTypeEnum()) - { - if (te.sym.isAnonymous()) - { - // This is a typedef for an anonymous enum. - te.sym.ident = id; - isalias = false; - } - idt = te.sym.ident; - } - else if (auto tt = dt.isTypeTag()) + if (auto tt = dt.isTypeTag()) { if (!tt.id && id) /* This applies for enums declared as * typedef enum {A} E; + * Or for similar structs and unions. */ tt.id = id; - Specifier spec; - declareTag(tt, spec); + if (tt.members) + { + Specifier spec; + declareTag(tt, spec); + } idt = tt.id; } + else if (auto tt = tspec.isTypeTag()) + { + // The unusual situation of an anonymous typedef struct where the + // first typedef can't be used as its name. + // Just declare it now so we can get a valid id. + if (!tt.id && tt.members) + { + Specifier spec; + declareTag(tt, spec, true); + idt = tt.id; + } + } if (isalias) { //printf("AliasDeclaration %s %s\n", id.toChars(), dt.toChars()); @@ -2035,6 +2043,16 @@ final class CParser(AST) : Parser!AST if (dt.ty == AST.Tvoid) error("`void` has no value"); + if (auto tt = tspec.isTypeTag()) + { + // Anonymous struct being used as a var decl type + if (!tt.id && tt.members && tt.tok != TOK.enum_) + { + Specifier spec; + declareTag(tt, spec); + } + } + AST.Initializer initializer; bool hasInitializer; if (token.value == TOK.assign) @@ -4097,7 +4115,7 @@ final class CParser(AST) : Parser!AST * struct { ... members ... }; * C11 6.7.2.1-13 */ - if (!tt.id && tt.members) + if (!tt.id && tt.members && tt.tok != TOK.enum_) { /* members of anonymous struct are considered members of * the containing struct @@ -4113,17 +4131,19 @@ final class CParser(AST) : Parser!AST /* `struct tag;` and `struct tag { ... };` * always result in a declaration in the current scope */ - // TODO: merge in specifier - auto stag = (tt.tok == TOK.struct_) - ? new AST.StructDeclaration(tt.loc, tt.id, false) - : new AST.UnionDeclaration(tt.loc, tt.id); - stag.members = tt.members; - if (!symbols) - symbols = new AST.Dsymbols(); - auto s = applySpecifier(stag, specifier); - symbols.push(s); + Specifier spec; + declareTag(tt, spec); return; } + if (auto tt = tspec.isTypeTag()) + { + // Declare the tagged type at this point. + if (tt.members) + { + Specifier spec; + declareTag(tt, spec); + } + } while (1) { diff --git a/compiler/test/compilable/imports/imp20499.c b/compiler/test/compilable/imports/imp20499.c new file mode 100644 index 0000000000..7ae74906f7 --- /dev/null +++ b/compiler/test/compilable/imports/imp20499.c @@ -0,0 +1,8 @@ +// https://github.com/dlang/dmd/issues/20499 +typedef struct Foo { + int x; +} *pFoo; + +struct Bar { + struct Foo foo; +}; diff --git a/compiler/test/compilable/nested_struct_20499.c b/compiler/test/compilable/nested_struct_20499.c new file mode 100644 index 0000000000..ec83abde17 --- /dev/null +++ b/compiler/test/compilable/nested_struct_20499.c @@ -0,0 +1,61 @@ +// https://github.com/dlang/dmd/issues/20499 + + +struct Outer { + struct __attribute__((aligned(8))) { + int x; + } n; + enum {A}; + enum {B} b; +}; + +struct Outer2 { + struct __attribute__((aligned(8))) Nested { + int x; + } n; +}; + +const int x = A; +const int y = B; + +struct Outer o = {3}; +_Static_assert(_Alignof(typeof(o.n)) == 8, ""); +_Static_assert(_Alignof(struct Outer) == 8, ""); +_Static_assert(_Alignof(struct Outer2) == 8, ""); +_Static_assert(_Alignof(struct Nested) == 8, ""); + +void test(void){ + struct Outer { + struct __attribute__((aligned(16))) { + int x; + } n; + enum {A=2}; + enum {B=3} b; + }; + + struct Outer2 { + struct __attribute__((aligned(16))) Nested { + int x; + } n; + }; + + const int x = A; + const int y = B; + + struct Outer o = {3}; + _Static_assert(_Alignof(typeof(o.n)) == 16, ""); + _Static_assert(_Alignof(struct Outer) == 16, ""); + _Static_assert(_Alignof(struct Outer2) == 16, ""); + _Static_assert(_Alignof(struct Nested) == 16, ""); +} + +void test2(void){ + const int x = A; + const int y = B; + + struct Outer o = {3}; + _Static_assert(_Alignof(typeof(o.n)) == 8, ""); + _Static_assert(_Alignof(struct Outer) == 8, ""); + _Static_assert(_Alignof(struct Outer2) == 8, ""); + _Static_assert(_Alignof(struct Nested) == 8, ""); +} diff --git a/compiler/test/compilable/struct_decls_20499.c b/compiler/test/compilable/struct_decls_20499.c new file mode 100644 index 0000000000..27f342db4d --- /dev/null +++ b/compiler/test/compilable/struct_decls_20499.c @@ -0,0 +1,287 @@ +// https://github.com/dlang/dmd/issues/20499 + +// +// attribute((aligned())) is so we can tell if attributes are being applied. +// +typedef struct __attribute__((aligned(8))) S { + int x, y; +} S; +_Static_assert(sizeof(struct S) == 8, "sizeof(S)"); +_Static_assert(_Alignof(struct S) == 8, "_Alignof(S)"); + +typedef struct __attribute__((aligned(8))) Foo { + int x, y; +} *pFoo, Foo, FooB; + +_Static_assert(sizeof(struct Foo) == sizeof(struct S), "sizeof(Foo)"); +_Static_assert(_Alignof(struct Foo) == _Alignof(struct S), "_Alignof(Foo)"); +_Static_assert(sizeof(Foo) == sizeof(struct S), "sizeof(Foo)"); +_Static_assert(_Alignof(Foo) == _Alignof(struct S), "_Alignof(Foo)"); +_Static_assert(sizeof(FooB) == sizeof(struct S), "sizeof(FooB)"); +_Static_assert(_Alignof(FooB) == _Alignof(struct S), "_Alignof(FooB)"); + +pFoo pf; +_Static_assert(sizeof(*pf) == sizeof(struct S), "sizeof(*pf)"); +_Static_assert(_Alignof(typeof(*pf)) == _Alignof(struct S), "_Alignof(*pf)"); + +typedef struct __attribute__((aligned(8))) { + int x, y; +} Baz, *pBaz, BazB; +_Static_assert(sizeof(Baz) == sizeof(struct S), "sizeof(Baz)"); +_Static_assert(sizeof(BazB) == sizeof(struct S), "sizeof(BazB)"); +_Static_assert(_Alignof(Baz) == _Alignof(struct S), "_Alignof(Baz)"); +_Static_assert(_Alignof(BazB) == _Alignof(struct S), "_Alignof(BazB)"); + +pBaz pb; +_Static_assert(sizeof(*pb) == sizeof(struct S), "sizeof(*pb)"); +_Static_assert(_Alignof(typeof(*pb)) == _Alignof(struct S), "_Alignof(*pb)"); + +typedef struct __attribute__((aligned(8))) { + int x, y; +} *pTux; +pTux pt; +_Static_assert(sizeof(*pt) == sizeof(struct S), "sizeof(*pt)"); +_Static_assert(_Alignof(typeof(*pt)) == _Alignof(struct S), "_Alignof(*pt)"); + +typedef struct __attribute__((aligned(8))) { + int x, y; +} Qux; +_Static_assert(sizeof(Qux) == sizeof(struct S), "sizeof(FooB)"); +_Static_assert(_Alignof(Qux) == _Alignof(struct S), "_Alignof(FooB)"); + +struct Bar { + struct S foo; +}; +_Static_assert(sizeof(struct Bar) == sizeof(struct S), "sizeof(Bar)"); +_Static_assert(_Alignof(struct Bar) == _Alignof(struct S), "_Alignof(Bar)"); + +typedef struct __attribute__((aligned(8))) { + int x, y; +} *pLux; +pLux pl; +_Static_assert(sizeof(*pl) == sizeof(struct S), "sizeof(*pl)"); +_Static_assert(_Alignof(typeof(*pl)) == _Alignof(struct S), "_Alignof(*pl)"); + + +typedef struct __attribute__((aligned(8))) { + int x, y; +} ****pWux; +pWux pw; +_Static_assert(sizeof(****pw) == sizeof(struct S), "sizeof(****pw)"); +_Static_assert(_Alignof(typeof(****pw)) == _Alignof(struct S), "_Alignof(****pw)"); + +struct __attribute__((aligned(8))) { + int x, y; +} f; +_Static_assert(sizeof(f) == sizeof(struct S), "sizeof(f)"); +_Static_assert(_Alignof(typeof(f)) == _Alignof(struct S), "_Alignof(f)"); + +struct __attribute__((aligned(8))) { + int x, y; +} fa[3]; +_Static_assert(sizeof(fa[0]) == sizeof(struct S), "sizeof(fa[0])"); +_Static_assert(_Alignof(typeof(fa[0])) == _Alignof(struct S), "_Alignof(fa[0])"); + +void locals(void){ + // function local version + // Use different values so we know we aren't just using globals + typedef struct __attribute__((aligned(16))) S { + int x, y[7]; + } S; + _Static_assert(sizeof(struct S) == 32, "sizeof(S)"); + _Static_assert(_Alignof(struct S) == 16, "_Alignof(S)"); + + typedef struct __attribute__((aligned(16))) Foo { + int x, y[7]; + } *pFoo, Foo, FooB; + + _Static_assert(sizeof(struct Foo) == sizeof(struct S), "sizeof(Foo)"); + _Static_assert(_Alignof(struct Foo) == _Alignof(struct S), "_Alignof(Foo)"); + _Static_assert(sizeof(Foo) == sizeof(struct S), "sizeof(Foo)"); + _Static_assert(_Alignof(Foo) == _Alignof(struct S), "_Alignof(Foo)"); + _Static_assert(sizeof(FooB) == sizeof(struct S), "sizeof(FooB)"); + _Static_assert(_Alignof(FooB) == _Alignof(struct S), "_Alignof(FooB)"); + + pFoo pf; + _Static_assert(sizeof(*pf) == sizeof(struct S), "sizeof(*pf)"); + _Static_assert(_Alignof(typeof(*pf)) == _Alignof(struct S), "_Alignof(*pf)"); + + typedef struct __attribute__((aligned(16))) { + int x, y[7]; + } Baz, *pBaz, BazB; + _Static_assert(sizeof(Baz) == sizeof(struct S), "sizeof(Baz)"); + _Static_assert(sizeof(BazB) == sizeof(struct S), "sizeof(BazB)"); + _Static_assert(_Alignof(Baz) == _Alignof(struct S), "_Alignof(Baz)"); + _Static_assert(_Alignof(BazB) == _Alignof(struct S), "_Alignof(BazB)"); + + + pBaz pb; + _Static_assert(sizeof(*pb) == sizeof(struct S), "sizeof(*pb)"); + _Static_assert(_Alignof(typeof(*pb)) == _Alignof(struct S), "_Alignof(*pb)"); + + + typedef struct __attribute__((aligned(16))) { + int x, y[7]; + } *pTux; + pTux pt; + _Static_assert(sizeof(*pt) == sizeof(struct S), "sizeof(*pt)"); + _Static_assert(_Alignof(typeof(*pt)) == _Alignof(struct S), "_Alignof(*pt)"); + + + typedef struct __attribute__((aligned(16))) { + int x, y[7]; + } Qux; + _Static_assert(sizeof(Qux) == sizeof(struct S), "sizeof(FooB)"); + _Static_assert(_Alignof(Qux) == _Alignof(struct S), "_Alignof(FooB)"); + + struct Bar { + struct S foo; + }; + _Static_assert(sizeof(struct Bar) == sizeof(struct S), "sizeof(Bar)"); + _Static_assert(_Alignof(struct Bar) == _Alignof(struct S), "_Alignof(Bar)"); + + typedef struct __attribute__((aligned(16))) { + int x, y[7]; + } *pLux; + pLux pl; + _Static_assert(sizeof(*pl) == sizeof(struct S), "sizeof(*pl)"); + _Static_assert(_Alignof(typeof(*pl)) == _Alignof(struct S), "_Alignof(*pl)"); + + + typedef struct __attribute__((aligned(16))) { + int x, y[7]; + } ****pWux; + pWux pw; + _Static_assert(sizeof(****pw) == sizeof(struct S), "sizeof(****pw)"); + _Static_assert(_Alignof(typeof(****pw)) == _Alignof(struct S), "_Alignof(****pw)"); + + struct __attribute__((aligned(16))) { + int x, y[7]; + } f; + _Static_assert(sizeof(f) == sizeof(struct S), "sizeof(f)"); + _Static_assert(_Alignof(typeof(f)) == _Alignof(struct S), "_Alignof(f)"); + // Verify shadowing works + { + typedef struct __attribute__((aligned(32))) S { + int x, y[15]; + } S; + _Static_assert(sizeof(struct S) == 64, "sizeof(S)"); + _Static_assert(_Alignof(struct S) == 32, "_Alignof(S)"); + + typedef struct __attribute__((aligned(32))) Foo { + int x, y[15]; + } *pFoo, Foo, FooB; + + _Static_assert(sizeof(struct Foo) == sizeof(struct S), "sizeof(Foo)"); + _Static_assert(_Alignof(struct Foo) == _Alignof(struct S), "_Alignof(Foo)"); + _Static_assert(sizeof(Foo) == sizeof(struct S), "sizeof(Foo)"); + _Static_assert(_Alignof(Foo) == _Alignof(struct S), "_Alignof(Foo)"); + _Static_assert(sizeof(FooB) == sizeof(struct S), "sizeof(FooB)"); + _Static_assert(_Alignof(FooB) == _Alignof(struct S), "_Alignof(FooB)"); + + pFoo pf; + _Static_assert(sizeof(*pf) == sizeof(struct S), "sizeof(*pf)"); + _Static_assert(_Alignof(typeof(*pf)) == _Alignof(struct S), "_Alignof(*pf)"); + + typedef struct __attribute__((aligned(32))) { + int x, y[15]; + } Baz, *pBaz, BazB; + _Static_assert(sizeof(Baz) == sizeof(struct S), "sizeof(Baz)"); + _Static_assert(sizeof(BazB) == sizeof(struct S), "sizeof(BazB)"); + _Static_assert(_Alignof(Baz) == _Alignof(struct S), "_Alignof(Baz)"); + _Static_assert(_Alignof(BazB) == _Alignof(struct S), "_Alignof(BazB)"); + + + pBaz pb; + _Static_assert(sizeof(*pb) == sizeof(struct S), "sizeof(*pb)"); + _Static_assert(_Alignof(typeof(*pb)) == _Alignof(struct S), "_Alignof(*pb)"); + + + typedef struct __attribute__((aligned(32))) { + int x, y[15]; + } *pTux; + pTux pt; + _Static_assert(sizeof(*pt) == sizeof(struct S), "sizeof(*pt)"); + _Static_assert(_Alignof(typeof(*pt)) == _Alignof(struct S), "_Alignof(*pt)"); + + + typedef struct __attribute__((aligned(32))) { + int x, y[15]; + } Qux; + _Static_assert(sizeof(Qux) == sizeof(struct S), "sizeof(FooB)"); + _Static_assert(_Alignof(Qux) == _Alignof(struct S), "_Alignof(FooB)"); + + struct Bar { + struct S foo; + }; + _Static_assert(sizeof(struct Bar) == sizeof(struct S), "sizeof(Bar)"); + _Static_assert(_Alignof(struct Bar) == _Alignof(struct S), "_Alignof(Bar)"); + + typedef struct __attribute__((aligned(32))) { + int x, y[15]; + } *pLux; + pLux pl; + _Static_assert(sizeof(*pl) == sizeof(struct S), "sizeof(*pl)"); + _Static_assert(_Alignof(typeof(*pl)) == _Alignof(struct S), "_Alignof(*pl)"); + + + typedef struct __attribute__((aligned(32))) { + int x, y[15]; + } ****pWux; + pWux pw; + _Static_assert(sizeof(****pw) == sizeof(struct S), "sizeof(****pw)"); + _Static_assert(_Alignof(typeof(****pw)) == _Alignof(struct S), "_Alignof(****pw)"); + + struct __attribute__((aligned(32))) { + int x, y[15]; + } f; + _Static_assert(sizeof(f) == sizeof(struct S), "sizeof(f)"); + _Static_assert(_Alignof(typeof(f)) == _Alignof(struct S), "_Alignof(f)"); + } +} + +void globals(void){ + _Static_assert(sizeof(struct S) == 8, "sizeof(S)"); + _Static_assert(_Alignof(struct S) == 8, "_Alignof(S)"); + + _Static_assert(sizeof(struct Foo) == sizeof(struct S), "sizeof(Foo)"); + _Static_assert(_Alignof(struct Foo) == _Alignof(struct S), "_Alignof(Foo)"); + _Static_assert(sizeof(Foo) == sizeof(struct S), "sizeof(Foo)"); + _Static_assert(_Alignof(Foo) == _Alignof(struct S), "_Alignof(Foo)"); + _Static_assert(sizeof(FooB) == sizeof(struct S), "sizeof(FooB)"); + _Static_assert(_Alignof(FooB) == _Alignof(struct S), "_Alignof(FooB)"); + + pFoo pf; + _Static_assert(sizeof(*pf) == sizeof(struct S), "sizeof(*pf)"); + _Static_assert(_Alignof(typeof(*pf)) == _Alignof(struct S), "_Alignof(*pf)"); + + _Static_assert(sizeof(Baz) == sizeof(struct S), "sizeof(Baz)"); + _Static_assert(sizeof(BazB) == sizeof(struct S), "sizeof(BazB)"); + _Static_assert(_Alignof(Baz) == _Alignof(struct S), "_Alignof(Baz)"); + _Static_assert(_Alignof(BazB) == _Alignof(struct S), "_Alignof(BazB)"); + + pBaz pb; + _Static_assert(sizeof(*pb) == sizeof(struct S), "sizeof(*pb)"); + _Static_assert(_Alignof(typeof(*pb)) == _Alignof(struct S), "_Alignof(*pb)"); + + pTux pt; + _Static_assert(sizeof(*pt) == sizeof(struct S), "sizeof(*pt)"); + _Static_assert(_Alignof(typeof(*pt)) == _Alignof(struct S), "_Alignof(*pt)"); + + _Static_assert(sizeof(Qux) == sizeof(struct S), "sizeof(FooB)"); + _Static_assert(_Alignof(Qux) == _Alignof(struct S), "_Alignof(FooB)"); + + _Static_assert(sizeof(struct Bar) == sizeof(struct S), "sizeof(Bar)"); + _Static_assert(_Alignof(struct Bar) == _Alignof(struct S), "_Alignof(Bar)"); + + pLux pl; + _Static_assert(sizeof(*pl) == sizeof(struct S), "sizeof(*pl)"); + _Static_assert(_Alignof(typeof(*pl)) == _Alignof(struct S), "_Alignof(*pl)"); + + + pWux pw; + _Static_assert(sizeof(****pw) == sizeof(struct S), "sizeof(****pw)"); + _Static_assert(_Alignof(typeof(****pw)) == _Alignof(struct S), "_Alignof(****pw)"); + Foo foo = {1, 2, 3}; + struct Foo foo2 = {1, 2, 3}; +} diff --git a/compiler/test/compilable/test20499.d b/compiler/test/compilable/test20499.d new file mode 100644 index 0000000000..9e9e1d2712 --- /dev/null +++ b/compiler/test/compilable/test20499.d @@ -0,0 +1,2 @@ +// https://github.com/dlang/dmd/issues/20499 +import imports.imp20499; diff --git a/compiler/test/compilable/test20963.c b/compiler/test/compilable/test20963.c new file mode 100644 index 0000000000..a5aead13d2 --- /dev/null +++ b/compiler/test/compilable/test20963.c @@ -0,0 +1,12 @@ +// https://github.com/dlang/dmd/issues/20963 + +void cdind() { + struct ABC { + int y; + } *p; + + { + struct ABC { int x; } abc; + abc.x = 1; + } +} diff --git a/compiler/test/fail_compilation/failcstuff3.c b/compiler/test/fail_compilation/failcstuff3.c index f54c942d44..dd07c3e165 100644 --- a/compiler/test/fail_compilation/failcstuff3.c +++ b/compiler/test/fail_compilation/failcstuff3.c @@ -1,7 +1,7 @@ // check importAll analysis of C files /* TEST_OUTPUT: --- -fail_compilation/failcstuff3.c(54): Error: union `failcstuff3.S22061` conflicts with struct `failcstuff3.S22061` at fail_compilation/failcstuff3.c(50) +fail_compilation/failcstuff3.c(54): Error: redeclaration of `S22061` --- */ diff --git a/compiler/test/runnable/exe1.c b/compiler/test/runnable/exe1.c index 104025f295..3f256810fa 100644 --- a/compiler/test/runnable/exe1.c +++ b/compiler/test/runnable/exe1.c @@ -1242,7 +1242,6 @@ void cdind() assert(cbptr->nextread == 4); } -#if 0 // TODO ImportC { struct ABC { char a,b,*l_text; } abc; static struct { int w_doto; struct ABC *w_dotp; } curw,*curwp; @@ -1253,7 +1252,6 @@ void cdind() c = curwp->w_dotp->l_text[curwp->w_doto]&0xFF; assert(c == '2'); } -#endif } void logexp()