April 17, 2015 [Issue 14459] New: String literal merge bug causes incorrect runtime program behavior | ||||
---|---|---|---|---|
| ||||
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 $ -- |
Copyright © 1999-2021 by the D Language Foundation