rustc: Fix passing errors from LLVM to rustc
Many of the instances of setting a global error variable ended up leaving a dangling pointer into free'd memory. This changes the method of error transmission to strdup any error and "relinquish ownership" to rustc when it gets an error. The corresponding Rust code will then free the error as necessary. Closes #12865
This commit is contained in:
parent
bb580f1a56
commit
de7845ac72
4 changed files with 27 additions and 17 deletions
|
@ -60,7 +60,7 @@ pub fn llvm_err(sess: &Session, msg: ~str) -> ! {
|
||||||
if cstr == ptr::null() {
|
if cstr == ptr::null() {
|
||||||
sess.fatal(msg);
|
sess.fatal(msg);
|
||||||
} else {
|
} else {
|
||||||
let err = CString::new(cstr, false);
|
let err = CString::new(cstr, true);
|
||||||
let err = str::from_utf8_lossy(err.as_bytes());
|
let err = str::from_utf8_lossy(err.as_bytes());
|
||||||
sess.fatal(msg + ": " + err.as_slice());
|
sess.fatal(msg + ": " + err.as_slice());
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ LLVMRustCreateTargetMachine(const char *triple,
|
||||||
const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Trip.getTriple(),
|
const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Trip.getTriple(),
|
||||||
Error);
|
Error);
|
||||||
if (TheTarget == NULL) {
|
if (TheTarget == NULL) {
|
||||||
LLVMRustError = Error.c_str();
|
LLVMRustSetLastError(Error.c_str());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target,
|
||||||
raw_fd_ostream OS(path, ErrorInfo, raw_fd_ostream::F_Binary);
|
raw_fd_ostream OS(path, ErrorInfo, raw_fd_ostream::F_Binary);
|
||||||
#endif
|
#endif
|
||||||
if (ErrorInfo != "") {
|
if (ErrorInfo != "") {
|
||||||
LLVMRustError = ErrorInfo.c_str();
|
LLVMRustSetLastError(ErrorInfo.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
formatted_raw_ostream FOS(OS);
|
formatted_raw_ostream FOS(OS);
|
||||||
|
|
|
@ -23,18 +23,28 @@ using namespace llvm;
|
||||||
using namespace llvm::sys;
|
using namespace llvm::sys;
|
||||||
using namespace llvm::object;
|
using namespace llvm::object;
|
||||||
|
|
||||||
const char *LLVMRustError;
|
static char *LastError;
|
||||||
|
|
||||||
extern "C" LLVMMemoryBufferRef
|
extern "C" LLVMMemoryBufferRef
|
||||||
LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
|
LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
|
||||||
LLVMMemoryBufferRef MemBuf = NULL;
|
LLVMMemoryBufferRef MemBuf = NULL;
|
||||||
LLVMCreateMemoryBufferWithContentsOfFile(Path, &MemBuf,
|
char *err = NULL;
|
||||||
const_cast<char **>(&LLVMRustError));
|
LLVMCreateMemoryBufferWithContentsOfFile(Path, &MemBuf, &err);
|
||||||
|
if (err != NULL) {
|
||||||
|
LLVMRustSetLastError(err);
|
||||||
|
}
|
||||||
return MemBuf;
|
return MemBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" const char *LLVMRustGetLastError(void) {
|
extern "C" char *LLVMRustGetLastError(void) {
|
||||||
return LLVMRustError;
|
char *ret = LastError;
|
||||||
|
LastError = NULL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLVMRustSetLastError(const char *err) {
|
||||||
|
free((void*) LastError);
|
||||||
|
LastError = strdup(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void
|
extern "C" void
|
||||||
|
@ -609,14 +619,14 @@ LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
|
||||||
MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
|
MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
|
||||||
ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(buf, Dst->getContext());
|
ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(buf, Dst->getContext());
|
||||||
if (!Src) {
|
if (!Src) {
|
||||||
LLVMRustError = Src.getError().message().c_str();
|
LLVMRustSetLastError(Src.getError().message().c_str());
|
||||||
delete buf;
|
delete buf;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Err;
|
std::string Err;
|
||||||
if (Linker::LinkModules(Dst, *Src, Linker::DestroySource, &Err)) {
|
if (Linker::LinkModules(Dst, *Src, Linker::DestroySource, &Err)) {
|
||||||
LLVMRustError = Err.c_str();
|
LLVMRustSetLastError(Err.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -629,13 +639,13 @@ LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
|
||||||
std::string Err;
|
std::string Err;
|
||||||
Module *Src = llvm::getLazyBitcodeModule(buf, Dst->getContext(), &Err);
|
Module *Src = llvm::getLazyBitcodeModule(buf, Dst->getContext(), &Err);
|
||||||
if (!Src) {
|
if (!Src) {
|
||||||
LLVMRustError = Err.c_str();
|
LLVMRustSetLastError(Err.c_str());
|
||||||
delete buf;
|
delete buf;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Linker::LinkModules(Dst, Src, Linker::DestroySource, &Err)) {
|
if (Linker::LinkModules(Dst, Src, Linker::DestroySource, &Err)) {
|
||||||
LLVMRustError = Err.c_str();
|
LLVMRustSetLastError(Err.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -648,12 +658,12 @@ LLVMRustOpenArchive(char *path) {
|
||||||
std::unique_ptr<MemoryBuffer> buf;
|
std::unique_ptr<MemoryBuffer> buf;
|
||||||
error_code err = MemoryBuffer::getFile(path, buf);
|
error_code err = MemoryBuffer::getFile(path, buf);
|
||||||
if (err) {
|
if (err) {
|
||||||
LLVMRustError = err.message().c_str();
|
LLVMRustSetLastError(err.message().c_str());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
Archive *ret = new Archive(buf.release(), err);
|
Archive *ret = new Archive(buf.release(), err);
|
||||||
if (err) {
|
if (err) {
|
||||||
LLVMRustError = err.message().c_str();
|
LLVMRustSetLastError(err.message().c_str());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -664,12 +674,12 @@ LLVMRustOpenArchive(char *path) {
|
||||||
OwningPtr<MemoryBuffer> buf;
|
OwningPtr<MemoryBuffer> buf;
|
||||||
error_code err = MemoryBuffer::getFile(path, buf);
|
error_code err = MemoryBuffer::getFile(path, buf);
|
||||||
if (err) {
|
if (err) {
|
||||||
LLVMRustError = err.message().c_str();
|
LLVMRustSetLastError(err.message().c_str());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
Archive *ret = new Archive(buf.take(), err);
|
Archive *ret = new Archive(buf.take(), err);
|
||||||
if (err) {
|
if (err) {
|
||||||
LLVMRustError = err.message().c_str();
|
LLVMRustSetLastError(err.message().c_str());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -68,4 +68,4 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern const char* LLVMRustError;
|
void LLVMRustSetLastError(const char*);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue