Skip to content

Commit de7845a

Browse files
committed
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
1 parent bb580f1 commit de7845a

File tree

4 files changed

+27
-17
lines changed

4 files changed

+27
-17
lines changed

src/librustc/back/link.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub fn llvm_err(sess: &Session, msg: ~str) -> ! {
6060
if cstr == ptr::null() {
6161
sess.fatal(msg);
6262
} else {
63-
let err = CString::new(cstr, false);
63+
let err = CString::new(cstr, true);
6464
let err = str::from_utf8_lossy(err.as_bytes());
6565
sess.fatal(msg + ": " + err.as_slice());
6666
}

src/rustllvm/PassWrapper.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ LLVMRustCreateTargetMachine(const char *triple,
7575
const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Trip.getTriple(),
7676
Error);
7777
if (TheTarget == NULL) {
78-
LLVMRustError = Error.c_str();
78+
LLVMRustSetLastError(Error.c_str());
7979
return NULL;
8080
}
8181

@@ -178,7 +178,7 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target,
178178
raw_fd_ostream OS(path, ErrorInfo, raw_fd_ostream::F_Binary);
179179
#endif
180180
if (ErrorInfo != "") {
181-
LLVMRustError = ErrorInfo.c_str();
181+
LLVMRustSetLastError(ErrorInfo.c_str());
182182
return false;
183183
}
184184
formatted_raw_ostream FOS(OS);

src/rustllvm/RustWrapper.cpp

+23-13
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,28 @@ using namespace llvm;
2323
using namespace llvm::sys;
2424
using namespace llvm::object;
2525

26-
const char *LLVMRustError;
26+
static char *LastError;
2727

2828
extern "C" LLVMMemoryBufferRef
2929
LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
3030
LLVMMemoryBufferRef MemBuf = NULL;
31-
LLVMCreateMemoryBufferWithContentsOfFile(Path, &MemBuf,
32-
const_cast<char **>(&LLVMRustError));
31+
char *err = NULL;
32+
LLVMCreateMemoryBufferWithContentsOfFile(Path, &MemBuf, &err);
33+
if (err != NULL) {
34+
LLVMRustSetLastError(err);
35+
}
3336
return MemBuf;
3437
}
3538

36-
extern "C" const char *LLVMRustGetLastError(void) {
37-
return LLVMRustError;
39+
extern "C" char *LLVMRustGetLastError(void) {
40+
char *ret = LastError;
41+
LastError = NULL;
42+
return ret;
43+
}
44+
45+
void LLVMRustSetLastError(const char *err) {
46+
free((void*) LastError);
47+
LastError = strdup(err);
3848
}
3949

4050
extern "C" void
@@ -609,14 +619,14 @@ LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
609619
MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
610620
ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(buf, Dst->getContext());
611621
if (!Src) {
612-
LLVMRustError = Src.getError().message().c_str();
622+
LLVMRustSetLastError(Src.getError().message().c_str());
613623
delete buf;
614624
return false;
615625
}
616626

617627
std::string Err;
618628
if (Linker::LinkModules(Dst, *Src, Linker::DestroySource, &Err)) {
619-
LLVMRustError = Err.c_str();
629+
LLVMRustSetLastError(Err.c_str());
620630
return false;
621631
}
622632
return true;
@@ -629,13 +639,13 @@ LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
629639
std::string Err;
630640
Module *Src = llvm::getLazyBitcodeModule(buf, Dst->getContext(), &Err);
631641
if (!Src) {
632-
LLVMRustError = Err.c_str();
642+
LLVMRustSetLastError(Err.c_str());
633643
delete buf;
634644
return false;
635645
}
636646

637647
if (Linker::LinkModules(Dst, Src, Linker::DestroySource, &Err)) {
638-
LLVMRustError = Err.c_str();
648+
LLVMRustSetLastError(Err.c_str());
639649
return false;
640650
}
641651
return true;
@@ -648,12 +658,12 @@ LLVMRustOpenArchive(char *path) {
648658
std::unique_ptr<MemoryBuffer> buf;
649659
error_code err = MemoryBuffer::getFile(path, buf);
650660
if (err) {
651-
LLVMRustError = err.message().c_str();
661+
LLVMRustSetLastError(err.message().c_str());
652662
return NULL;
653663
}
654664
Archive *ret = new Archive(buf.release(), err);
655665
if (err) {
656-
LLVMRustError = err.message().c_str();
666+
LLVMRustSetLastError(err.message().c_str());
657667
return NULL;
658668
}
659669
return ret;
@@ -664,12 +674,12 @@ LLVMRustOpenArchive(char *path) {
664674
OwningPtr<MemoryBuffer> buf;
665675
error_code err = MemoryBuffer::getFile(path, buf);
666676
if (err) {
667-
LLVMRustError = err.message().c_str();
677+
LLVMRustSetLastError(err.message().c_str());
668678
return NULL;
669679
}
670680
Archive *ret = new Archive(buf.take(), err);
671681
if (err) {
672-
LLVMRustError = err.message().c_str();
682+
LLVMRustSetLastError(err.message().c_str());
673683
return NULL;
674684
}
675685
return ret;

src/rustllvm/rustllvm.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,4 @@
6868
#include <unistd.h>
6969
#endif
7070

71-
extern const char* LLVMRustError;
71+
void LLVMRustSetLastError(const char*);

0 commit comments

Comments
 (0)