Refactor the call to llvm::sys::fs::getMainExecutable.

Taking the address of `main` is UB in C++. Reading LLVM's source, any function address can be used (that's what clang does too).
This commit is contained in:
Johan Engelen 2016-07-27 20:26:54 +02:00
parent 246c0c359c
commit c3fe8f3fdd
4 changed files with 12 additions and 5 deletions

View file

@ -19,9 +19,15 @@ namespace {
string exePath;
}
void exe_path::initialize(const char *arg0, void *mainAddress) {
void exe_path::initialize(const char *arg0) {
assert(exePath.empty());
exePath = llvm::sys::fs::getMainExecutable(arg0, mainAddress);
// Some platforms can't implement LLVM's getMainExecutable
// without being given the address of a function in the main executable.
// Thus getMainExecutable needs the address of a function;
// any function address in the main executable will do.
exePath = llvm::sys::fs::getMainExecutable(
arg0, reinterpret_cast<void *>(&exe_path::initialize));
}
const string &exe_path::getExePath() {

View file

@ -18,7 +18,8 @@
#include <string>
namespace exe_path {
void initialize(const char *arg0, void *mainAddress);
void initialize(const char *arg0);
const std::string &getExePath(); // <baseDir>/bin/ldc2
std::string getBinDir(); // <baseDir>/bin

View file

@ -1046,7 +1046,7 @@ static size_t addStrlen(size_t acc, const char *str) {
int main(int argc, char **argv);
int cppmain(int argc, char **argv) {
exe_path::initialize(argv[0], reinterpret_cast<void *>(main));
exe_path::initialize(argv[0]);
std::string ldcExeName = LDC_EXE_NAME;
#ifdef _WIN32

View file

@ -1052,7 +1052,7 @@ int cppmain(int argc, char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal();
#endif
exe_path::initialize(argv[0], reinterpret_cast<void *>(main));
exe_path::initialize(argv[0]);
global._init();
global.version = ldc::dmd_version;