From 77100f890ceaa04dbe6796a6ff57d1f5276c1f9f Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Sun, 3 May 2009 11:16:54 +0200 Subject: [PATCH] Make static int[] a = [1, 2]; a[0] = 4; not segfault by making the array data ptr a non-const global variable. --- gen/arrays.cpp | 4 +++- gen/toir.cpp | 4 +++- tests/mini/mutablearrayinit.d | 9 +++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 tests/mini/mutablearrayinit.d diff --git a/gen/arrays.cpp b/gen/arrays.cpp index 81accf2d..66abca1a 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -317,7 +317,9 @@ LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit) return constarr; // for dynamic array we need to make a global with the data, so we have a pointer for the dynamic array - LLGlobalVariable* gvar = new LLGlobalVariable(constarr->getType(), true, LLGlobalValue::InternalLinkage, constarr, ".constarray", gIR->module); + // Important: don't make the gvar constant, since this const initializer might + // be used as an initializer for a static T[] - where modifying contents is allowed. + LLGlobalVariable* gvar = new LLGlobalVariable(constarr->getType(), false, LLGlobalValue::InternalLinkage, constarr, ".constarray", gIR->module); LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) }; LLConstant* gep = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); diff --git a/gen/toir.cpp b/gen/toir.cpp index f480f81c..856770ca 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -2405,7 +2405,9 @@ LLConstant* ArrayLiteralExp::toConstElem(IRState* p) return initval; // for dynamic arrays we need to put the initializer in a global, and build a constant dynamic array reference with the .ptr field pointing into this global - LLConstant* globalstore = new LLGlobalVariable(arrtype, true, LLGlobalValue::InternalLinkage, initval, ".dynarrayStorage", p->module); + // Important: don't make the global constant, since this const initializer might + // be used as an initializer for a static T[] - where modifying contents is allowed. + LLConstant* globalstore = new LLGlobalVariable(arrtype, false, LLGlobalValue::InternalLinkage, initval, ".dynarrayStorage", p->module); LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) }; LLConstant* globalstorePtr = llvm::ConstantExpr::getGetElementPtr(globalstore, idxs, 2); diff --git a/tests/mini/mutablearrayinit.d b/tests/mini/mutablearrayinit.d new file mode 100644 index 00000000..95b00cd3 --- /dev/null +++ b/tests/mini/mutablearrayinit.d @@ -0,0 +1,9 @@ +void main() +{ + static int[] b = [1, 2]; + b[0] = 2; + + typedef int[] ia = [1,2]; + static ia a; + a[0] = 5; +} \ No newline at end of file