mirror of
https://github.com/dlang/dmd.git
synced 2025-04-25 12:40:11 +03:00
Fix 18127 - ImportC: redeclaration of struct in different translation unit doesn’t check compatibility (#21224)
Fixes: https://github.com/dlang/dmd/issues/18127 When merging struct definitions from different C imports, check that the structs are actually compatible according to the C rules. If they are not, issue an error.
This commit is contained in:
parent
605fb8bf5b
commit
8a8746f318
7 changed files with 661 additions and 4 deletions
|
@ -3091,10 +3091,18 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
|||
StructDeclaration sym = ts.sym;
|
||||
if (sd.isCsymbol() && sym.isCsymbol())
|
||||
{
|
||||
/* This is two structs imported from different C files.
|
||||
* Just ignore sd, the second one. The first one will always
|
||||
* be found when going through the type.
|
||||
*/
|
||||
|
||||
if (!isCCompatible(sd, sym))
|
||||
{
|
||||
// Already issued an error.
|
||||
errorSupplemental(sd.loc, "C %ss with the same name from different imports are merged", sd.kind);
|
||||
}
|
||||
else {
|
||||
/* This is two structs imported from different C files.
|
||||
* Just ignore sd, the second one. The first one will always
|
||||
* be found when going through the type.
|
||||
*/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3134,6 +3142,234 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
|||
//printf("-StructDeclaration::semantic(this=%p, '%s', sizeok = %d)\n", sd, sd.toPrettyChars(), sd.sizeok);
|
||||
}
|
||||
|
||||
//
|
||||
// Checks if two structs are compatible
|
||||
// Implements the rules according to C23 6.2.7
|
||||
//
|
||||
static bool isCCompatible(StructDeclaration a, StructDeclaration b)
|
||||
{
|
||||
// Get the name of a type, while avoiding exposing "__tagXXX" anonymous structs
|
||||
static const(char)* typeName(Type t)
|
||||
{
|
||||
if (TypeStruct ts = t.isTypeStruct())
|
||||
{
|
||||
if (ts.sym.ident.toString().startsWith("__tag"))
|
||||
return ts.sym.isUnionDeclaration() ? "(anonymous union)".ptr: "(anonymous struct)".ptr;
|
||||
}
|
||||
return t.toChars();
|
||||
}
|
||||
|
||||
void incompatError()
|
||||
{
|
||||
.error(a.loc, "%s `%s` already exists with an incompatible definition.",
|
||||
a.kind, typeName(a.type));
|
||||
errorSupplemental(b.loc, "previously declared here");
|
||||
}
|
||||
|
||||
|
||||
// For recursive calls into unnamed structs (so Type.equals() doesn't work).
|
||||
static bool isCCompatibleUnnamedStruct(Type a, Type b)
|
||||
{
|
||||
TypeStruct ats = a.isTypeStruct();
|
||||
if (!ats) return false;
|
||||
TypeStruct bts = b.isTypeStruct();
|
||||
if (!bts) return false;
|
||||
// Hack, anonymous structs within a struct are given
|
||||
// an anonymous id starting with __tag.
|
||||
if (!ats.sym.ident.toString().startsWith("__tag"))
|
||||
return false;
|
||||
if (!bts.sym.ident.toString().startsWith("__tag"))
|
||||
return false;
|
||||
return isCCompatible(ats.sym, bts.sym);
|
||||
}
|
||||
|
||||
if (a.fields.length != b.fields.length)
|
||||
{
|
||||
incompatError();
|
||||
errorSupplemental(a.loc, "`%s` has %zu field(s) while `%s` has %zu field(s)",
|
||||
a.toPrettyChars(), a.fields.length, b.toPrettyChars(), b.fields.length);
|
||||
return false;
|
||||
}
|
||||
// both are structs or both are unions
|
||||
if ((a.isUnionDeclaration() is null) != (b.isUnionDeclaration() is null))
|
||||
{
|
||||
incompatError();
|
||||
errorSupplemental(a.loc, "`%s` is a %s while `%s` is a %s",
|
||||
a.toPrettyChars(), a.kind, b.toPrettyChars(), b.kind);
|
||||
return false;
|
||||
}
|
||||
if (a.alignment != b.alignment)
|
||||
{
|
||||
incompatError();
|
||||
errorSupplemental(a.loc, "`%s` has different alignment or packing", a.toPrettyChars());
|
||||
if (a.alignment.isDefault() && ! b.alignment.isDefault())
|
||||
{
|
||||
errorSupplemental(a.loc, "`%s` alignment: default", a.toPrettyChars());
|
||||
errorSupplemental(b.loc, "`%s` alignment: %u",
|
||||
b.toPrettyChars(), cast(uint)b.alignment.get());
|
||||
}
|
||||
else if (!a.alignment.isDefault() && b.alignment.isDefault())
|
||||
{
|
||||
errorSupplemental(a.loc, "`%s` alignment: %u",
|
||||
a.toPrettyChars(), cast(uint)a.alignment.get());
|
||||
errorSupplemental(b.loc, "`%s` alignment: default",
|
||||
b.toPrettyChars());
|
||||
}
|
||||
else if (a.alignment.get() != b.alignment.get())
|
||||
{
|
||||
errorSupplemental(a.loc, "`%s` alignment: %u",
|
||||
a.toPrettyChars(), cast(uint)a.alignment.get());
|
||||
errorSupplemental(b.loc, "`%s` alignment: %u",
|
||||
b.toPrettyChars(), cast(uint)b.alignment.get());
|
||||
}
|
||||
if (a.alignment.isPack() != b.alignment.isPack())
|
||||
{
|
||||
errorSupplemental(a.loc, "`%s` packed: %s",
|
||||
a.toPrettyChars(), a.alignment.isPack()?"true".ptr:"false".ptr);
|
||||
errorSupplemental(b.loc, "`%s` packed: %s",
|
||||
b.toPrettyChars(), b.alignment.isPack()?"true".ptr:"false".ptr);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
foreach (size_t i, VarDeclaration a_field; a.fields[])
|
||||
{
|
||||
VarDeclaration b_field = b.fields[i];
|
||||
//
|
||||
// — there shall be a one-to-one correspondence between
|
||||
// their members such that each pair of corresponding
|
||||
// members are declared with compatible types;
|
||||
//
|
||||
if (!a_field.type.equals(b_field.type) && !isCCompatibleUnnamedStruct(a_field.type, b_field.type))
|
||||
{
|
||||
// Already errored, just bail
|
||||
incompatError();
|
||||
if (a_field.type.isTypeError()) return false;
|
||||
if (b_field.type.isTypeError()) return false;
|
||||
|
||||
errorSupplemental(a_field.loc, "Field %zu differs in type", i);
|
||||
errorSupplemental(a_field.loc, "typeof(%s): %s",
|
||||
a_field.toChars(), typeName(a_field.type));
|
||||
errorSupplemental(b_field.loc, "typeof(%s): %s",
|
||||
b_field.toChars(), typeName(b_field.type));
|
||||
return false;
|
||||
}
|
||||
//
|
||||
// — if one member of the pair is declared with an
|
||||
// alignment specifier, the second is declared with an
|
||||
// equivalent alignment specifier;
|
||||
//
|
||||
if (a_field.alignment != b_field.alignment)
|
||||
{
|
||||
incompatError();
|
||||
errorSupplemental(a_field.loc, "Field %zu differs in alignment or packing", i);
|
||||
if (a_field.alignment.isDefault() && ! b_field.alignment.isDefault())
|
||||
{
|
||||
errorSupplemental(a_field.loc, "`%s.%s` alignment: default",
|
||||
a.toPrettyChars(),a_field.toChars());
|
||||
errorSupplemental(b_field.loc, "`%s.%s` alignment: %u",
|
||||
b.toPrettyChars(), b_field.toChars(), cast(uint)b_field.alignment.get());
|
||||
}
|
||||
else if (!a_field.alignment.isDefault() && b_field.alignment.isDefault())
|
||||
{
|
||||
errorSupplemental(a_field.loc, "`%s.%s` alignment: %u",
|
||||
a.toPrettyChars(), a_field.toChars(), cast(uint)a_field.alignment.get());
|
||||
errorSupplemental(b_field.loc, "`%s.%s` alignment: default",
|
||||
b.toPrettyChars(), b_field.toChars());
|
||||
}
|
||||
else if (a_field.alignment.get() != b_field.alignment.get())
|
||||
{
|
||||
errorSupplemental(a_field.loc, "`%s.%s` alignment: %u",
|
||||
a.toPrettyChars(), a_field.toChars(),
|
||||
cast(uint)a_field.alignment.get());
|
||||
errorSupplemental(b_field.loc, "`%s.%s` alignment: %u",
|
||||
b.toPrettyChars(), b_field.toChars(),
|
||||
cast(uint)b_field.alignment.get());
|
||||
}
|
||||
if (a_field.alignment.isPack() != b_field.alignment.isPack())
|
||||
{
|
||||
errorSupplemental(a_field.loc, "`%s.%s` packed: %s",
|
||||
a.toPrettyChars(), a_field.toChars(),
|
||||
a_field.alignment.isPack()?"true".ptr:"false".ptr);
|
||||
errorSupplemental(b_field.loc, "`%s.%s` packed: %s",
|
||||
b.toPrettyChars(), b_field.toChars(),
|
||||
b_field.alignment.isPack()?"true".ptr:"false".ptr);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//
|
||||
// - and, if one member of the pair is declared with a
|
||||
// name, the second is declared with the same name.
|
||||
//
|
||||
if (a_field.ident.isAnonymous())
|
||||
{
|
||||
if (!b_field.ident.isAnonymous())
|
||||
{
|
||||
incompatError();
|
||||
errorSupplemental(a_field.loc, "Field %zu differs in name", i);
|
||||
errorSupplemental(a_field.loc, "(anonymous)", a_field.ident.toChars());
|
||||
errorSupplemental(b_field.loc, "%s", b_field.ident.toChars());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (b_field.ident.isAnonymous())
|
||||
{
|
||||
incompatError();
|
||||
errorSupplemental(a_field.loc, "Field %zu differs in name", i);
|
||||
errorSupplemental(a_field.loc, "%s", a_field.ident.toChars());
|
||||
errorSupplemental(b_field.loc, "(anonymous)");
|
||||
return false;
|
||||
}
|
||||
else if (a_field.ident != b_field.ident)
|
||||
{
|
||||
incompatError();
|
||||
errorSupplemental(a_field.loc, "Field %zu differs in name", i);
|
||||
errorSupplemental(a_field.loc, "%s", a_field.ident.toChars());
|
||||
errorSupplemental(b_field.loc, "%s", b_field.ident.toChars());
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// For two structures or unions, corresponding bit-fields shall have the same widths.
|
||||
//
|
||||
BitFieldDeclaration bfa = a_field.isBitFieldDeclaration();
|
||||
BitFieldDeclaration bfb = b_field.isBitFieldDeclaration();
|
||||
if ((bfa is null) != (bfb is null))
|
||||
{
|
||||
incompatError();
|
||||
errorSupplemental(a_field.loc, "Field %zu differs in being a bitfield", i);
|
||||
if (bfa is null)
|
||||
{
|
||||
errorSupplemental(a_field.loc, "`%s.%s` is not a bitfield",
|
||||
a.toPrettyChars(), a_field.toChars());
|
||||
errorSupplemental(b_field.loc, "`%s.%s` is a bitfield",
|
||||
b.toPrettyChars(), b_field.toChars());
|
||||
}
|
||||
else if (bfb is null)
|
||||
{
|
||||
errorSupplemental(a_field.loc, "`%s.%s` *is a bitfield",
|
||||
a.toPrettyChars(), a_field.toChars());
|
||||
errorSupplemental(b_field.loc, "`%s.%s` is not a bitfield",
|
||||
b.toPrettyChars(), b_field.toChars());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (bfa !is null && bfb !is null)
|
||||
{
|
||||
if (bfa.fieldWidth != bfb.fieldWidth)
|
||||
{
|
||||
incompatError();
|
||||
errorSupplemental(a_field.loc, "Field %zu differs in bitfield width", i);
|
||||
errorSupplemental(a_field.loc, "`%s.%s`: %u",
|
||||
a.toPrettyChars(), a_field.toChars(), bfa.fieldWidth);
|
||||
errorSupplemental(b_field.loc, "`%s.%s`: %u",
|
||||
b.toPrettyChars(), b_field.toChars(), bfb.fieldWidth);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void interfaceSemantic(ClassDeclaration cd)
|
||||
{
|
||||
cd.vtblInterfaces = new BaseClasses();
|
||||
|
|
74
compiler/test/compilable/imports/imp18127a.c
Normal file
74
compiler/test/compilable/imports/imp18127a.c
Normal file
|
@ -0,0 +1,74 @@
|
|||
// https://github.com/dlang/dmd/issues/18127
|
||||
union struct_or_union {
|
||||
int x;
|
||||
};
|
||||
|
||||
struct S_n_fields {
|
||||
int x, y;
|
||||
};
|
||||
|
||||
struct S_types {
|
||||
float x;
|
||||
};
|
||||
|
||||
struct S_names {
|
||||
float x;
|
||||
};
|
||||
|
||||
struct B {
|
||||
int x;
|
||||
};
|
||||
|
||||
struct S_b {
|
||||
struct B b;
|
||||
};
|
||||
|
||||
struct S_contains_anon_named {
|
||||
struct {
|
||||
int x;
|
||||
} a;
|
||||
};
|
||||
|
||||
struct S_contains_anon_unnamed {
|
||||
struct {
|
||||
int x;
|
||||
};
|
||||
};
|
||||
|
||||
struct S_bitfields_mismatch1 {
|
||||
unsigned x: 3;
|
||||
unsigned y: 1;
|
||||
};
|
||||
struct S_bitfields_mismatch2 {
|
||||
unsigned x;
|
||||
unsigned y: 1;
|
||||
};
|
||||
|
||||
struct S_bitfields_widths {
|
||||
unsigned x: 3;
|
||||
unsigned y: 1;
|
||||
};
|
||||
|
||||
struct S_bitfields_anon {
|
||||
unsigned x: 3;
|
||||
unsigned : 1;
|
||||
};
|
||||
|
||||
struct S_alignas {
|
||||
_Alignas(8) float x;
|
||||
};
|
||||
struct S_aligned {
|
||||
float x;
|
||||
}__attribute__((aligned(8)));
|
||||
|
||||
struct __attribute__((packed)) S_pack_1 {
|
||||
float x;
|
||||
char c;
|
||||
};
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct S_pack_2 {
|
||||
float x;
|
||||
char c;
|
||||
};
|
||||
#pragma pack(pop)
|
74
compiler/test/compilable/imports/imp18127b.c
Normal file
74
compiler/test/compilable/imports/imp18127b.c
Normal file
|
@ -0,0 +1,74 @@
|
|||
// https://github.com/dlang/dmd/issues/18127
|
||||
union struct_or_union {
|
||||
int x;
|
||||
};
|
||||
|
||||
struct S_n_fields {
|
||||
int x, y;
|
||||
};
|
||||
|
||||
struct S_types {
|
||||
float x;
|
||||
};
|
||||
|
||||
struct S_names {
|
||||
float x;
|
||||
};
|
||||
|
||||
struct B {
|
||||
int x;
|
||||
};
|
||||
|
||||
struct S_b {
|
||||
struct B b;
|
||||
};
|
||||
|
||||
struct S_contains_anon_named {
|
||||
struct {
|
||||
int x;
|
||||
} a;
|
||||
};
|
||||
|
||||
struct S_contains_anon_unnamed {
|
||||
struct {
|
||||
int x;
|
||||
};
|
||||
};
|
||||
|
||||
struct S_bitfields_mismatch1 {
|
||||
unsigned x: 3;
|
||||
unsigned y: 1;
|
||||
};
|
||||
struct S_bitfields_mismatch2 {
|
||||
unsigned x;
|
||||
unsigned y: 1;
|
||||
};
|
||||
|
||||
struct S_bitfields_widths {
|
||||
unsigned x: 3;
|
||||
unsigned y: 1;
|
||||
};
|
||||
|
||||
struct S_bitfields_anon {
|
||||
unsigned x: 3;
|
||||
unsigned : 1;
|
||||
};
|
||||
|
||||
struct S_alignas {
|
||||
_Alignas(8) float x;
|
||||
};
|
||||
struct S_aligned {
|
||||
float x;
|
||||
}__attribute__((aligned(8)));
|
||||
|
||||
struct __attribute__((packed)) S_pack_1 {
|
||||
float x;
|
||||
char c;
|
||||
};
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct S_pack_2 {
|
||||
float x;
|
||||
char c;
|
||||
};
|
||||
#pragma pack(pop)
|
4
compiler/test/compilable/test18127.d
Normal file
4
compiler/test/compilable/test18127.d
Normal file
|
@ -0,0 +1,4 @@
|
|||
// https://github.com/dlang/dmd/issues/18127
|
||||
|
||||
import imports.imp18127a;
|
||||
import imports.imp18127b;
|
83
compiler/test/fail_compilation/imports/imp18127a.c
Normal file
83
compiler/test/fail_compilation/imports/imp18127a.c
Normal file
|
@ -0,0 +1,83 @@
|
|||
// https://github.com/dlang/dmd/issues/18127
|
||||
// union in here, struct in other
|
||||
union struct_or_union {
|
||||
int x;
|
||||
};
|
||||
|
||||
// mismatching number of fields
|
||||
struct S_n_fields {
|
||||
int x, y;
|
||||
};
|
||||
|
||||
// mismatched types
|
||||
struct S_types {
|
||||
float x;
|
||||
};
|
||||
|
||||
// mismatched names
|
||||
struct S_names {
|
||||
float x;
|
||||
};
|
||||
|
||||
struct B {
|
||||
int x;
|
||||
};
|
||||
|
||||
// Contains a struct that is incompatible
|
||||
struct S_b {
|
||||
struct B b;
|
||||
};
|
||||
|
||||
// mismatched anonymous struct
|
||||
struct S_contains_anon_named {
|
||||
struct {
|
||||
int x;
|
||||
} a;
|
||||
};
|
||||
|
||||
struct S_contains_anon_unnamed {
|
||||
struct {
|
||||
int x;
|
||||
};
|
||||
};
|
||||
|
||||
// bitfields
|
||||
struct S_bitfields_mismatch1 {
|
||||
unsigned x: 3;
|
||||
unsigned y: 1;
|
||||
};
|
||||
struct S_bitfields_mismatch2 {
|
||||
unsigned x;
|
||||
unsigned y: 1;
|
||||
};
|
||||
|
||||
struct S_bitfields_widths {
|
||||
unsigned x: 3;
|
||||
unsigned y: 1;
|
||||
};
|
||||
|
||||
struct S_bitfields_anon {
|
||||
unsigned x: 3;
|
||||
unsigned : 1;
|
||||
};
|
||||
|
||||
// mismatched alignment
|
||||
struct S_alignas {
|
||||
_Alignas(8) float x;
|
||||
};
|
||||
struct S_aligned {
|
||||
float x;
|
||||
}__attribute__((aligned(8)));
|
||||
|
||||
// mismatched packing
|
||||
struct __attribute__((packed)) S_pack_1 {
|
||||
float x;
|
||||
char c;
|
||||
};
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct S_pack_2 {
|
||||
float x;
|
||||
char c;
|
||||
};
|
||||
#pragma pack(pop)
|
80
compiler/test/fail_compilation/imports/imp18127b.c
Normal file
80
compiler/test/fail_compilation/imports/imp18127b.c
Normal file
|
@ -0,0 +1,80 @@
|
|||
// https://github.com/dlang/dmd/issues/18127
|
||||
// struct in here, union in other
|
||||
struct struct_or_union {
|
||||
int x;
|
||||
};
|
||||
|
||||
// mismatching number of fields
|
||||
struct S_n_fields {
|
||||
int x;
|
||||
};
|
||||
|
||||
// mismatched types
|
||||
struct S_types {
|
||||
int x;
|
||||
};
|
||||
|
||||
// mismatched names
|
||||
struct S_names {
|
||||
float y;
|
||||
};
|
||||
|
||||
struct B {
|
||||
float x;
|
||||
};
|
||||
|
||||
// Contains a struct that is incompatible
|
||||
struct S_b {
|
||||
struct B b;
|
||||
};
|
||||
|
||||
// mismatched anonymous struct
|
||||
struct S_contains_anon_named {
|
||||
struct {
|
||||
float x;
|
||||
} a;
|
||||
};
|
||||
|
||||
struct S_contains_anon_unnamed {
|
||||
struct {
|
||||
float x;
|
||||
};
|
||||
};
|
||||
|
||||
// bitfields
|
||||
struct S_bitfields_mismatch1 {
|
||||
unsigned x: 3;
|
||||
unsigned y;
|
||||
};
|
||||
struct S_bitfields_mismatch2 {
|
||||
unsigned x: 3;
|
||||
unsigned y: 1;
|
||||
};
|
||||
|
||||
struct S_bitfields_widths {
|
||||
unsigned x: 3;
|
||||
unsigned y: 2;
|
||||
};
|
||||
|
||||
struct S_bitfields_anon {
|
||||
unsigned x: 3;
|
||||
unsigned y: 1;
|
||||
};
|
||||
|
||||
// mismatched alignment
|
||||
struct S_alignas {
|
||||
float x;
|
||||
};
|
||||
struct S_aligned {
|
||||
float x;
|
||||
}__attribute__((aligned(4)));
|
||||
|
||||
// mismatched packing
|
||||
struct S_pack_1 {
|
||||
float x;
|
||||
char c;
|
||||
};
|
||||
struct S_pack_2 {
|
||||
float x;
|
||||
char c;
|
||||
};
|
106
compiler/test/fail_compilation/test18127.d
Normal file
106
compiler/test/fail_compilation/test18127.d
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/imports/imp18127b.c(3): Error: struct `struct_or_union` already exists with an incompatible definition.
|
||||
fail_compilation/imports/imp18127a.c(3): previously declared here
|
||||
fail_compilation/imports/imp18127b.c(3): `imp18127b.struct_or_union` is a struct while `imp18127a.struct_or_union` is a union
|
||||
fail_compilation/imports/imp18127b.c(3): C structs with the same name from different imports are merged
|
||||
fail_compilation/imports/imp18127b.c(8): Error: struct `S_n_fields` already exists with an incompatible definition.
|
||||
fail_compilation/imports/imp18127a.c(8): previously declared here
|
||||
fail_compilation/imports/imp18127b.c(8): `imp18127b.S_n_fields` has 1 field(s) while `imp18127a.S_n_fields` has 2 field(s)
|
||||
fail_compilation/imports/imp18127b.c(8): C structs with the same name from different imports are merged
|
||||
fail_compilation/imports/imp18127b.c(13): Error: struct `S_types` already exists with an incompatible definition.
|
||||
fail_compilation/imports/imp18127a.c(13): previously declared here
|
||||
fail_compilation/imports/imp18127b.c(14): Field 0 differs in type
|
||||
fail_compilation/imports/imp18127b.c(14): typeof(x): int
|
||||
fail_compilation/imports/imp18127a.c(14): typeof(x): float
|
||||
fail_compilation/imports/imp18127b.c(13): C structs with the same name from different imports are merged
|
||||
fail_compilation/imports/imp18127b.c(18): Error: struct `S_names` already exists with an incompatible definition.
|
||||
fail_compilation/imports/imp18127a.c(18): previously declared here
|
||||
fail_compilation/imports/imp18127b.c(19): Field 0 differs in name
|
||||
fail_compilation/imports/imp18127b.c(19): y
|
||||
fail_compilation/imports/imp18127a.c(19): x
|
||||
fail_compilation/imports/imp18127b.c(18): C structs with the same name from different imports are merged
|
||||
fail_compilation/imports/imp18127b.c(22): Error: struct `B` already exists with an incompatible definition.
|
||||
fail_compilation/imports/imp18127a.c(22): previously declared here
|
||||
fail_compilation/imports/imp18127b.c(23): Field 0 differs in type
|
||||
fail_compilation/imports/imp18127b.c(23): typeof(x): float
|
||||
fail_compilation/imports/imp18127a.c(23): typeof(x): int
|
||||
fail_compilation/imports/imp18127b.c(22): C structs with the same name from different imports are merged
|
||||
fail_compilation/imports/imp18127b.c(27): Error: struct `S_b` already exists with an incompatible definition.
|
||||
fail_compilation/imports/imp18127a.c(27): previously declared here
|
||||
fail_compilation/imports/imp18127b.c(27): C structs with the same name from different imports are merged
|
||||
fail_compilation/imports/imp18127b.c(33): Error: struct `(anonymous struct)` already exists with an incompatible definition.
|
||||
fail_compilation/imports/imp18127a.c(33): previously declared here
|
||||
fail_compilation/imports/imp18127b.c(34): Field 0 differs in type
|
||||
fail_compilation/imports/imp18127b.c(34): typeof(x): float
|
||||
fail_compilation/imports/imp18127a.c(34): typeof(x): int
|
||||
fail_compilation/imports/imp18127b.c(32): Error: struct `S_contains_anon_named` already exists with an incompatible definition.
|
||||
fail_compilation/imports/imp18127a.c(32): previously declared here
|
||||
fail_compilation/imports/imp18127b.c(35): Field 0 differs in type
|
||||
fail_compilation/imports/imp18127b.c(35): typeof(a): (anonymous struct)
|
||||
fail_compilation/imports/imp18127a.c(35): typeof(a): (anonymous struct)
|
||||
fail_compilation/imports/imp18127b.c(32): C structs with the same name from different imports are merged
|
||||
fail_compilation/imports/imp18127b.c(38): Error: struct `S_contains_anon_unnamed` already exists with an incompatible definition.
|
||||
fail_compilation/imports/imp18127a.c(38): previously declared here
|
||||
fail_compilation/imports/imp18127b.c(40): Field 0 differs in type
|
||||
fail_compilation/imports/imp18127b.c(40): typeof(x): float
|
||||
fail_compilation/imports/imp18127a.c(40): typeof(x): int
|
||||
fail_compilation/imports/imp18127b.c(38): C structs with the same name from different imports are merged
|
||||
fail_compilation/imports/imp18127b.c(45): Error: struct `S_bitfields_mismatch1` already exists with an incompatible definition.
|
||||
fail_compilation/imports/imp18127a.c(45): previously declared here
|
||||
fail_compilation/imports/imp18127b.c(47): Field 1 differs in being a bitfield
|
||||
fail_compilation/imports/imp18127b.c(47): `imp18127b.S_bitfields_mismatch1.y` is not a bitfield
|
||||
fail_compilation/imports/imp18127a.c(47): `imp18127a.S_bitfields_mismatch1.y` is a bitfield
|
||||
fail_compilation/imports/imp18127b.c(45): C structs with the same name from different imports are merged
|
||||
fail_compilation/imports/imp18127b.c(49): Error: struct `S_bitfields_mismatch2` already exists with an incompatible definition.
|
||||
fail_compilation/imports/imp18127a.c(49): previously declared here
|
||||
fail_compilation/imports/imp18127b.c(50): Field 0 differs in being a bitfield
|
||||
fail_compilation/imports/imp18127b.c(50): `imp18127b.S_bitfields_mismatch2.x` *is a bitfield
|
||||
fail_compilation/imports/imp18127a.c(50): `imp18127a.S_bitfields_mismatch2.x` is not a bitfield
|
||||
fail_compilation/imports/imp18127b.c(49): C structs with the same name from different imports are merged
|
||||
fail_compilation/imports/imp18127b.c(54): Error: struct `S_bitfields_widths` already exists with an incompatible definition.
|
||||
fail_compilation/imports/imp18127a.c(54): previously declared here
|
||||
fail_compilation/imports/imp18127b.c(56): Field 1 differs in bitfield width
|
||||
fail_compilation/imports/imp18127b.c(56): `imp18127b.S_bitfields_widths.y`: 2
|
||||
fail_compilation/imports/imp18127a.c(56): `imp18127a.S_bitfields_widths.y`: 1
|
||||
fail_compilation/imports/imp18127b.c(54): C structs with the same name from different imports are merged
|
||||
fail_compilation/imports/imp18127b.c(59): Error: struct `S_bitfields_anon` already exists with an incompatible definition.
|
||||
fail_compilation/imports/imp18127a.c(59): previously declared here
|
||||
fail_compilation/imports/imp18127b.c(61): Field 1 differs in name
|
||||
fail_compilation/imports/imp18127b.c(61): y
|
||||
fail_compilation/imports/imp18127a.c(61): (anonymous)
|
||||
fail_compilation/imports/imp18127b.c(59): C structs with the same name from different imports are merged
|
||||
fail_compilation/imports/imp18127b.c(65): Error: struct `S_alignas` already exists with an incompatible definition.
|
||||
fail_compilation/imports/imp18127a.c(65): previously declared here
|
||||
fail_compilation/imports/imp18127b.c(66): Field 0 differs in alignment or packing
|
||||
fail_compilation/imports/imp18127b.c(66): `imp18127b.S_alignas.x` alignment: default
|
||||
fail_compilation/imports/imp18127a.c(66): `imp18127a.S_alignas.x` alignment: 8
|
||||
fail_compilation/imports/imp18127b.c(65): C structs with the same name from different imports are merged
|
||||
fail_compilation/imports/imp18127b.c(68): Error: struct `S_aligned` already exists with an incompatible definition.
|
||||
fail_compilation/imports/imp18127a.c(68): previously declared here
|
||||
fail_compilation/imports/imp18127b.c(68): `imp18127b.S_aligned` has different alignment or packing
|
||||
fail_compilation/imports/imp18127b.c(68): `imp18127b.S_aligned` alignment: 4
|
||||
fail_compilation/imports/imp18127a.c(68): `imp18127a.S_aligned` alignment: 8
|
||||
fail_compilation/imports/imp18127b.c(68): C structs with the same name from different imports are merged
|
||||
fail_compilation/imports/imp18127b.c(73): Error: struct `S_pack_1` already exists with an incompatible definition.
|
||||
fail_compilation/imports/imp18127a.c(73): previously declared here
|
||||
fail_compilation/imports/imp18127b.c(73): `imp18127b.S_pack_1` has different alignment or packing
|
||||
fail_compilation/imports/imp18127b.c(73): `imp18127b.S_pack_1` alignment: default
|
||||
fail_compilation/imports/imp18127a.c(73): `imp18127a.S_pack_1` alignment: 1
|
||||
fail_compilation/imports/imp18127b.c(73): `imp18127b.S_pack_1` packed: false
|
||||
fail_compilation/imports/imp18127a.c(73): `imp18127a.S_pack_1` packed: true
|
||||
fail_compilation/imports/imp18127b.c(73): C structs with the same name from different imports are merged
|
||||
fail_compilation/imports/imp18127b.c(77): Error: struct `S_pack_2` already exists with an incompatible definition.
|
||||
fail_compilation/imports/imp18127a.c(79): previously declared here
|
||||
fail_compilation/imports/imp18127b.c(77): `imp18127b.S_pack_2` has different alignment or packing
|
||||
fail_compilation/imports/imp18127b.c(77): `imp18127b.S_pack_2` alignment: default
|
||||
fail_compilation/imports/imp18127a.c(79): `imp18127a.S_pack_2` alignment: 1
|
||||
fail_compilation/imports/imp18127b.c(77): C structs with the same name from different imports are merged
|
||||
---
|
||||
*/
|
||||
|
||||
// https://github.com/dlang/dmd/issues/18127
|
||||
|
||||
import imports.imp18127a;
|
||||
import imports.imp18127b;
|
Loading…
Add table
Add a link
Reference in a new issue