April 17, 2015
https://issues.dlang.org/show_bug.cgi?id=14459

          Issue ID: 14459
           Summary: String literal merge bug causes incorrect runtime
                    program behavior
           Product: D
           Version: D2
          Hardware: x86
                OS: Mac OS X
            Status: NEW
          Severity: critical
          Priority: P1
         Component: DMD
          Assignee: nobody@puremagic.com
          Reporter: gorox@comcast.net

Created attachment 1514
  --> https://issues.dlang.org/attachment.cgi?id=1514&action=edit
strlit16bug.d

The front end propagates const char* string literals in such a way that backend must merge identical constants or else funny things may happen at runtime.  The DMD backend merges string literals but only caches 16 unique strings, so a carefully crafted program with more than 16 string literals can produce erroneous results.  See attached code, which follows this pattern:

{
    const char* s0 = "hi0";
    const(char)* p0 = s0;
    assert(p0 == s0);
    const char* s1 = "hi1";
    const(char)* p1 = s1;
...
    const char* s15 = "hi15";
    const(char)* p15 = s15;
    assert(p0 == s0);                        // ok
    const char* s16 = "hi16";
    const(char)* p16 = s16;
    assert(p0 == s0);                        // fails
}



This was uncovered while digging into an LDC issue #898 and trying to understand how DMD front end propagates string literals for const char*.

https://github.com/ldc-developers/ldc/issues/898

Output from attached strlit16bug.d

$ dmd --version
DMD64 D Compiler v2.067.0
Copyright (c) 1999-2014 by Digital Mars written by Walter Bright
$ dmd -run strlit16bug
core.exception.AssertError@strlit16bug.d(40): Assertion failure
----------------
5   dmd_runN2D2U4                       0x000000010855ee54 void
strlit16bug.__assert(int) + 44
6   dmd_runN2D2U4                       0x000000010855ee21 _Dmain + 193
7   dmd_runN2D2U4                       0x0000000108573b94
D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv + 40
8   dmd_runN2D2U4                       0x0000000108573ad9 void
rt.dmain2._d_run_main(int, char**, extern (C) int
function(char[][])*).tryExec(scope void delegate()) + 45
9   dmd_runN2D2U4                       0x0000000108573b39 void
rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll()
+ 45
10  dmd_runN2D2U4                       0x0000000108573ad9 void
rt.dmain2._d_run_main(int, char**, extern (C) int
function(char[][])*).tryExec(scope void delegate()) + 45
11  dmd_runN2D2U4                       0x0000000108573a4c _d_run_main + 504
12  dmd_runN2D2U4                       0x000000010855ee6c main + 20
13  libdyld.dylib                       0x00007fff8dd375c9 start + 1
14  ???                                 0x0000000000000001 0x0 + 1
$

--