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:
Alex Crichton 2014-04-15 07:25:22 -07:00
parent bb580f1a56
commit de7845ac72
4 changed files with 27 additions and 17 deletions

View file

@ -60,7 +60,7 @@ pub fn llvm_err(sess: &Session, msg: ~str) -> ! {
if cstr == ptr::null() {
sess.fatal(msg);
} else {
let err = CString::new(cstr, false);
let err = CString::new(cstr, true);
let err = str::from_utf8_lossy(err.as_bytes());
sess.fatal(msg + ": " + err.as_slice());
}

View file

@ -75,7 +75,7 @@ LLVMRustCreateTargetMachine(const char *triple,
const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Trip.getTriple(),
Error);
if (TheTarget == NULL) {
LLVMRustError = Error.c_str();
LLVMRustSetLastError(Error.c_str());
return NULL;
}
@ -178,7 +178,7 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target,
raw_fd_ostream OS(path, ErrorInfo, raw_fd_ostream::F_Binary);
#endif
if (ErrorInfo != "") {
LLVMRustError = ErrorInfo.c_str();
LLVMRustSetLastError(ErrorInfo.c_str());
return false;
}
formatted_raw_ostream FOS(OS);

View file

@ -23,18 +23,28 @@ using namespace llvm;
using namespace llvm::sys;
using namespace llvm::object;
const char *LLVMRustError;
static char *LastError;
extern "C" LLVMMemoryBufferRef
LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
LLVMMemoryBufferRef MemBuf = NULL;
LLVMCreateMemoryBufferWithContentsOfFile(Path, &MemBuf,
const_cast<char **>(&LLVMRustError));
char *err = NULL;
LLVMCreateMemoryBufferWithContentsOfFile(Path, &MemBuf, &err);
if (err != NULL) {
LLVMRustSetLastError(err);
}
return MemBuf;
}
extern "C" const char *LLVMRustGetLastError(void) {
return LLVMRustError;
extern "C" char *LLVMRustGetLastError(void) {
char *ret = LastError;
LastError = NULL;
return ret;
}
void LLVMRustSetLastError(const char *err) {
free((void*) LastError);
LastError = strdup(err);
}
extern "C" void
@ -609,14 +619,14 @@ LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(buf, Dst->getContext());
if (!Src) {
LLVMRustError = Src.getError().message().c_str();
LLVMRustSetLastError(Src.getError().message().c_str());
delete buf;
return false;
}
std::string Err;
if (Linker::LinkModules(Dst, *Src, Linker::DestroySource, &Err)) {
LLVMRustError = Err.c_str();
LLVMRustSetLastError(Err.c_str());
return false;
}
return true;
@ -629,13 +639,13 @@ LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
std::string Err;
Module *Src = llvm::getLazyBitcodeModule(buf, Dst->getContext(), &Err);
if (!Src) {
LLVMRustError = Err.c_str();
LLVMRustSetLastError(Err.c_str());
delete buf;
return false;
}
if (Linker::LinkModules(Dst, Src, Linker::DestroySource, &Err)) {
LLVMRustError = Err.c_str();
LLVMRustSetLastError(Err.c_str());
return false;
}
return true;
@ -648,12 +658,12 @@ LLVMRustOpenArchive(char *path) {
std::unique_ptr<MemoryBuffer> buf;
error_code err = MemoryBuffer::getFile(path, buf);
if (err) {
LLVMRustError = err.message().c_str();
LLVMRustSetLastError(err.message().c_str());
return NULL;
}
Archive *ret = new Archive(buf.release(), err);
if (err) {
LLVMRustError = err.message().c_str();
LLVMRustSetLastError(err.message().c_str());
return NULL;
}
return ret;
@ -664,12 +674,12 @@ LLVMRustOpenArchive(char *path) {
OwningPtr<MemoryBuffer> buf;
error_code err = MemoryBuffer::getFile(path, buf);
if (err) {
LLVMRustError = err.message().c_str();
LLVMRustSetLastError(err.message().c_str());
return NULL;
}
Archive *ret = new Archive(buf.take(), err);
if (err) {
LLVMRustError = err.message().c_str();
LLVMRustSetLastError(err.message().c_str());
return NULL;
}
return ret;

View file

@ -68,4 +68,4 @@
#include <unistd.h>
#endif
extern const char* LLVMRustError;
void LLVMRustSetLastError(const char*);