Skip to content

Commit

Permalink
Fix version with NULLPTR in JSON output
Browse files Browse the repository at this point in the history
global._version has been changed at some point to an
null-terminated string. However, its type was still a D string. Some
parts of the code base were updated to do `.length - 1`, but other like
the `compilerInfo` were forgotten. This change remedies this and:
- removes null terminator from the D string of _version
- initializes versionNumber directly and avoid the use of a __gshared
  global
  • Loading branch information
wilzbach committed Aug 28, 2020
1 parent 5e7ccd9 commit e2c26e8
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 35 deletions.
5 changes: 3 additions & 2 deletions src/dmd/backend/elfobj.d
Original file line number Diff line number Diff line change
Expand Up @@ -1500,8 +1500,9 @@ void Obj_compiler()
enum n = compilerHeader.length;
char[n + maxVersionLength] compiler = compilerHeader;

assert(config._version.length < maxVersionLength);
const newLength = n + config._version.length;
// _version is a null-terminated D string
assert(config._version.length +1 < maxVersionLength);
const newLength = n + config._version.length + 1;
compiler[n .. newLength] = config._version;
comment_data.write(compiler[0 .. newLength]);
//dbg_printf("Comment data size %d\n",comment_data.length());
Expand Down
67 changes: 37 additions & 30 deletions src/dmd/globals.d
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ extern (C++) struct Global
Array!(const(char)*)* filePath; // Array of char*'s which form the file import lookup path

string _version;
uint _versionNumber;
const(char)[] vendor; // Compiler backend name

Param params;
Expand Down Expand Up @@ -370,7 +371,10 @@ extern (C++) struct Global

extern (C++) void _init()
{
// add NULL for the backend, but retain _version as dstring for the frontend
_version = import("VERSION") ~ '\0';
_version = _version[0 .. $-1];
_versionNumber = calcVersionNumber();

version (MARS)
{
Expand Down Expand Up @@ -459,41 +463,44 @@ extern (C++) struct Global
}

/**
Returns: the version as the number that would be returned for __VERSION__
*/
extern(C++) uint versionNumber()
* Computes the version number __VERSION__ from the compiler version string.
*/
private uint calcVersionNumber()
{
import core.stdc.ctype;
__gshared uint cached = 0;
if (cached == 0)
import core.stdc.ctype : isdigit;
//
// parse _version
//
uint major = 0;
uint minor = 0;
bool point = false;
// skip initial 'v'
foreach (const c; _version[1..$])
{
//
// parse _version
//
uint major = 0;
uint minor = 0;
bool point = false;
for (const(char)* p = _version.ptr + 1;; p++)
if (isdigit(cast(char)c))
{
const c = *p;
if (isdigit(cast(char)c))
{
minor = minor * 10 + c - '0';
}
else if (c == '.')
{
if (point)
break; // ignore everything after second '.'
point = true;
major = minor;
minor = 0;
}
else
break;
minor = minor * 10 + c - '0';
}
else if (c == '.')
{
if (point)
break; // ignore everything after second '.'
point = true;
major = minor;
minor = 0;
}
cached = major * 1000 + minor;
else
break;
}
return cached;
return major * 1000 + minor;
}

/**
Returns: the version as the number that would be returned for __VERSION__
*/
extern(C++) uint versionNumber()
{
return _versionNumber;
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/dmd/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ struct Global
Array<const char *> *filePath; // Array of char*'s which form the file import lookup path

DString version; // Compiler version string
const unsigned _versionNumber; // Compiler __VERSION__ number
DString vendor; // Compiler backend name

Param params;
Expand Down
6 changes: 3 additions & 3 deletions src/dmd/mars.d
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ private void logo()
{
printf("DMD%llu D Compiler %.*s\n%.*s %.*s\n",
cast(ulong)size_t.sizeof * 8,
cast(int) global._version.length - 1, global._version.ptr,
cast(int) global._version.length, global._version.ptr,
cast(int)global.copyright.length, global.copyright.ptr,
cast(int)global.written.length, global.written.ptr
);
Expand All @@ -93,7 +93,7 @@ extern(C) void printInternalFailure(FILE* stream)
"with, preferably, a reduced, reproducible example and the information below.\n" ~
"DustMite (https://github.com/CyberShadow/DustMite/wiki) can help with the reduction.\n" ~
"---\n").ptr, stream);
stream.fprintf("DMD %.*s\n", cast(int) global._version.length - 1, global._version.ptr);
stream.fprintf("DMD %.*s\n", cast(int) global._version.length, global._version.ptr);
stream.printPredefinedVersions;
stream.printGlobalConfigs();
fputs("---\n".ptr, stream);
Expand Down Expand Up @@ -1310,7 +1310,7 @@ private void printPredefinedVersions(FILE* stream)
extern(C) void printGlobalConfigs(FILE* stream)
{
stream.fprintf("binary %.*s\n", cast(int)global.params.argv0.length, global.params.argv0.ptr);
stream.fprintf("version %.*s\n", cast(int) global._version.length - 1, global._version.ptr);
stream.fprintf("version %.*s\n", cast(int) global._version.length, global._version.ptr);
const iniOutput = global.inifilename ? global.inifilename : "(none)";
stream.fprintf("config %.*s\n", cast(int)iniOutput.length, iniOutput.ptr);
// Print DFLAGS environment variable
Expand Down

0 comments on commit e2c26e8

Please sign in to comment.