Skip to content

Commit 471b5b7

Browse files
authored
fix Issue 22576 - ImportC: cannot implicitly convert expression S(0) of type S to int in an S array (#13437)
1 parent 5ab3bc5 commit 471b5b7

File tree

2 files changed

+57
-6
lines changed

2 files changed

+57
-6
lines changed

src/dmd/initsem.d

+24-6
Original file line numberDiff line numberDiff line change
@@ -744,10 +744,11 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
744744
* Params:
745745
* t = element type
746746
* dim = max number of elements
747+
* simple = true if array of simple elements
747748
* Returns:
748749
* # of elements in array
749750
*/
750-
size_t array(Type t, size_t dim)
751+
size_t array(Type t, size_t dim, ref bool simple)
751752
{
752753
//printf(" type %s i %d dim %d dil.length = %d\n", t.toChars(), cast(int)i, cast(int)dim, cast(int)dil.length);
753754
auto tn = t.nextOf().toBasetype();
@@ -789,14 +790,30 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
789790
if (tnsa && di.initializer.isExpInitializer())
790791
{
791792
// no braces enclosing array initializer, so recurse
792-
array(tnsa, nelems);
793+
array(tnsa, nelems, simple);
793794
}
794795
else if (auto tns = tn.isTypeStruct())
795796
{
796-
if (di.initializer.isExpInitializer())
797+
if (auto ei = di.initializer.isExpInitializer())
797798
{
798799
// no braces enclosing struct initializer
799-
dil[n].initializer = structs(tns);
800+
801+
/* Disambiguate between an exp representing the entire
802+
* struct, and an exp representing the first field of the struct
803+
*/
804+
if (needInterpret)
805+
sc = sc.startCTFE();
806+
ei.exp = ei.exp.expressionSemantic(sc);
807+
ei.exp = resolveProperties(sc, ei.exp);
808+
if (needInterpret)
809+
sc = sc.endCTFE();
810+
if (ei.exp.implicitConvTo(tn))
811+
di.initializer = elem(di.initializer); // the whole struct
812+
else
813+
{
814+
simple = false;
815+
dil[n].initializer = structs(tns); // the first field
816+
}
800817
}
801818
else
802819
dil[n].initializer = elem(di.initializer);
@@ -814,7 +831,8 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
814831
}
815832

816833
size_t dim = tsa.isIncomplete() ? dil.length : cast(size_t)tsa.dim.toInteger();
817-
auto newdim = array(t, dim);
834+
bool simple = true;
835+
auto newdim = array(t, dim, simple);
818836

819837
if (errors)
820838
return err();
@@ -845,7 +863,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
845863
/* If an array of simple elements, replace with an ArrayInitializer
846864
*/
847865
auto tnb = tn.toBasetype();
848-
if (!(tnb.isTypeSArray() || tnb.isTypeStruct()))
866+
if (!tnb.isTypeSArray() && (!tnb.isTypeStruct() || simple))
849867
{
850868
auto ai = new ArrayInitializer(ci.loc);
851869
ai.dim = cast(uint) dil.length;

test/runnable/test22567.c

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// https://issues.dlang.org/show_bug.cgi?id=22576
2+
3+
int printf(const char *s, ...);
4+
void exit(int);
5+
6+
void assert(int b, int line)
7+
{
8+
if (!b)
9+
{
10+
printf("failed test %d\n", line);
11+
exit(1);
12+
}
13+
}
14+
15+
typedef struct S { int x; } S;
16+
17+
void test(int i, S s)
18+
{
19+
int a[1] = { i };
20+
assert(a[0] == 3, 1);
21+
S b[1] = { (S){2} };
22+
assert(b[0].x == 2, 2);
23+
S c[1] = { s };
24+
assert(c[0].x == 7, 3);
25+
}
26+
27+
int main()
28+
{
29+
S s;
30+
s.x = 7;
31+
test(3, s);
32+
return 0;
33+
}

0 commit comments

Comments
 (0)