diff --git a/gen/asmstmt.cpp b/gen/asmstmt.cpp index d616f69549..44b9dd5cfc 100644 --- a/gen/asmstmt.cpp +++ b/gen/asmstmt.cpp @@ -508,10 +508,13 @@ void CompoundAsmStatement_toIR(CompoundAsmStatement *stmt, IRState *p) { // we use a simple static counter to make sure the new end labels are // unique - static size_t uniqueLabelsId = 0; std::ostringstream asmGotoEndLabel; - printLabelName(asmGotoEndLabel, fdmangle, "_llvm_asm_end"); - asmGotoEndLabel << uniqueLabelsId++; + { + static size_t uniqueLabelsId = 0; + std::string suffix = "_llvm_asm_end"; + suffix += std::to_string(uniqueLabelsId++); + printLabelName(asmGotoEndLabel, fdmangle, suffix.c_str()); + } // initialize the setter statement we're going to build auto outSetterStmt = new IRAsmStmt; diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index a299112ca2..f7558238d3 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -1372,8 +1372,10 @@ bool isLLVMUnsigned(Type *t) { void printLabelName(std::ostream &target, const char *func_mangle, const char *label_name) { - target << gTargetMachine->getMCAsmInfo()->getPrivateGlobalPrefix().str() - << func_mangle << "_" << label_name; + // note: quotes needed for Unicode + target << '"' + << gTargetMachine->getMCAsmInfo()->getPrivateGlobalPrefix().str() + << func_mangle << "_" << label_name << '"'; } //////////////////////////////////////////////////////////////////////////////// diff --git a/runtime/druntime/src/core/internal/array/construction.d b/runtime/druntime/src/core/internal/array/construction.d index 40e5a61bbd..567de440fb 100644 --- a/runtime/druntime/src/core/internal/array/construction.d +++ b/runtime/druntime/src/core/internal/array/construction.d @@ -359,6 +359,7 @@ T[] _d_newarrayU(T)(size_t length, bool isShared=false) @trusted if (length == 0 || elemSize == 0) return null; + /+ LDC: don't blind the optimizer; core.checkedint.mulu is basically an intrinsic version (D_InlineAsm_X86) { asm pure nothrow @nogc @@ -379,7 +380,7 @@ T[] _d_newarrayU(T)(size_t length, bool isShared=false) @trusted jnc Lcontinue ; } } - else + else+/ { import core.checkedint : mulu; diff --git a/tests/compilable/gh4927.d b/tests/compilable/gh4927.d new file mode 100644 index 0000000000..b1cf70f196 --- /dev/null +++ b/tests/compilable/gh4927.d @@ -0,0 +1,53 @@ +// RUN: %ldc -c %s + +alias T = int; + +T[] arrayAlloc(size_t size); + +T[] Σ(size_t length) +{ + size_t elemSize = T.sizeof; + size_t arraySize; + + if (length == 0 || elemSize == 0) + return null; + + version (D_InlineAsm_X86) + { + asm pure nothrow @nogc + { + mov EAX, elemSize ; + mul EAX, length ; + mov arraySize, EAX ; + jnc Lcontinue ; + } + } + else version (D_InlineAsm_X86_64) + { + asm pure nothrow @nogc + { + mov RAX, elemSize ; + mul RAX, length ; + mov arraySize, RAX ; + jnc Lcontinue ; + } + } + else + { + import core.checkedint : mulu; + + bool overflow = false; + arraySize = mulu(elemSize, length, overflow); + if (!overflow) + goto Lcontinue; + } + +Loverflow: + assert(0); + +Lcontinue: + auto arr = arrayAlloc(arraySize); + if (!arr.ptr) + goto Loverflow; + return arr; +}