From a9efb98285713dac64a35e9eb166119d33d5fdc2 Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Wed, 9 Jun 2021 23:59:31 -0700 Subject: [PATCH] ImportC add simple array initialization --- src/dmd/initsem.d | 41 ++++++++++++++++++++++++++++++++++++++--- src/dmd/todt.d | 16 +++++++++++++++- test/runnable/cstuff2.c | 22 ++++++++++++++++++++++ 3 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 test/runnable/cstuff2.c diff --git a/src/dmd/initsem.d b/src/dmd/initsem.d index 234f155882d3..926b0782a20b 100644 --- a/src/dmd/initsem.d +++ b/src/dmd/initsem.d @@ -559,11 +559,46 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ return i; } - Initializer visitC(CInitializer i) + Initializer visitC(CInitializer ci) { //printf("CInitializer::semantic()\n"); - error(i.loc, "C initializers not supported yet"); - return err(); + t = t.toBasetype(); + auto tsa = t.isTypeSArray(); + if (!tsa) + { + error(ci.loc, "C non-static-array initializers not supported yet"); + return err(); + } + + const uint amax = 0x8000_0000; + bool errors; + auto tn = tsa.nextOf(); + auto dil = ci.initializerList[]; + foreach (di; dil) + { + if (di.designatorList) + { + error(ci.loc, "C designator-list not supported yet"); + return err(); + } + di.initializer = di.initializer.initializerSemantic(sc, tn, needInterpret); + if (di.initializer.isErrorInitializer()) + errors = true; + } + + if (errors) + return err(); + + const sz = tn.size(); + bool overflow; + const max = mulu(dil.length, sz, overflow); + if (overflow || max >= amax) + { + error(ci.loc, "array dimension %llu exceeds max of %llu", ulong(dil.length), ulong(amax / sz)); + return err(); + } + + return ci; } final switch (init.kind) diff --git a/src/dmd/todt.d b/src/dmd/todt.d index e3587b8c5499..c45046d52088 100644 --- a/src/dmd/todt.d +++ b/src/dmd/todt.d @@ -79,6 +79,9 @@ extern (C++) void Initializer_toDt(Initializer init, ref DtBuilder dtb) void visitStruct(StructInitializer si) { + /* The StructInitializer was converted to a StructLiteralExp, + * which is converted to dtb by membersToDt() + */ //printf("StructInitializer.toDt('%s')\n", si.toChars()); assert(0); } @@ -197,6 +200,17 @@ extern (C++) void Initializer_toDt(Initializer init, ref DtBuilder dtb) Expression_toDt(ei.exp, dtb); } + void visitC(CInitializer ci) + { + //printf("CInitializer::semantic()\n"); + auto dil = ci.initializerList[]; + foreach (di; dil) + { + assert(!di.designatorList); + Initializer_toDt(di.initializer, dtb); + } + } + final switch (init.kind) { case InitKind.void_: return visitVoid (cast( VoidInitializer)init); @@ -204,7 +218,7 @@ extern (C++) void Initializer_toDt(Initializer init, ref DtBuilder dtb) case InitKind.struct_: return visitStruct(cast(StructInitializer)init); case InitKind.array: return visitArray (cast( ArrayInitializer)init); case InitKind.exp: return visitExp (cast( ExpInitializer)init); - case InitKind.C_: assert(0); + case InitKind.C_: return visitC (cast( CInitializer)init); } } diff --git a/test/runnable/cstuff2.c b/test/runnable/cstuff2.c new file mode 100644 index 000000000000..79a81ccf70b3 --- /dev/null +++ b/test/runnable/cstuff2.c @@ -0,0 +1,22 @@ + +int printf(const char *, ...); +void exit(int); + +void test1() +{ + static int a[3] = {1, 2, 3}; + if (a[0] != 1 || + a[1] != 2 || + a[2] != 3) + { + printf("error 1\n"); + exit(1); + } +} + +int main() +{ + test1(); + return 0; +} +