diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -31,6 +31,8 @@ #include "tsan_mman.h" #include "tsan_fd.h" +#include + using namespace __tsan; #if SANITIZER_FREEBSD || SANITIZER_MAC @@ -135,6 +137,7 @@ #endif const int MAP_FIXED = 0x10; typedef long long_t; +typedef __sanitizer::u16 mode_t; // From /usr/include/unistd.h # define F_ULOCK 0 /* Unlock a previously locked region. */ @@ -1508,20 +1511,28 @@ #define TSAN_MAYBE_INTERCEPT_FSTAT64 #endif -TSAN_INTERCEPTOR(int, open, const char *name, int flags, int mode) { - SCOPED_TSAN_INTERCEPTOR(open, name, flags, mode); +TSAN_INTERCEPTOR(int, open, const char *name, int oflag, ...) { + va_list ap; + va_start(ap, oflag); + mode_t mode = va_arg(ap, int); + va_end(ap); + SCOPED_TSAN_INTERCEPTOR(open, name, oflag, mode); READ_STRING(thr, pc, name, 0); - int fd = REAL(open)(name, flags, mode); + int fd = REAL(open)(name, oflag, mode); if (fd >= 0) FdFileCreate(thr, pc, fd); return fd; } #if SANITIZER_LINUX -TSAN_INTERCEPTOR(int, open64, const char *name, int flags, int mode) { - SCOPED_TSAN_INTERCEPTOR(open64, name, flags, mode); +TSAN_INTERCEPTOR(int, open64, const char *name, int oflag, ...) { + va_list ap; + va_start(ap, oflag); + mode_t mode = va_arg(ap, int); + va_end(ap); + SCOPED_TSAN_INTERCEPTOR(open64, name, oflag, mode); READ_STRING(thr, pc, name, 0); - int fd = REAL(open64)(name, flags, mode); + int fd = REAL(open64)(name, oflag, mode); if (fd >= 0) FdFileCreate(thr, pc, fd); return fd; diff --git a/compiler-rt/test/tsan/variadic-open.cpp b/compiler-rt/test/tsan/variadic-open.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/tsan/variadic-open.cpp @@ -0,0 +1,24 @@ +// RUN: %clangxx_tsan -O1 %s -o %t && %run %t %t.tmp 2>&1 | FileCheck %s +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + fprintf(stderr, "Hello world.\n"); + assert(argv[1]); + unlink(argv[1]); + int fd = open(argv[1], O_RDWR | O_CREAT, 0600); + assert(fd != -1); + struct stat info; + int result = fstat(fd, &info); + fprintf(stderr, "permissions = 0%o\n", info.st_mode & ~S_IFMT); + assert(result == 0); + close(fd); + fprintf(stderr, "Done.\n"); +} + +// CHECK: Hello world. +// CHECK: permissions = 0600 +// CHECK: Done.