mirror of
https://github.com/dlang/dmd.git
synced 2025-04-27 05:30:13 +03:00
Merge pull request #15898 from WalterBright/fix24274
fix Issue 24274 - [REG master] ImportC: unrecognized C initializer wi…
This commit is contained in:
commit
603be63f97
3 changed files with 119 additions and 25 deletions
|
@ -572,7 +572,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
|||
printf(" type = %s\n", dsym.type ? dsym.type.toChars() : "null");
|
||||
printf(" stc = x%llx\n", dsym.storage_class);
|
||||
printf(" storage_class = x%llx\n", dsym.storage_class);
|
||||
printf("linkage = %d\n", dsym.linkage);
|
||||
printf("linkage = %d\n", dsym._linkage);
|
||||
//if (strcmp(toChars(), "mul") == 0) assert(0);
|
||||
}
|
||||
//if (semanticRun > PASS.initial)
|
||||
|
|
|
@ -803,9 +803,6 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
|
|||
Loop1:
|
||||
for (size_t index = 0; index < ci.initializerList.length; )
|
||||
{
|
||||
CInitializer cprev;
|
||||
size_t indexprev;
|
||||
L1:
|
||||
DesigInit di = ci.initializerList[index];
|
||||
Designators* dlist = di.designatorList;
|
||||
if (dlist)
|
||||
|
@ -833,15 +830,6 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
|
|||
continue Loop1;
|
||||
}
|
||||
}
|
||||
if (cprev)
|
||||
{
|
||||
/* The peeling didn't work, so unpeel it
|
||||
*/
|
||||
ci = cprev;
|
||||
index = indexprev;
|
||||
di = ci.initializerList[index];
|
||||
goto L2;
|
||||
}
|
||||
error(ci.loc, "`.%s` is not a field of `%s`\n", id.toChars(), sd.toChars());
|
||||
return err();
|
||||
}
|
||||
|
@ -849,18 +837,55 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
|
|||
{
|
||||
if (fieldi == nfields)
|
||||
break;
|
||||
if (index + 1 == ci.initializerList.length && di.initializer.isCInitializer())
|
||||
|
||||
auto ix = di.initializer;
|
||||
|
||||
/* If a C initializer is wrapped in a C initializer, with no designators,
|
||||
* peel off the outer one
|
||||
*/
|
||||
if (ix.isCInitializer())
|
||||
{
|
||||
/* Try peeling off this set of { } and see if it works
|
||||
*/
|
||||
cprev = ci;
|
||||
ci = di.initializer.isCInitializer();
|
||||
indexprev = index;
|
||||
index = 0;
|
||||
goto L1;
|
||||
CInitializer cix = ix.isCInitializer();
|
||||
if (cix.initializerList.length == 1)
|
||||
{
|
||||
DesigInit dix = cix.initializerList[0];
|
||||
if (!dix.designatorList)
|
||||
{
|
||||
Initializer inix = dix.initializer;
|
||||
if (inix.isCInitializer())
|
||||
ix = inix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (auto cix = ix.isCInitializer())
|
||||
{
|
||||
/* ImportC loses the structure from anonymous structs, but this is retained
|
||||
* by the initializer syntax. if a CInitializer has a Designator, it is probably
|
||||
* a nested anonymous struct
|
||||
*/
|
||||
if (cix.initializerList.length)
|
||||
{
|
||||
DesigInit dix = cix.initializerList[0];
|
||||
Designators* dlistx = dix.designatorList;
|
||||
if (dlistx && (*dlistx).length == 1 && (*dlistx)[0].ident)
|
||||
{
|
||||
auto id = (*dlistx)[0].ident;
|
||||
foreach (k, f; sd.fields[]) // linear search for now
|
||||
{
|
||||
if (f.ident == id)
|
||||
{
|
||||
fieldi = k;
|
||||
si.addInit(id, dix.initializer);
|
||||
++fieldi;
|
||||
++index;
|
||||
continue Loop1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
L2:
|
||||
VarDeclaration field;
|
||||
while (1) // skip field if it overlaps with previously seen fields
|
||||
{
|
||||
|
@ -871,10 +896,11 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
|
|||
if (fieldi == nfields)
|
||||
break;
|
||||
}
|
||||
|
||||
auto tn = field.type.toBasetype();
|
||||
auto tnsa = tn.isTypeSArray();
|
||||
auto tns = tn.isTypeStruct();
|
||||
auto ix = di.initializer;
|
||||
|
||||
if (tnsa && ix.isExpInitializer())
|
||||
{
|
||||
ExpInitializer ei = ix.isExpInitializer();
|
||||
|
@ -1013,7 +1039,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
|
|||
}
|
||||
else
|
||||
{
|
||||
error(ci.loc, "unrecognized C initializer `%s`", toChars(ci));
|
||||
error(ci.loc, "unrecognized C initializer `%s` for type `%s`", toChars(ci), t.toChars());
|
||||
return err();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,10 +55,75 @@ struct S3
|
|||
|
||||
void test3()
|
||||
{
|
||||
struct S3 tn = (struct S3) {{0}, 4};
|
||||
struct S3 tn = (struct S3) {{1}, 4};
|
||||
assert(tn.context[0] == 1);
|
||||
assert(tn.context[1] == 0);
|
||||
assert(tn.context[2] == 0);
|
||||
assert(tn.context[3] == 0);
|
||||
assert(tn.id == 4);
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
// https://issues.dlang.org/show_bug.cgi?id=24274
|
||||
|
||||
struct S0
|
||||
{
|
||||
struct
|
||||
{
|
||||
char short_data[24];
|
||||
};
|
||||
int length;
|
||||
};
|
||||
|
||||
void test4()
|
||||
{
|
||||
struct S0 s0 = { {.short_data = {1}}, .length = 2};
|
||||
assert(s0.short_data[0] == 1);
|
||||
assert(s0.length == 2);
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
|
||||
struct S1
|
||||
{
|
||||
struct
|
||||
{
|
||||
int long_data;
|
||||
char short_data[24];
|
||||
};
|
||||
int length;
|
||||
};
|
||||
|
||||
void test5()
|
||||
{
|
||||
struct S1 s1 = { {.short_data = {7}}, .length = 8};
|
||||
assert(s1.long_data == 0);
|
||||
assert(s1.short_data[0] == 7);
|
||||
assert(s1.length == 8);
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
|
||||
struct S6
|
||||
{
|
||||
int abc[4];
|
||||
};
|
||||
|
||||
void test6()
|
||||
{
|
||||
struct S6 s = {{4},5,6,7};
|
||||
assert(s.abc[0] == 4);
|
||||
assert(s.abc[1] == 0);
|
||||
assert(s.abc[2] == 0);
|
||||
assert(s.abc[3] == 0);
|
||||
|
||||
struct S6 t = {4,{5},6,7};
|
||||
assert(t.abc[0] == 4);
|
||||
assert(t.abc[1] == 5);
|
||||
assert(t.abc[2] == 6);
|
||||
assert(t.abc[3] == 7);
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
|
||||
int main()
|
||||
|
@ -66,5 +131,8 @@ int main()
|
|||
test1();
|
||||
test2();
|
||||
test3();
|
||||
test4();
|
||||
test5();
|
||||
test6();
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue