Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix version with NULLPTR in JSON output #11640

Merged
merged 1 commit into from
Sep 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/dmd/backend/dwarfdbginf.d
Original file line number Diff line number Diff line change
Expand Up @@ -1126,7 +1126,7 @@ static if (ELFOBJ || MACHOBJ)
version (MARS)
{
debug_info.buf.write("Digital Mars D ");
debug_info.buf.write(config._version); // DW_AT_producer
debug_info.buf.writeString(config._version); // DW_AT_producer
// DW_AT_language
debug_info.buf.writeByte((config.fulltypes == CVDWARF_D) ? DW_LANG_D : DW_LANG_C89);
}
Expand Down
5 changes: 3 additions & 2 deletions src/dmd/backend/elfobj.d
Original file line number Diff line number Diff line change
Expand Up @@ -1500,10 +1500,11 @@ void Obj_compiler()
enum n = compilerHeader.length;
char[n + maxVersionLength] compiler = compilerHeader;

assert(config._version.length < maxVersionLength);
assert(config._version.length + 1 < maxVersionLength);
const newLength = n + config._version.length;
compiler[n .. newLength] = config._version;
comment_data.write(compiler[0 .. newLength]);
compiler[newLength] = 0;
comment_data.write(compiler[0 .. newLength + 1]);
//dbg_printf("Comment data size %d\n",comment_data.length());
}

Expand Down
2 changes: 1 addition & 1 deletion src/dmd/dmsc.d
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ void backend_init()
params.useModuleInfo && Module.moduleinfo,
params.useTypeInfo && Type.dtypeinfo,
params.useExceptions && ClassDeclaration.throwable,
global._version
global.versionString()
);

debug
Expand Down
4 changes: 2 additions & 2 deletions src/dmd/frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -12497,7 +12497,6 @@ struct Global
DArray< char > written;
Array<const char*>* path;
Array<const char*>* filePath;
DArray< char > _version;
DArray< const char > vendor;
Param params;
uint32_t errors;
Expand All @@ -12515,8 +12514,9 @@ struct Global
void increaseErrorCount();
void _init();
uint32_t versionNumber();
const char* const versionChars();
~Global();
Global() : inifilename(), mars_ext("d"), obj_ext(), lib_ext(), dll_ext(), doc_ext("html"), ddoc_ext("ddoc"), hdr_ext("di"), cxxhdr_ext("h"), json_ext("json"), map_ext("map"), run_noext(), copyright("Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved"), written("written by Walter Bright"), path(), filePath(), _version(), vendor(), params(), errors(), warnings(), gag(), gaggedErrors(), gaggedWarnings(), console(), versionids(), debugids() {}
Global() : inifilename(), mars_ext("d"), obj_ext(), lib_ext(), dll_ext(), doc_ext("html"), ddoc_ext("ddoc"), hdr_ext("di"), cxxhdr_ext("h"), json_ext("json"), map_ext("map"), run_noext(), copyright("Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved"), written("written by Walter Bright"), path(), filePath(), vendor(), params(), errors(), warnings(), gag(), gaggedErrors(), gaggedWarnings(), console(), versionids(), debugids() {}
};

typedef uint64_t dinteger_t;
Expand Down
84 changes: 51 additions & 33 deletions src/dmd/globals.d
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,9 @@ extern (C++) struct Global
Array!(const(char)*)* path; // Array of char*'s which form the import lookup path
Array!(const(char)*)* filePath; // Array of char*'s which form the file import lookup path

string _version;
private enum string _version = import("VERSION");
private enum uint _versionNumber = parseVersionNumber(_version);

const(char)[] vendor; // Compiler backend name

Param params;
Expand Down Expand Up @@ -380,8 +382,6 @@ extern (C++) struct Global

extern (C++) void _init()
{
_version = import("VERSION") ~ '\0';

version (MARS)
{
vendor = "Digital Mars D";
Expand Down Expand Up @@ -469,41 +469,59 @@ 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.
*/
extern (D) private static uint parseVersionNumber(string version_)
{
import core.stdc.ctype;
__gshared uint cached = 0;
if (cached == 0)
//
// 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 ('0' <= c && c <= '9') // isdigit
{
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';
}
cached = major * 1000 + minor;
else if (c == '.')
{
if (point)
break; // ignore everything after second '.'
point = true;
major = minor;
minor = 0;
}
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;
}

/**
Returns: compiler version string.
*/
extern(D) string versionString()
{
return _version;
}

/**
Returns: compiler version as char string.
*/
extern(C++) const(char*) versionChars()
{
return _version.ptr;
}

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

DString version; // Compiler version string
DString vendor; // Compiler backend name

Param params;
Expand Down Expand Up @@ -326,6 +325,11 @@ struct Global
Returns: the version as the number that would be returned for __VERSION__
*/
unsigned versionNumber();

/**
Returns: the compiler version string.
*/
const char * versionChars();
};

extern Global global;
Expand Down
2 changes: 1 addition & 1 deletion src/dmd/json.d
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,7 @@ public:
{
objectStart();
requiredProperty("vendor", global.vendor);
requiredProperty("version", global._version);
requiredProperty("version", global.versionString());
property("__VERSION__", global.versionNumber());
requiredProperty("interface", determineCompilerInterface());
property("size_t", size_t.sizeof);
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.versionString().length, global.versionString().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.versionString().length, global.versionString().ptr);
stream.printPredefinedVersions;
stream.printGlobalConfigs();
fputs("---\n".ptr, stream);
Expand Down Expand Up @@ -1347,7 +1347,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.versionString().length, global.versionString().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
9 changes: 9 additions & 0 deletions src/tests/cxxfrontend.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@ void test_tokens()
assert(strcmp(Token::toChars(TOKvectorarray), "vectorarray") == 0);
}

void test_compiler_globals()
{
// only check constant prefix of version
assert(strncmp(global.versionChars(), "v2.", 3) == 0);
unsigned versionNumber = global.versionNumber();
assert(versionNumber >= 2060 && versionNumber <= 3000);
}

/**********************************/

class TestVisitor : public Visitor
Expand Down Expand Up @@ -457,6 +465,7 @@ int main(int argc, char **argv)
frontend_init();

test_tokens();
test_compiler_globals();
test_visitors();
test_semantic();
test_expression();
Expand Down