From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1873) id C5CAA3858D33; Mon, 26 Jun 2023 00:51:34 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C5CAA3858D33 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1687740694; bh=FdCbaSHtIy/p5BYQhPcvki3gW+Bc7LYfXbt1Hf2mLtg=; h=From:To:Subject:Date:From; b=knaRtAnUQMe2tcTQ4q00GdRyDXlJfmDe1oBO28rvKrQSNTmhre55qbianPVr27eC7 cnxKo5OFOAqjCoiX3//qYmsCrnOmhPSQvyJD9kF7cLpxbFcDtUuzckEUF0P5QvqFDV mwR8zb4+aPtlqYh4kaGlavvDToRKQ1779PAVu7eU= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Iain Buclaw To: gcc-cvs@gcc.gnu.org Subject: [gcc r12-9729] d: Fix crash in d/dmd/root/aav.d:127 dmd_aaGetRvalue from DsymbolTable::lookup X-Act-Checkin: gcc X-Git-Author: Iain Buclaw X-Git-Refname: refs/heads/releases/gcc-12 X-Git-Oldrev: f315d6592d4d313b02eac340b7b4b5e0147e7cb4 X-Git-Newrev: 016047f54713dc601c661ab57c78a26da3759608 Message-Id: <20230626005134.C5CAA3858D33@sourceware.org> Date: Mon, 26 Jun 2023 00:51:34 +0000 (GMT) List-Id: https://gcc.gnu.org/g:016047f54713dc601c661ab57c78a26da3759608 commit r12-9729-g016047f54713dc601c661ab57c78a26da3759608 Author: Iain Buclaw Date: Mon Jun 26 02:29:46 2023 +0200 d: Fix crash in d/dmd/root/aav.d:127 dmd_aaGetRvalue from DsymbolTable::lookup Backports patch from upstream dmd mainline for fixing PR110113. The data being Mem.xrealloc'd contains many Array(T) fields, some of which have self references in their data.ptr field thanks to the smallarray optimization used by Array. Naturally then, the memcpy from old GC data to new retains those self referenced addresses, and the GC marks the old data as "free". Some time later GC.malloc will return a pointer to said "free" data. So now we have two GC references to the same memory. One that is treating the data as an Array(VarDeclaration) in dmd.escape.escapeByStorage, and the other as an AA in the symtab of a dmd.dsymbol.ScopeDsymbol. Fix this memory corruption by not storing the data in a global variable for reuse. If there are no more live references, the GC will free it. PR d/110113 gcc/d/ChangeLog: * dmd/escape.d (checkMutableArguments): Always allocate new buffer for computing escapeBy. gcc/testsuite/ChangeLog: * gdc.test/compilable/test23978.d: New test. Reviewed-on: https://github.com/dlang/dmd/pull/15302 (cherry picked from commit ae3a4cefd855512b10b833a56f275b701bacdb34) Diff: --- gcc/d/dmd/escape.d | 24 +-------------------- gcc/testsuite/gdc.test/compilable/test23978.d | 30 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d index 7c7ba96db0d..ab85f8706ec 100644 --- a/gcc/d/dmd/escape.d +++ b/gcc/d/dmd/escape.d @@ -77,22 +77,7 @@ bool checkMutableArguments(Scope* sc, FuncDeclaration fd, TypeFunction tf, bool isMutable; // true if reference to mutable } - /* Store escapeBy as static data escapeByStorage so we can keep reusing the same - * arrays rather than reallocating them. - */ - __gshared EscapeBy[] escapeByStorage; - auto escapeBy = escapeByStorage; - if (escapeBy.length < len) - { - auto newPtr = cast(EscapeBy*)mem.xrealloc(escapeBy.ptr, len * EscapeBy.sizeof); - // Clear the new section - memset(newPtr + escapeBy.length, 0, (len - escapeBy.length) * EscapeBy.sizeof); - escapeBy = newPtr[0 .. len]; - escapeByStorage = escapeBy; - } - else - escapeBy = escapeBy[0 .. len]; - + auto escapeBy = new EscapeBy[len]; const paramLength = tf.parameterList.length; // Fill in escapeBy[] with arguments[], ethis, and outerVars[] @@ -212,13 +197,6 @@ bool checkMutableArguments(Scope* sc, FuncDeclaration fd, TypeFunction tf, escape(i, eb, false); } - /* Reset the arrays in escapeBy[] so we can reuse them next time through - */ - foreach (ref eb; escapeBy) - { - eb.er.reset(); - } - return errors; } diff --git a/gcc/testsuite/gdc.test/compilable/test23978.d b/gcc/testsuite/gdc.test/compilable/test23978.d new file mode 100644 index 00000000000..cc30f728dee --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23978.d @@ -0,0 +1,30 @@ +// REQUIRED_ARGS: -preview=dip1021 -lowmem +// https://issues.dlang.org/show_bug.cgi?id=23978 + +// Note: this is a memory corruption bug. +// Memory returned by `GC.realloc` retains references to old memory in it, +// mostly because of the smallarray optimization for `Array(T)`. +// If this fails again, it might not be consistent, so try running it multiple times. + +class LUBench { } +void lup(ulong , ulong , int , int = 1) +{ + new LUBench; +} +void lup_3200(ulong iters, ulong flops) +{ + lup(iters, flops, 3200); +} +void raytrace() +{ + struct V + { + float x, y, z; + auto normalize() { } + struct Tid { } + auto spawnLinked() { } + string[] namesByTid; + class MessageBox { } + auto cross() { } + } +}