diff --git a/Dockerfile b/Dockerfile index 5028a2b..bdbb335 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,6 +13,7 @@ RUN set -x \ g++ openjdk-8-jdk-headless sbt cmake make curl git \ zlib1g-dev \ libgc-dev libunwind8-dev libre2-dev \ + valgrind \ && rm -rf /var/lib/apt/lists/* ARG LLVM_VERSION=6.0 diff --git a/bindgen/Main.cpp b/bindgen/Main.cpp index 4f877d6..cd56d46 100644 --- a/bindgen/Main.cpp +++ b/bindgen/Main.cpp @@ -61,6 +61,7 @@ int main(int argc, const char *argv[]) { char *resolved = realpath(op.getSourcePathList()[0].c_str(), nullptr); LocationManager locationManager(resolved); + delete [] resolved; IR ir(libName, linkName, objectName, Package.getValue(), locationManager); diff --git a/bindgen/valgrind-suppressions.txt b/bindgen/valgrind-suppressions.txt new file mode 100644 index 0000000..d0b93ce --- /dev/null +++ b/bindgen/valgrind-suppressions.txt @@ -0,0 +1,17 @@ +{ + syscall_param_suppression + Memcheck:Param + __pthread_sigmask(set) + fun:__pthread_sigmask + fun:pthread_sigmask + fun:_ZN4llvm3sys7Process25SafelyCloseFileDescriptorEi + fun:_ZN12_GLOBAL__N_18RealFileD1Ev + fun:_ZN12_GLOBAL__N_18RealFileD0Ev + fun:_ZN5clang3vfs10FileSystem16getBufferForFileERKN4llvm5TwineExbb + fun:_ZN5clang11FileManager16getBufferForFileEPKNS_9FileEntryEbb + fun:_ZNK5clang6SrcMgr12ContentCache9getBufferERNS_17DiagnosticsEngineERKNS_13SourceManagerENS_14SourceLocationEPb + fun:_ZNK5clang13SourceManager9getBufferENS_6FileIDENS_14SourceLocationEPb + fun:_ZN5clang12Preprocessor15EnterSourceFileENS_6FileIDEPKNS_15DirectoryLookupENS_14SourceLocationE + fun:_ZN5clang12Preprocessor19EnterMainSourceFileEv + fun:_ZN5clang8ParseASTERNS_4SemaEbb +} diff --git a/bindgen/visitor/TreeVisitor.cpp b/bindgen/visitor/TreeVisitor.cpp index 06807c6..381f131 100644 --- a/bindgen/visitor/TreeVisitor.cpp +++ b/bindgen/visitor/TreeVisitor.cpp @@ -179,7 +179,9 @@ bool TreeVisitor::VisitVarDecl(clang::VarDecl *varDecl) { std::shared_ptr TreeVisitor::getLocation(clang::Decl *decl) { clang::SourceManager &sm = astContext->getSourceManager(); std::string filename = std::string(sm.getFilename(decl->getLocation())); - std::string path = realpath(filename.c_str(), nullptr); + char *resolved = realpath(filename.c_str(), nullptr); + std::string path = resolved; + delete [] resolved; unsigned lineNumber = sm.getSpellingLineNumber(decl->getLocation()); return std::make_shared(path, lineNumber); diff --git a/build.sbt b/build.sbt index 2acde02..90284ba 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,12 @@ import scala.sys.process._ addCommandAlias("verify", "; ^test:compile ; ^test ; ^scripted ; docs/makeSite") +addCommandAlias( + "verifyWithoutMemoryChecks", + "; ^test:compile ; " + + "^testOnly -- -z \"should exist\" -z \"correct bindings\" ; " + + "^scripted ; " + + "docs/makeSite") val Versions = new { val scala210 = "2.10.6" diff --git a/scripts/test.sh b/scripts/test.sh index 8f3e3cd..98d8c6f 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -13,4 +13,8 @@ if [[ ! -e bindgen/target/.llvm-version ]] || [[ "$( ())).exitValue() + } + for (input <- inputDirectory.listFiles() if input.getName.endsWith(".h")) { - it(s"should generate bindings for ${input.getName}") { + it(s"should generate correct bindings for ${input.getName}") { val testName = input.getName.replace(".h", "") val expected = new File(inputDirectory, testName + ".scala") val output = new File(outputDir, testName + ".scala") @@ -43,6 +64,10 @@ class BindgenSpec extends FunSpec { assert(output.exists()) assert(contentOf(output) == contentOf(expected)) } + + it(s"should generate bindings for ${input.getName} without memory errors") { + assert(0 == checkMemoryErrors(input)) + } } } }