[PATCH] D33304: [WIP][clang-tidy] Add a new module Android and a new check for file descriptors.

2017-05-30 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 100777.
yawanng added a comment.

Modify the detection algorithm. Add another two checks and corresponding tests 
as well as the docs.


https://reviews.llvm.org/D33304

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CreatUsageCheck.cpp
  clang-tidy/android/CreatUsageCheck.h
  clang-tidy/android/FileOpenFlagCheck.cpp
  clang-tidy/android/FileOpenFlagCheck.h
  clang-tidy/android/FopenModeCheck.cpp
  clang-tidy/android/FopenModeCheck.h
  clang-tidy/plugin/CMakeLists.txt
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  clang-tidy/utils/CMakeLists.txt
  clang-tidy/utils/ExprToStr.cpp
  clang-tidy/utils/ExprToStr.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-creat-usage.rst
  docs/clang-tidy/checks/android-file-open-flag.rst
  docs/clang-tidy/checks/android-fopen-mode.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/index.rst
  test/clang-tidy/android-creat-usage.cpp
  test/clang-tidy/android-file-open-flag.cpp
  test/clang-tidy/android-fopen-mode.cpp
  unittests/clang-tidy/CMakeLists.txt

Index: unittests/clang-tidy/CMakeLists.txt
===
--- unittests/clang-tidy/CMakeLists.txt
+++ unittests/clang-tidy/CMakeLists.txt
@@ -25,6 +25,7 @@
   clangFrontend
   clangLex
   clangTidy
+  clangTidyAndroidModule
   clangTidyGoogleModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: test/clang-tidy/android-fopen-mode.cpp
===
--- test/clang-tidy/android-fopen-mode.cpp
+++ test/clang-tidy/android-fopen-mode.cpp
@@ -0,0 +1,51 @@
+// RUN: %check_clang_tidy %s android-fopen-mode %t
+
+#define FILE_OPEN_RO "r"
+
+typedef int FILE;
+
+extern "C" FILE *fopen(const char *filename, const char *mode, ...);
+extern "C" FILE *open(const char *filename, const char *mode, ...);
+
+void f() {
+  fopen("filename", "r");
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use fopen() mode 'e' to set O_CLOEXEC. [android-fopen-mode]
+  // CHECK-FIXES: "re"
+
+  fopen("filename", FILE_OPEN_RO);
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use fopen() mode 'e' to set O_CLOEXEC. [android-fopen-mode]
+  // CHECK-FIXES: FILE_OPEN_RO "e"
+
+  fopen("filename", "er");
+  // CHECK-MESSAGES-NOT: warning:
+  fopen("filename", "re");
+  // CHECK-MESSAGES-NOT: warning:
+  fopen("filename", "e");
+  // CHECK-MESSAGES-NOT: warning:
+  open("filename", "e");
+  // CHECK-MESSAGES-NOT: warning:
+
+  char *str = "r";
+  fopen("filename", str);
+  // CHECK-MESSAGES-NOT: warning:
+  char arr[2] = "r";
+  fopen("filename", arr);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+namespace i {
+int *fopen(const char *filename, const char *mode, ...);
+void g() {
+  fopen("filename", "e");
+  // CHECK-MESSAGES-NOT: warning:
+}
+} // namespace i
+
+class C {
+public:
+  int *fopen(const char *filename, const char *mode, ...);
+  void h() {
+fopen("filename", "e");
+// CHECK-MESSAGES-NOT: warning:
+  }
+};
Index: test/clang-tidy/android-file-open-flag.cpp
===
--- test/clang-tidy/android-file-open-flag.cpp
+++ test/clang-tidy/android-file-open-flag.cpp
@@ -0,0 +1,104 @@
+// RUN: %check_clang_tidy %s android-file-open-flag %t
+
+#define O_RDWR 1
+#define O_EXCL 2
+#define __O_CLOEXEC 3
+#define O_CLOEXEC __O_CLOEXEC
+
+extern "C" int open(const char *fn, int flags, ...);
+extern "C" int open64(const char *fn, int flags, ...);
+extern "C" int openat(int dirfd, const char *pathname, int flags, ...);
+
+void a() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void b() {
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open64("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void c() {
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  openat(0, "filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void f() {
+  open("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possib

[PATCH] D33304: [clang-tidy] Add a new module Android and a new check for file descriptors.

2017-05-30 Thread Yan Wang via Phabricator via cfe-commits
yawanng added a comment.

Hi,  I have updated this CL for review. Thank you very much :)


https://reviews.llvm.org/D33304



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33304: [clang-tidy] Add a new module Android and a new check for file descriptors.

2017-05-30 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 100782.

https://reviews.llvm.org/D33304

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CreatUsageCheck.cpp
  clang-tidy/android/CreatUsageCheck.h
  clang-tidy/android/FileOpenFlagCheck.cpp
  clang-tidy/android/FileOpenFlagCheck.h
  clang-tidy/android/FopenModeCheck.cpp
  clang-tidy/android/FopenModeCheck.h
  clang-tidy/plugin/CMakeLists.txt
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  clang-tidy/utils/CMakeLists.txt
  clang-tidy/utils/ExprToStr.cpp
  clang-tidy/utils/ExprToStr.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-creat-usage.rst
  docs/clang-tidy/checks/android-file-open-flag.rst
  docs/clang-tidy/checks/android-fopen-mode.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/index.rst
  test/clang-tidy/android-creat-usage.cpp
  test/clang-tidy/android-file-open-flag.cpp
  test/clang-tidy/android-fopen-mode.cpp
  unittests/clang-tidy/CMakeLists.txt

Index: unittests/clang-tidy/CMakeLists.txt
===
--- unittests/clang-tidy/CMakeLists.txt
+++ unittests/clang-tidy/CMakeLists.txt
@@ -25,6 +25,7 @@
   clangFrontend
   clangLex
   clangTidy
+  clangTidyAndroidModule
   clangTidyGoogleModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: test/clang-tidy/android-fopen-mode.cpp
===
--- test/clang-tidy/android-fopen-mode.cpp
+++ test/clang-tidy/android-fopen-mode.cpp
@@ -0,0 +1,51 @@
+// RUN: %check_clang_tidy %s android-fopen-mode %t
+
+#define FILE_OPEN_RO "r"
+
+typedef int FILE;
+
+extern "C" FILE *fopen(const char *filename, const char *mode, ...);
+extern "C" FILE *open(const char *filename, const char *mode, ...);
+
+void f() {
+  fopen("filename", "r");
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use fopen() mode 'e' to set O_CLOEXEC. [android-fopen-mode]
+  // CHECK-FIXES: "re"
+
+  fopen("filename", FILE_OPEN_RO);
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use fopen() mode 'e' to set O_CLOEXEC. [android-fopen-mode]
+  // CHECK-FIXES: FILE_OPEN_RO "e"
+
+  fopen("filename", "er");
+  // CHECK-MESSAGES-NOT: warning:
+  fopen("filename", "re");
+  // CHECK-MESSAGES-NOT: warning:
+  fopen("filename", "e");
+  // CHECK-MESSAGES-NOT: warning:
+  open("filename", "e");
+  // CHECK-MESSAGES-NOT: warning:
+
+  char *str = "r";
+  fopen("filename", str);
+  // CHECK-MESSAGES-NOT: warning:
+  char arr[2] = "r";
+  fopen("filename", arr);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+namespace i {
+int *fopen(const char *filename, const char *mode, ...);
+void g() {
+  fopen("filename", "e");
+  // CHECK-MESSAGES-NOT: warning:
+}
+} // namespace i
+
+class C {
+public:
+  int *fopen(const char *filename, const char *mode, ...);
+  void h() {
+fopen("filename", "e");
+// CHECK-MESSAGES-NOT: warning:
+  }
+};
Index: test/clang-tidy/android-file-open-flag.cpp
===
--- test/clang-tidy/android-file-open-flag.cpp
+++ test/clang-tidy/android-file-open-flag.cpp
@@ -0,0 +1,104 @@
+// RUN: %check_clang_tidy %s android-file-open-flag %t
+
+#define O_RDWR 1
+#define O_EXCL 2
+#define __O_CLOEXEC 3
+#define O_CLOEXEC __O_CLOEXEC
+
+extern "C" int open(const char *fn, int flags, ...);
+extern "C" int open64(const char *fn, int flags, ...);
+extern "C" int openat(int dirfd, const char *pathname, int flags, ...);
+
+void a() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void b() {
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open64("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void c() {
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  openat(0, "filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void f() {
+  open("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+  open64("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: w

[PATCH] D33304: [clang-tidy] Add a new module Android and a new check for file descriptors.

2017-05-30 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 100786.
yawanng marked 8 inline comments as done.

https://reviews.llvm.org/D33304

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CreatUsageCheck.cpp
  clang-tidy/android/CreatUsageCheck.h
  clang-tidy/android/FileOpenFlagCheck.cpp
  clang-tidy/android/FileOpenFlagCheck.h
  clang-tidy/android/FopenModeCheck.cpp
  clang-tidy/android/FopenModeCheck.h
  clang-tidy/plugin/CMakeLists.txt
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  clang-tidy/utils/CMakeLists.txt
  clang-tidy/utils/ExprToStr.cpp
  clang-tidy/utils/ExprToStr.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-creat-usage.rst
  docs/clang-tidy/checks/android-file-open-flag.rst
  docs/clang-tidy/checks/android-fopen-mode.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/index.rst
  test/clang-tidy/android-creat-usage.cpp
  test/clang-tidy/android-file-open-flag.cpp
  test/clang-tidy/android-fopen-mode.cpp
  unittests/clang-tidy/CMakeLists.txt

Index: unittests/clang-tidy/CMakeLists.txt
===
--- unittests/clang-tidy/CMakeLists.txt
+++ unittests/clang-tidy/CMakeLists.txt
@@ -25,6 +25,7 @@
   clangFrontend
   clangLex
   clangTidy
+  clangTidyAndroidModule
   clangTidyGoogleModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: test/clang-tidy/android-fopen-mode.cpp
===
--- test/clang-tidy/android-fopen-mode.cpp
+++ test/clang-tidy/android-fopen-mode.cpp
@@ -0,0 +1,51 @@
+// RUN: %check_clang_tidy %s android-fopen-mode %t
+
+#define FILE_OPEN_RO "r"
+
+typedef int FILE;
+
+extern "C" FILE *fopen(const char *filename, const char *mode, ...);
+extern "C" FILE *open(const char *filename, const char *mode, ...);
+
+void f() {
+  fopen("filename", "r");
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use fopen() mode 'e' to set O_CLOEXEC. [android-fopen-mode]
+  // CHECK-FIXES: "re"
+
+  fopen("filename", FILE_OPEN_RO);
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use fopen() mode 'e' to set O_CLOEXEC. [android-fopen-mode]
+  // CHECK-FIXES: FILE_OPEN_RO "e"
+
+  fopen("filename", "er");
+  // CHECK-MESSAGES-NOT: warning:
+  fopen("filename", "re");
+  // CHECK-MESSAGES-NOT: warning:
+  fopen("filename", "e");
+  // CHECK-MESSAGES-NOT: warning:
+  open("filename", "e");
+  // CHECK-MESSAGES-NOT: warning:
+
+  char *str = "r";
+  fopen("filename", str);
+  // CHECK-MESSAGES-NOT: warning:
+  char arr[2] = "r";
+  fopen("filename", arr);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+namespace i {
+int *fopen(const char *filename, const char *mode, ...);
+void g() {
+  fopen("filename", "e");
+  // CHECK-MESSAGES-NOT: warning:
+}
+} // namespace i
+
+class C {
+public:
+  int *fopen(const char *filename, const char *mode, ...);
+  void h() {
+fopen("filename", "e");
+// CHECK-MESSAGES-NOT: warning:
+  }
+};
Index: test/clang-tidy/android-file-open-flag.cpp
===
--- test/clang-tidy/android-file-open-flag.cpp
+++ test/clang-tidy/android-file-open-flag.cpp
@@ -0,0 +1,104 @@
+// RUN: %check_clang_tidy %s android-file-open-flag %t
+
+#define O_RDWR 1
+#define O_EXCL 2
+#define __O_CLOEXEC 3
+#define O_CLOEXEC __O_CLOEXEC
+
+extern "C" int open(const char *fn, int flags, ...);
+extern "C" int open64(const char *fn, int flags, ...);
+extern "C" int openat(int dirfd, const char *pathname, int flags, ...);
+
+void a() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void b() {
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open64("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void c() {
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  openat(0, "filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void f() {
+  open("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+  open64("filename", 3)

[PATCH] D33304: [clang-tidy] Add a new module Android and three new checks.

2017-05-31 Thread Yan Wang via Phabricator via cfe-commits
yawanng added a comment.

In https://reviews.llvm.org/D33304#768731, @alexfh wrote:

> It's awesome to see another two checks, and it seems to justify adding a 
> separate module, but I'd prefer the other two checks to be sent for review as 
> separate patches to make the review easier and faster.


The other two checks are relatively small and simple. I understand this may 
make the review process longer and we could wait for that. Please take your 
time :-) Thank you!


https://reviews.llvm.org/D33304



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33304: [clang-tidy] Add a new module Android and three new checks.

2017-05-31 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 100928.
yawanng added a comment.

Split the commit to three ones that each of them contains one. This is the 
first part.


https://reviews.llvm.org/D33304

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/FileOpenFlagCheck.cpp
  clang-tidy/android/FileOpenFlagCheck.h
  clang-tidy/plugin/CMakeLists.txt
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  clang-tidy/utils/CMakeLists.txt
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-file-open-flag.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/index.rst
  test/clang-tidy/android-file-open-flag.cpp
  unittests/clang-tidy/CMakeLists.txt

Index: unittests/clang-tidy/CMakeLists.txt
===
--- unittests/clang-tidy/CMakeLists.txt
+++ unittests/clang-tidy/CMakeLists.txt
@@ -25,6 +25,7 @@
   clangFrontend
   clangLex
   clangTidy
+  clangTidyAndroidModule
   clangTidyGoogleModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: test/clang-tidy/android-file-open-flag.cpp
===
--- /dev/null
+++ test/clang-tidy/android-file-open-flag.cpp
@@ -0,0 +1,104 @@
+// RUN: %check_clang_tidy %s android-file-open-flag %t
+
+#define O_RDWR 1
+#define O_EXCL 2
+#define __O_CLOEXEC 3
+#define O_CLOEXEC __O_CLOEXEC
+
+extern "C" int open(const char *fn, int flags, ...);
+extern "C" int open64(const char *fn, int flags, ...);
+extern "C" int openat(int dirfd, const char *pathname, int flags, ...);
+
+void a() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void b() {
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open64("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void c() {
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  openat(0, "filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void f() {
+  open("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+  open64("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+  openat(0, "filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+
+  int flag = 3;
+  open("filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+namespace i {
+int open(const char *pathname, int flags, ...);
+int open64(const char *pathname, int flags, ...);
+int openat(int dirfd, const char *pathname, int flags, ...);
+
+void d() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+} // namespace i
+
+void e() {
+  open("filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open("filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+class G {
+public:
+  int open(const char *pathname, int flags, ...);
+  int open64(const char *pathname, int flags, ...);
+  int openat(int dirfd, const char *pathname, int flags, ...);
+
+  void h() {
+open("filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+open64("filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+openat(0, "filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+  }
+};
Index: docs/clang-tidy/index.rst
===

[PATCH] D33304: [clang-tidy][Part1] Add a new module Android and three new checks.

2017-05-31 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 100934.
yawanng edited the summary of this revision.

https://reviews.llvm.org/D33304

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/FileOpenFlagCheck.cpp
  clang-tidy/android/FileOpenFlagCheck.h
  clang-tidy/plugin/CMakeLists.txt
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-file-open-flag.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/index.rst
  test/clang-tidy/android-file-open-flag.cpp
  unittests/clang-tidy/CMakeLists.txt

Index: unittests/clang-tidy/CMakeLists.txt
===
--- unittests/clang-tidy/CMakeLists.txt
+++ unittests/clang-tidy/CMakeLists.txt
@@ -25,6 +25,7 @@
   clangFrontend
   clangLex
   clangTidy
+  clangTidyAndroidModule
   clangTidyGoogleModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: test/clang-tidy/android-file-open-flag.cpp
===
--- /dev/null
+++ test/clang-tidy/android-file-open-flag.cpp
@@ -0,0 +1,104 @@
+// RUN: %check_clang_tidy %s android-file-open-flag %t
+
+#define O_RDWR 1
+#define O_EXCL 2
+#define __O_CLOEXEC 3
+#define O_CLOEXEC __O_CLOEXEC
+
+extern "C" int open(const char *fn, int flags, ...);
+extern "C" int open64(const char *fn, int flags, ...);
+extern "C" int openat(int dirfd, const char *pathname, int flags, ...);
+
+void a() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void b() {
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open64("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void c() {
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  openat(0, "filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void f() {
+  open("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+  open64("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+  openat(0, "filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+
+  int flag = 3;
+  open("filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+namespace i {
+int open(const char *pathname, int flags, ...);
+int open64(const char *pathname, int flags, ...);
+int openat(int dirfd, const char *pathname, int flags, ...);
+
+void d() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+} // namespace i
+
+void e() {
+  open("filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open("filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+class G {
+public:
+  int open(const char *pathname, int flags, ...);
+  int open64(const char *pathname, int flags, ...);
+  int openat(int dirfd, const char *pathname, int flags, ...);
+
+  void h() {
+open("filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+open64("filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+openat(0, "filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+  }
+};
Index: docs/clang-tidy/index.rst
===
--- docs/clang-tidy/index.rst
+++ docs/clang-tidy/index.rst
@@ -55,6 +55,7 @@
 

[PATCH] D33304: [clang-tidy][Part1] Add a new module Android and three new checks.

2017-06-02 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 101267.

https://reviews.llvm.org/D33304

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/FileOpenFlagCheck.cpp
  clang-tidy/android/FileOpenFlagCheck.h
  clang-tidy/plugin/CMakeLists.txt
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-file-open-flag.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/index.rst
  test/clang-tidy/android-file-open-flag.cpp
  unittests/clang-tidy/CMakeLists.txt

Index: unittests/clang-tidy/CMakeLists.txt
===
--- unittests/clang-tidy/CMakeLists.txt
+++ unittests/clang-tidy/CMakeLists.txt
@@ -25,6 +25,7 @@
   clangFrontend
   clangLex
   clangTidy
+  clangTidyAndroidModule
   clangTidyGoogleModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: test/clang-tidy/android-file-open-flag.cpp
===
--- /dev/null
+++ test/clang-tidy/android-file-open-flag.cpp
@@ -0,0 +1,104 @@
+// RUN: %check_clang_tidy %s android-file-open-flag %t
+
+#define O_RDWR 1
+#define O_EXCL 2
+#define __O_CLOEXEC 3
+#define O_CLOEXEC __O_CLOEXEC
+
+extern "C" int open(const char *fn, int flags, ...);
+extern "C" int open64(const char *fn, int flags, ...);
+extern "C" int openat(int dirfd, const char *pathname, int flags, ...);
+
+void a() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void b() {
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open64("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void c() {
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  openat(0, "filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void f() {
+  open("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+  open64("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+  openat(0, "filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+
+  int flag = 3;
+  open("filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+namespace i {
+int open(const char *pathname, int flags, ...);
+int open64(const char *pathname, int flags, ...);
+int openat(int dirfd, const char *pathname, int flags, ...);
+
+void d() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+} // namespace i
+
+void e() {
+  open("filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open("filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+class G {
+public:
+  int open(const char *pathname, int flags, ...);
+  int open64(const char *pathname, int flags, ...);
+  int openat(int dirfd, const char *pathname, int flags, ...);
+
+  void h() {
+open("filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+open64("filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+openat(0, "filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+  }
+};
Index: docs/clang-tidy/index.rst
===
--- docs/clang-tidy/index.rst
+++ docs/clang-tidy/index.rst
@@ -55,6 +55,7 @@
 == =
 Name prefixDescription
 == =

[PATCH] D33304: [clang-tidy][Part1] Add a new module Android and three new checks.

2017-06-02 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 101279.
yawanng added a comment.

Format changes.


https://reviews.llvm.org/D33304

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/FileOpenFlagCheck.cpp
  clang-tidy/android/FileOpenFlagCheck.h
  clang-tidy/plugin/CMakeLists.txt
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-file-open-flag.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/index.rst
  test/clang-tidy/android-file-open-flag.cpp
  unittests/clang-tidy/CMakeLists.txt

Index: unittests/clang-tidy/CMakeLists.txt
===
--- unittests/clang-tidy/CMakeLists.txt
+++ unittests/clang-tidy/CMakeLists.txt
@@ -25,6 +25,7 @@
   clangFrontend
   clangLex
   clangTidy
+  clangTidyAndroidModule
   clangTidyGoogleModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: test/clang-tidy/android-file-open-flag.cpp
===
--- /dev/null
+++ test/clang-tidy/android-file-open-flag.cpp
@@ -0,0 +1,104 @@
+// RUN: %check_clang_tidy %s android-file-open-flag %t
+
+#define O_RDWR 1
+#define O_EXCL 2
+#define __O_CLOEXEC 3
+#define O_CLOEXEC __O_CLOEXEC
+
+extern "C" int open(const char *fn, int flags, ...);
+extern "C" int open64(const char *fn, int flags, ...);
+extern "C" int openat(int dirfd, const char *pathname, int flags, ...);
+
+void a() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void b() {
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open64("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void c() {
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  openat(0, "filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void f() {
+  open("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+  open64("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+  openat(0, "filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where possible. [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+
+  int flag = 3;
+  open("filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+namespace i {
+int open(const char *pathname, int flags, ...);
+int open64(const char *pathname, int flags, ...);
+int openat(int dirfd, const char *pathname, int flags, ...);
+
+void d() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+} // namespace i
+
+void e() {
+  open("filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open("filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+class G {
+public:
+  int open(const char *pathname, int flags, ...);
+  int open64(const char *pathname, int flags, ...);
+  int openat(int dirfd, const char *pathname, int flags, ...);
+
+  void h() {
+open("filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+open64("filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+openat(0, "filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+  }
+};
Index: docs/clang-tidy/index.rst
===
--- docs/clang-tidy/index.rst
+++ docs/clang-tidy/index.rst
@@ -55,6 +55,7 @@
 == =
 Name prefixDescription
 =

[PATCH] D33304: [clang-tidy][Part1] Add a new module Android and three new checks.

2017-06-07 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 101831.
yawanng marked an inline comment as done.

https://reviews.llvm.org/D33304

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/FileOpenFlagCheck.cpp
  clang-tidy/android/FileOpenFlagCheck.h
  clang-tidy/plugin/CMakeLists.txt
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-file-open-flag.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/index.rst
  test/clang-tidy/android-file-open-flag.cpp
  unittests/clang-tidy/CMakeLists.txt

Index: unittests/clang-tidy/CMakeLists.txt
===
--- unittests/clang-tidy/CMakeLists.txt
+++ unittests/clang-tidy/CMakeLists.txt
@@ -25,6 +25,7 @@
   clangFrontend
   clangLex
   clangTidy
+  clangTidyAndroidModule
   clangTidyGoogleModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: test/clang-tidy/android-file-open-flag.cpp
===
--- /dev/null
+++ test/clang-tidy/android-file-open-flag.cpp
@@ -0,0 +1,104 @@
+// RUN: %check_clang_tidy %s android-file-open-flag %t
+
+#define O_RDWR 1
+#define O_EXCL 2
+#define __O_CLOEXEC 3
+#define O_CLOEXEC __O_CLOEXEC
+
+extern "C" int open(const char *fn, int flags, ...);
+extern "C" int open64(const char *fn, int flags, ...);
+extern "C" int openat(int dirfd, const char *pathname, int flags, ...);
+
+void a() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void b() {
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open64("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void c() {
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  openat(0, "filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void f() {
+  open("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+  open64("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+  openat(0, "filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+
+  int flag = 3;
+  open("filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+namespace i {
+int open(const char *pathname, int flags, ...);
+int open64(const char *pathname, int flags, ...);
+int openat(int dirfd, const char *pathname, int flags, ...);
+
+void d() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+} // namespace i
+
+void e() {
+  open("filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open("filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+class G {
+public:
+  int open(const char *pathname, int flags, ...);
+  int open64(const char *pathname, int flags, ...);
+  int openat(int dirfd, const char *pathname, int flags, ...);
+
+  void h() {
+open("filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+open64("filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+openat(0, "filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+  }
+};
Index: docs/clang-tidy/index.rst
===
--- docs/clang-tidy/index.rst
+++ docs/clang-tidy/index.rst
@@ -55,6 +55,7 @@
 == =
 Name prefixDescription
 

[PATCH] D34002: [clang-tidy] When" -fno-exceptions is used", this warning is better to be suppressed.

2017-06-07 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 101834.
yawanng marked an inline comment as done.

https://reviews.llvm.org/D34002

Files:
  clang-tidy/misc/NoexceptMoveConstructorCheck.cpp
  test/clang-tidy/misc-noexcept-move-constructor.cpp


Index: test/clang-tidy/misc-noexcept-move-constructor.cpp
===
--- test/clang-tidy/misc-noexcept-move-constructor.cpp
+++ test/clang-tidy/misc-noexcept-move-constructor.cpp
@@ -1,16 +1,25 @@
-// RUN: %check_clang_tidy %s misc-noexcept-move-constructor %t
+// RUN: clang-tidy %s -checks="-*,misc-noexcept-move-constructor" -- 
-std=c++11 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-EXCEPTIONS \
+// RUN:   -implicit-check-not="{{warning|error}}:"
+// RUN: clang-tidy %s -checks="-*,misc-noexcept-move-constructor" -- 
-fno-exceptions -std=c++11 \
+// RUN:   | FileCheck %s -allow-empty -check-prefix=CHECK-NONEXCEPTIONS \
+// RUN:   -implicit-check-not="{{warning|error}}:"
+
 
 class A {
   A(A &&);
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: move constructors should be 
marked noexcept [misc-noexcept-move-constructor]
+  // CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: move constructors should be 
marked noexcept [misc-noexcept-move-constructor]
+  // CHECK-NONEXCEPTIONS-NOT: warning:
   A &operator=(A &&);
-  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: move assignment operators should
+  // CHECK-EXCEPTIONS: :[[@LINE-1]]:6: warning: move assignment operators 
should
+  // CHECK-NONEXCEPTIONS-NOT: warning:
 };
 
 struct B {
   static constexpr bool kFalse = false;
   B(B &&) noexcept(kFalse);
-  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: noexcept specifier on the move 
constructor evaluates to 'false' [misc-noexcept-move-constructor]
+  // CHECK-EXCEPTIONS: :[[@LINE-1]]:20: warning: noexcept specifier on the 
move constructor evaluates to 'false' [misc-noexcept-move-constructor]
+  // CHECK-NONEXCEPTIONS-NOT: warning:
 };
 
 class OK {};
Index: clang-tidy/misc/NoexceptMoveConstructorCheck.cpp
===
--- clang-tidy/misc/NoexceptMoveConstructorCheck.cpp
+++ clang-tidy/misc/NoexceptMoveConstructorCheck.cpp
@@ -20,7 +20,7 @@
 void NoexceptMoveConstructorCheck::registerMatchers(MatchFinder *Finder) {
   // Only register the matchers for C++11; the functionality currently does not
   // provide any benefit to other languages, despite being benign.
-  if (!getLangOpts().CPlusPlus11)
+  if (!getLangOpts().CPlusPlus11 || !getLangOpts().CXXExceptions)
 return;
 
   Finder->addMatcher(


Index: test/clang-tidy/misc-noexcept-move-constructor.cpp
===
--- test/clang-tidy/misc-noexcept-move-constructor.cpp
+++ test/clang-tidy/misc-noexcept-move-constructor.cpp
@@ -1,16 +1,25 @@
-// RUN: %check_clang_tidy %s misc-noexcept-move-constructor %t
+// RUN: clang-tidy %s -checks="-*,misc-noexcept-move-constructor" -- -std=c++11 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-EXCEPTIONS \
+// RUN:   -implicit-check-not="{{warning|error}}:"
+// RUN: clang-tidy %s -checks="-*,misc-noexcept-move-constructor" -- -fno-exceptions -std=c++11 \
+// RUN:   | FileCheck %s -allow-empty -check-prefix=CHECK-NONEXCEPTIONS \
+// RUN:   -implicit-check-not="{{warning|error}}:"
+
 
 class A {
   A(A &&);
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: move constructors should be marked noexcept [misc-noexcept-move-constructor]
+  // CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: move constructors should be marked noexcept [misc-noexcept-move-constructor]
+  // CHECK-NONEXCEPTIONS-NOT: warning:
   A &operator=(A &&);
-  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: move assignment operators should
+  // CHECK-EXCEPTIONS: :[[@LINE-1]]:6: warning: move assignment operators should
+  // CHECK-NONEXCEPTIONS-NOT: warning:
 };
 
 struct B {
   static constexpr bool kFalse = false;
   B(B &&) noexcept(kFalse);
-  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: noexcept specifier on the move constructor evaluates to 'false' [misc-noexcept-move-constructor]
+  // CHECK-EXCEPTIONS: :[[@LINE-1]]:20: warning: noexcept specifier on the move constructor evaluates to 'false' [misc-noexcept-move-constructor]
+  // CHECK-NONEXCEPTIONS-NOT: warning:
 };
 
 class OK {};
Index: clang-tidy/misc/NoexceptMoveConstructorCheck.cpp
===
--- clang-tidy/misc/NoexceptMoveConstructorCheck.cpp
+++ clang-tidy/misc/NoexceptMoveConstructorCheck.cpp
@@ -20,7 +20,7 @@
 void NoexceptMoveConstructorCheck::registerMatchers(MatchFinder *Finder) {
   // Only register the matchers for C++11; the functionality currently does not
   // provide any benefit to other languages, despite being benign.
-  if (!getLangOpts().CPlusPlus11)
+  if (!getLangOpts().CPlusPlus11 || !getLangOpts().CXXExceptions)
 return;
 
   Finder->addMatcher(
___
cfe-commits mailing list
cfe-commits@list

[PATCH] D33304: [clang-tidy][Part1] Add a new module Android and three new checks.

2017-06-09 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 102064.
yawanng marked 6 inline comments as done.

https://reviews.llvm.org/D33304

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/FileOpenFlagCheck.cpp
  clang-tidy/android/FileOpenFlagCheck.h
  clang-tidy/plugin/CMakeLists.txt
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-file-open-flag.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/index.rst
  test/clang-tidy/android-file-open-flag.cpp
  unittests/clang-tidy/CMakeLists.txt

Index: unittests/clang-tidy/CMakeLists.txt
===
--- unittests/clang-tidy/CMakeLists.txt
+++ unittests/clang-tidy/CMakeLists.txt
@@ -25,6 +25,7 @@
   clangFrontend
   clangLex
   clangTidy
+  clangTidyAndroidModule
   clangTidyGoogleModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: test/clang-tidy/android-file-open-flag.cpp
===
--- /dev/null
+++ test/clang-tidy/android-file-open-flag.cpp
@@ -0,0 +1,104 @@
+// RUN: %check_clang_tidy %s android-file-open-flag %t
+
+#define O_RDWR 1
+#define O_EXCL 2
+#define __O_CLOEXEC 3
+#define O_CLOEXEC __O_CLOEXEC
+
+extern "C" int open(const char *fn, int flags, ...);
+extern "C" int open64(const char *fn, int flags, ...);
+extern "C" int openat(int dirfd, const char *pathname, int flags, ...);
+
+void a() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'open' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: 'open' should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void b() {
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: 'open64' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open64("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'open64' should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void c() {
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'openat' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  openat(0, "filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: 'openat' should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void f() {
+  open("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'open' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+  open64("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'open64' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+  openat(0, "filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'openat' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+
+  int flag = 3;
+  open("filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+namespace i {
+int open(const char *pathname, int flags, ...);
+int open64(const char *pathname, int flags, ...);
+int openat(int dirfd, const char *pathname, int flags, ...);
+
+void d() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+} // namespace i
+
+void e() {
+  open("filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open("filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+class G {
+public:
+  int open(const char *pathname, int flags, ...);
+  int open64(const char *pathname, int flags, ...);
+  int openat(int dirfd, const char *pathname, int flags, ...);
+
+  void h() {
+open("filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+open64("filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+openat(0, "filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+  }
+};
Index: docs/clang-tidy/index.rst
===
--- docs/clang-tidy/index.rst
+++ docs/clang-tidy/index.rst
@@ -55,6 +55,7 @@
 == =
 Name prefixDescrip

[PATCH] D33304: [clang-tidy][Part1] Add a new module Android and three new checks.

2017-06-13 Thread Yan Wang via Phabricator via cfe-commits
yawanng added inline comments.



Comment at: docs/clang-tidy/checks/android-file-open-flag.rst:6
+
+A common source of security bugs has been code that opens file without using
+the ``O_CLOEXEC`` flag.  Without that flag, an opened sensitive file would

alexfh wrote:
> I'm not sure about using of "has been" here. Maybe just use present tense? 
> You might want to consult a nearby native speaker though. Alternatively, you 
> might want to rephrase this as "Opening files using POSIX ``open`` or similar 
> system calls without specifying the ``O_CLOEXEC`` flag is a common source of 
> security bugs."
I copied these sentences from the requests written by a native speaker, I 
think. But after talking with another native speaker, yes, present tense seems 
to be better here. Thanks :)


https://reviews.llvm.org/D33304



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33304: [clang-tidy][Part1] Add a new module Android and three new checks.

2017-06-14 Thread Yan Wang via Phabricator via cfe-commits
yawanng added inline comments.



Comment at: clang-tidy/android/FileOpenFlagCheck.cpp:61
+  SourceLocation EndLoc =
+  Lexer::getLocForEndOfToken(FlagArg->getLocEnd(), 0, SM, getLangOpts());
+

hokein wrote:
> Instead of using getLangOpts(), you should use `Result.Context.getLangOpts()`.
May I ask what's the difference between the `Result.Context.getLangOpts()` and 
`getLangOpts()`? Does `Result.Context.getLangOpts()` have a longer lifetime 
than `getLangOpts()`?



Comment at: clang-tidy/android/FileOpenFlagCheck.cpp:79
+std::pair ExpansionInfo = SM.getDecomposedLoc(Loc);
+auto MacroName =
+SM.getBufferData(ExpansionInfo.first)

hokein wrote:
> You could use `Lexer::getImmediateMacroName(Loc, SM, Opts);` to get the marco 
> name, or doesn't it work here?
`getImmediateMacroName` sometimes cannot return the `O_CLOEXEC `, like

#define O_CLOEXEC  _O_CLOEXEC
#define _O_CLOEXEC  1

`getImmediateMacroName` will return `_O_CLOEXEC`, whereas `O_CLOEXEC` is what 
we need.  I change this to directly get the source text if it's a macro, which 
seems to be simpler.


https://reviews.llvm.org/D33304



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33304: [clang-tidy][Part1] Add a new module Android and three new checks.

2017-06-14 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 102577.
yawanng marked 7 inline comments as done.

https://reviews.llvm.org/D33304

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/FileOpenFlagCheck.cpp
  clang-tidy/android/FileOpenFlagCheck.h
  clang-tidy/plugin/CMakeLists.txt
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  clang-tidy/tool/run-clang-tidy.py
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-file-open-flag.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/index.rst
  test/clang-tidy/android-file-open-flag.cpp
  unittests/clang-tidy/CMakeLists.txt

Index: unittests/clang-tidy/CMakeLists.txt
===
--- unittests/clang-tidy/CMakeLists.txt
+++ unittests/clang-tidy/CMakeLists.txt
@@ -25,6 +25,7 @@
   clangFrontend
   clangLex
   clangTidy
+  clangTidyAndroidModule
   clangTidyGoogleModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: test/clang-tidy/android-file-open-flag.cpp
===
--- /dev/null
+++ test/clang-tidy/android-file-open-flag.cpp
@@ -0,0 +1,110 @@
+// RUN: %check_clang_tidy %s android-file-open-flag %t
+
+#define O_RDWR 1
+#define O_EXCL 2
+#define __O_CLOEXEC 3
+#define O_CLOEXEC __O_CLOEXEC
+
+extern "C" int open(const char *fn, int flags, ...);
+extern "C" int open64(const char *fn, int flags, ...);
+extern "C" int openat(int dirfd, const char *pathname, int flags, ...);
+
+void a() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'open' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: 'open' should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void b() {
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: 'open64' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open64("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'open64' should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void c() {
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'openat' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  openat(0, "filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: 'openat' should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void f() {
+  open("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'open' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+  open64("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'open64' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+  openat(0, "filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'openat' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+
+  int flag = 3;
+  open("filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+namespace i {
+int open(const char *pathname, int flags, ...);
+int open64(const char *pathname, int flags, ...);
+int openat(int dirfd, const char *pathname, int flags, ...);
+
+void d() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+} // namespace i
+
+void e() {
+  open("filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open("filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open("filename", O_RDWR | O_CLOEXEC | O_EXCL);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR | O_CLOEXEC | O_EXCL);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR | O_CLOEXEC | O_EXCL);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+class G {
+public:
+  int open(const char *pathname, int flags, ...);
+  int open64(const char *pathname, int flags, ...);
+  int openat(int dirfd, const char *pathname, int flags, ...);
+
+  void h() {
+open("filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+open64("filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+openat(0, "filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+  

[PATCH] D33304: [clang-tidy][Part1] Add a new module Android and three new checks.

2017-06-15 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 102690.
yawanng added a comment.

Format change.


https://reviews.llvm.org/D33304

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/FileOpenFlagCheck.cpp
  clang-tidy/android/FileOpenFlagCheck.h
  clang-tidy/plugin/CMakeLists.txt
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-file-open-flag.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/index.rst
  test/clang-tidy/android-file-open-flag.cpp
  unittests/clang-tidy/CMakeLists.txt

Index: unittests/clang-tidy/CMakeLists.txt
===
--- unittests/clang-tidy/CMakeLists.txt
+++ unittests/clang-tidy/CMakeLists.txt
@@ -25,6 +25,7 @@
   clangFrontend
   clangLex
   clangTidy
+  clangTidyAndroidModule
   clangTidyGoogleModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: test/clang-tidy/android-file-open-flag.cpp
===
--- /dev/null
+++ test/clang-tidy/android-file-open-flag.cpp
@@ -0,0 +1,110 @@
+// RUN: %check_clang_tidy %s android-file-open-flag %t
+
+#define O_RDWR 1
+#define O_EXCL 2
+#define __O_CLOEXEC 3
+#define O_CLOEXEC __O_CLOEXEC
+
+extern "C" int open(const char *fn, int flags, ...);
+extern "C" int open64(const char *fn, int flags, ...);
+extern "C" int openat(int dirfd, const char *pathname, int flags, ...);
+
+void a() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'open' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: 'open' should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void b() {
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: 'open64' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open64("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'open64' should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void c() {
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'openat' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  openat(0, "filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: 'openat' should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void f() {
+  open("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'open' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+  open64("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'open64' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+  openat(0, "filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'openat' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+
+  int flag = 3;
+  open("filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+namespace i {
+int open(const char *pathname, int flags, ...);
+int open64(const char *pathname, int flags, ...);
+int openat(int dirfd, const char *pathname, int flags, ...);
+
+void d() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+} // namespace i
+
+void e() {
+  open("filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open("filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open("filename", O_RDWR | O_CLOEXEC | O_EXCL);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR | O_CLOEXEC | O_EXCL);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR | O_CLOEXEC | O_EXCL);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+class G {
+public:
+  int open(const char *pathname, int flags, ...);
+  int open64(const char *pathname, int flags, ...);
+  int openat(int dirfd, const char *pathname, int flags, ...);
+
+  void h() {
+open("filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+open64("filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+openat(0, "filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+  }
+};
Index: docs/clang-tidy/index.r

[PATCH] D34114: [clang] A better format for unnecessary packed warning.

2017-06-16 Thread Yan Wang via Phabricator via cfe-commits
yawanng added a comment.

Ping.


Repository:
  rL LLVM

https://reviews.llvm.org/D34114



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33304: [clang-tidy][Part1] Add a new module Android and three new checks.

2017-06-19 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 103068.
yawanng marked 3 inline comments as done.

https://reviews.llvm.org/D33304

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/FileOpenFlagCheck.cpp
  clang-tidy/android/FileOpenFlagCheck.h
  clang-tidy/plugin/CMakeLists.txt
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-file-open-flag.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/index.rst
  test/clang-tidy/android-file-open-flag.cpp
  unittests/clang-tidy/CMakeLists.txt

Index: unittests/clang-tidy/CMakeLists.txt
===
--- unittests/clang-tidy/CMakeLists.txt
+++ unittests/clang-tidy/CMakeLists.txt
@@ -25,6 +25,7 @@
   clangFrontend
   clangLex
   clangTidy
+  clangTidyAndroidModule
   clangTidyGoogleModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: test/clang-tidy/android-file-open-flag.cpp
===
--- /dev/null
+++ test/clang-tidy/android-file-open-flag.cpp
@@ -0,0 +1,110 @@
+// RUN: %check_clang_tidy %s android-file-open-flag %t
+
+#define O_RDWR 1
+#define O_EXCL 2
+#define __O_CLOEXEC 3
+#define O_CLOEXEC __O_CLOEXEC
+
+extern "C" int open(const char *fn, int flags, ...);
+extern "C" int open64(const char *fn, int flags, ...);
+extern "C" int openat(int dirfd, const char *pathname, int flags, ...);
+
+void a() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'open' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: 'open' should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void b() {
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: 'open64' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open64("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'open64' should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void c() {
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'openat' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  openat(0, "filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: 'openat' should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void f() {
+  open("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'open' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+  open64("filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'open64' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+  openat(0, "filename", 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'openat' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-FIXES: 3 | O_CLOEXEC
+
+  int flag = 3;
+  open("filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", flag);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+namespace i {
+int open(const char *pathname, int flags, ...);
+int open64(const char *pathname, int flags, ...);
+int openat(int dirfd, const char *pathname, int flags, ...);
+
+void d() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+} // namespace i
+
+void e() {
+  open("filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open("filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open("filename", O_RDWR | O_CLOEXEC | O_EXCL);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  open64("filename", O_RDWR | O_CLOEXEC | O_EXCL);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR | O_CLOEXEC);
+  // CHECK-MESSAGES-NOT: warning:
+  openat(0, "filename", O_RDWR | O_CLOEXEC | O_EXCL);
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+class G {
+public:
+  int open(const char *pathname, int flags, ...);
+  int open64(const char *pathname, int flags, ...);
+  int openat(int dirfd, const char *pathname, int flags, ...);
+
+  void h() {
+open("filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+open64("filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+openat(0, "filename", O_RDWR);
+// CHECK-MESSAGES-NOT: warning:
+  }
+};
Index: docs/clang-tidy/index.r

[PATCH] D34633: [clang-tidy] Fix a bug in android-file-open-flag

2017-06-26 Thread Yan Wang via Phabricator via cfe-commits
yawanng created this revision.
yawanng added a project: clang-tools-extra.
Herald added subscribers: xazax.hun, JDevlieghere.

Handle a case when the function is passed as an argument of a function-like 
macro. Plus fix a format that was forgotten to commit last time.


Repository:
  rL LLVM

https://reviews.llvm.org/D34633

Files:
  clang-tidy/android/FileOpenFlagCheck.cpp
  test/clang-tidy/android-file-open-flag.cpp

Index: test/clang-tidy/android-file-open-flag.cpp
===
--- test/clang-tidy/android-file-open-flag.cpp
+++ test/clang-tidy/android-file-open-flag.cpp
@@ -4,6 +4,13 @@
 #define O_EXCL 2
 #define __O_CLOEXEC 3
 #define O_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({\
+int _rc;\
+do {\
+  _rc = (exp);  \
+} while (_rc == -1);\
+  })
 
 extern "C" int open(const char *fn, int flags, ...);
 extern "C" int open64(const char *fn, int flags, ...);
@@ -13,47 +20,80 @@
   open("filename", O_RDWR);
   // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'open' should use O_CLOEXEC where possible [android-file-open-flag]
   // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  TEMP_FAILURE_RETRY(open("filename", O_RDWR));
+  // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: 'open' should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
   open("filename", O_RDWR | O_EXCL);
   // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: 'open' should use O_CLOEXEC where
   // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+  TEMP_FAILURE_RETRY(open("filename", O_RDWR | O_EXCL));
+  // CHECK-MESSAGES: :[[@LINE-1]]:54: warning: 'open' should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
 }
 
 void b() {
   open64("filename", O_RDWR);
   // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: 'open64' should use O_CLOEXEC where possible [android-file-open-flag]
   // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  TEMP_FAILURE_RETRY(open64("filename", O_RDWR));
+  // CHECK-MESSAGES: :[[@LINE-1]]:47: warning: 'open64' should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
   open64("filename", O_RDWR | O_EXCL);
   // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'open64' should use O_CLOEXEC where
   // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+  TEMP_FAILURE_RETRY(open64("filename", O_RDWR | O_EXCL));
+  // CHECK-MESSAGES: :[[@LINE-1]]:56: warning: 'open64' should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
 }
 
 void c() {
   openat(0, "filename", O_RDWR);
   // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'openat' should use O_CLOEXEC where possible [android-file-open-flag]
   // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR));
+  // CHECK-MESSAGES: :[[@LINE-1]]:50: warning: 'openat' should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
   openat(0, "filename", O_RDWR | O_EXCL);
   // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: 'openat' should use O_CLOEXEC where
   // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+  TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR | O_EXCL));
+  // CHECK-MESSAGES: :[[@LINE-1]]:59: warning: 'openat' should use O_CLOEXEC where
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
 }
 
 void f() {
   open("filename", 3);
   // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'open' should use O_CLOEXEC where possible [android-file-open-flag]
   // CHECK-FIXES: 3 | O_CLOEXEC
+  TEMP_FAILURE_RETRY(open("filename", 3));
+  // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: 'open' should use O_CLOEXEC where
+  // CHECK-FIXES: 3 | O_CLOEXEC
   open64("filename", 3);
   // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'open64' should use O_CLOEXEC where possible [android-file-open-flag]
   // CHECK-FIXES: 3 | O_CLOEXEC
+  TEMP_FAILURE_RETRY(open64("filename", 3));
+  // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: 'open64' should use O_CLOEXEC where
+  // CHECK-FIXES: 3 | O_CLOEXEC
   openat(0, "filename", 3);
   // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'openat' should use O_CLOEXEC where possible [android-file-open-flag]
   // CHECK-FIXES: 3 | O_CLOEXEC
+  TEMP_FAILURE_RETRY(openat(0, "filename", 3));
+  // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: 'openat' should use O_CLOEXEC where
+  // CHECK-FIXES: 3 | O_CLOEXEC
 
   int flag = 3;
   open("filename", flag);
   // CHECK-MESSAGES-NOT: warning:
+  TEMP_FAILURE_RETRY(open("filename", flag));
+  // CHECK-MESSAGES-NOT: warning:
   open64("filename", flag);
   // CHECK-MESSAGES-NOT: warning:
+  TEMP_FAILURE_RETRY(open64("filename", flag));
+  // CHECK-MESSAGES-NOT: warning:
   openat(0, "filename", flag);
   // CHECK-MESSAGES-NOT: warning:
+  TEMP_FAILURE_RETRY(openat(0, "filename", flag));
+  // CHECK-MESSAGES-NOT: warning:
 }
 
 namespace i {
@@ -64,10 +104,16 @@
 void d() {
   open("filename", O_RDWR);
   // CHECK-MESSAGES-NOT: warning:
+  TEMP_FAILURE_RETRY(open("filename", O_RDWR));
+  // CHECK-MESSAGES-NOT: warning:
   open64("filename", O_RDWR);

[PATCH] D34114: [clang] Change the condition of unnecessary packed warning

2017-07-28 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 108665.
yawanng marked 3 inline comments as done.

https://reviews.llvm.org/D34114

Files:
  lib/AST/RecordLayoutBuilder.cpp
  test/CodeGenCXX/warn-padded-packed.cpp

Index: test/CodeGenCXX/warn-padded-packed.cpp
===
--- test/CodeGenCXX/warn-padded-packed.cpp
+++ test/CodeGenCXX/warn-padded-packed.cpp
@@ -17,7 +17,7 @@
 } __attribute__((packed));
 
 struct S4 {
-  int i; // expected-warning {{packed attribute is unnecessary for 'i'}}
+  int i;
   char c;
 } __attribute__((packed));
 
@@ -46,18 +46,18 @@
   int i; // expected-warning {{padding struct 'S8' with 3 bytes to align 'i'}}
 };
 
-struct S9 { // expected-warning {{packed attribute is unnecessary for 'S9'}}
-  int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
-  int y; // expected-warning {{packed attribute is unnecessary for 'y'}}
+struct S9 {
+  int x;
+  int y;
 } __attribute__((packed));
 
-struct S10 { // expected-warning {{packed attribute is unnecessary for 'S10'}}
-  int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
+struct S10 {
+  int x;
   char a,b,c,d;
 } __attribute__((packed));
 
 
-struct S11 {
+struct S11 { // expected-warning {{packed attribute is unnecessary for 'S11'}}
   bool x;
   char a,b,c,d;
 } __attribute__((packed));
@@ -72,5 +72,82 @@
   bool b : 10;
 };
 
+struct S14 { // expected-warning {{packed attribute is unnecessary for 'S14'}}
+  char a,b,c,d;
+} __attribute__((packed));
+
+struct S15 { // expected-warning {{packed attribute is unnecessary for 'S15'}}
+  struct S14 s;
+  char a;
+} __attribute__((packed));
+
+struct S16 { // expected-warning {{padding size of 'S16' with 2 bytes to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S16'}}
+  char a,b;
+} __attribute__((packed, aligned(4)));
+
+struct S17 {
+  struct S16 s;
+  char a,b;
+} __attribute__((packed, aligned(2)));
+
+struct S18 { // expected-warning {{padding size of 'S18' with 2 bytes to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S18'}}
+  struct S16 s;
+  char a,b;
+} __attribute__((packed, aligned(4)));
+
+struct S19 { // expected-warning {{packed attribute is unnecessary for 'S19'}}
+  bool b;
+  char a;
+} __attribute__((packed, aligned(1)));
+
+struct S20 {
+  int i;
+  char a;
+} __attribute__((packed, aligned(1)));
+
+struct S21 { // expected-warning {{padding size of 'S21' with 4 bits to alignment boundary}}
+  unsigned char a : 6;
+  unsigned char b : 6;
+} __attribute__((packed, aligned(1)));
+
+struct S22 { // expected-warning {{packed attribute is unnecessary for 'S22'}}
+  unsigned char a : 4;
+  unsigned char b : 4;
+} __attribute__((packed));
+
+struct S23 { // expected-warning {{padding size of 'S23' with 4 bits to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S23'}}
+  unsigned char a : 2;
+  unsigned char b : 2;
+} __attribute__((packed));
+
+struct S24 {
+  unsigned char a : 6;
+  unsigned char b : 6;
+  unsigned char c : 6;
+  unsigned char d : 6;
+  unsigned char e : 6;
+  unsigned char f : 6;
+  unsigned char g : 6;
+  unsigned char h : 6;
+} __attribute__((packed));
+
+struct S25 { // expected-warning {{padding size of 'S25' with 7 bits to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S25'}}
+  unsigned char a;
+  unsigned char b : 1;
+} __attribute__((packed));
+
+struct S26 { // expected-warning {{packed attribute is unnecessary for 'S26'}}
+  unsigned char a : 1;
+  unsigned char b; //expected-warning {{padding struct 'S26' with 7 bits to align 'b'}}
+} __attribute__((packed));
+
+struct S27 { // expected-warning {{padding size of 'S27' with 7 bits to alignment boundary}}
+  unsigned char a : 1;
+  unsigned char b : 8;
+} __attribute__((packed));
+
+
 // The warnings are emitted when the layout of the structs is computed, so we have to use them.
-void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*) { }
+void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*,
+   S14*, S15*, S16*, S17*, S18*, S19*, S20*, S21*, S22*, S23*, S24*, S25*,
+   S26*, S27*){}
Index: lib/AST/RecordLayoutBuilder.cpp
===
--- lib/AST/RecordLayoutBuilder.cpp
+++ lib/AST/RecordLayoutBuilder.cpp
@@ -632,6 +632,9 @@
   /// pointer, as opposed to inheriting one from a primary base class.
   bool HasOwnVFPtr;
 
+  /// \brief the flag of field offset changing due to packed attribute.
+  bool HasPackedField;
+
   typedef llvm::DenseMap BaseOffsetsMapTy;
 
   /// Bases - base classes and their offsets in the record.
@@ -666,7 +669,7 @@
 NonVirtualSize(CharUnits::Zero()),
 NonVirtualAlignment(CharUnits::One()), PrimaryBase(nullptr),
 PrimaryBaseIsVirtual(false), HasOwnVFPtr(false),
-FirstNearlyEmptyVBase(nullptr) {}
+HasPackedField(false), FirstNearlyEmpt

[PATCH] D35372: [clang-tidy] Refactor the code and add a close-on-exec check on memfd_create() in Android module.

2017-07-31 Thread Yan Wang via Phabricator via cfe-commits
yawanng added a comment.

Ping.


https://reviews.llvm.org/D35372



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35743: [clang-format] Handle Structured binding declaration in C++17

2017-07-31 Thread Yan Wang via Phabricator via cfe-commits
yawanng added a comment.

Ping.


https://reviews.llvm.org/D35743



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35743: [clang-format] Handle Structured binding declaration in C++17

2017-08-01 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 109222.
yawanng added a comment.

Move tests to unitest and fix a bug.


https://reviews.llvm.org/D35743

Files:
  lib/Format/TokenAnnotator.cpp
  lib/Format/UnwrappedLineParser.cpp
  lib/Format/UnwrappedLineParser.h
  unittests/Format/FormatTest.cpp

Index: unittests/Format/FormatTest.cpp
===
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -11085,6 +11085,41 @@
   EXPECT_EQ("auto c = u8'a';", format("auto c = u8'a';"));
 }
 
+TEST_F(FormatTest, StructuredBindingDeclaration) {
+  // structured-binding-declaration is a C++17 feature.
+  EXPECT_EQ("auto [x, y] = a;", format("auto[x, y] = a;"));
+  EXPECT_EQ("auto &[x, y] = a;", format("auto   &   [x, y] = a;"));
+  EXPECT_EQ("auto &&[x, y] = a;", format("auto &&   [x, y] = a;"));
+  EXPECT_EQ("auto &&[x, y] = a;", format("auto &&   [x, y] = a;"));
+  EXPECT_EQ("auto [x] = a;", format("auto[x] = a;"));
+  EXPECT_EQ("auto &[x] = a;", format("auto   &   [x] = a;"));
+  EXPECT_EQ("auto &&[x] = a;", format("auto &&   [x] = a;"));
+  EXPECT_EQ("const auto [x, y] = f();", format("const auto[x, y] = f();"));
+  EXPECT_EQ("const auto &[x, y] = f();", format("const auto  &   [x, y] = f();"));
+  EXPECT_EQ("const auto &&[x, y] = f();", format("const auto  &&   [x, y] = f();"));
+  EXPECT_EQ("auto [x, y] = A{};", format("auto[x,y] = A{};"));
+  EXPECT_EQ("auto &[x, y] = A{};", format("auto   &   [x,y] = A{};"));
+  EXPECT_EQ("auto &&[x, y] = A{};", format("auto   &&   [x,y] = A{};"));
+  EXPECT_EQ("for (const auto &&[a, b] : some_range) {\n"
+"}",
+format("for (const auto   &&   [a, b] : some_range) {\n"
+"}"));
+  EXPECT_EQ("for (const auto &[a, b] : some_range) {\n"
+"}",
+format("for (const auto   &   [a, b] : some_range) {\n"
+"}"));
+  EXPECT_EQ("for (const auto [a, b] : some_range) {\n"
+"}",
+format("for (const auto[a, b] : some_range) {\n"
+"}"));
+  EXPECT_EQ("auto [x, y](expr);", format("auto[x,y]  (expr);"));
+  EXPECT_EQ("auto &[x, y](expr);", format("auto   &   [x,y](expr);"));
+  EXPECT_EQ("auto &&[x, y](expr);", format("auto   &&   [x,y](expr);"));
+  EXPECT_EQ("auto [x, y]{expr};", format("auto[x,y] {expr};"));
+  EXPECT_EQ("auto &[x, y]{expr};", format("auto   &   [x,y]  {expr};"));
+  EXPECT_EQ("auto &&[x, y]{expr};", format("auto   &&   [x,y]  {expr};"));
+}
+
 } // end namespace
 } // end namespace format
 } // end namespace clang
Index: lib/Format/UnwrappedLineParser.h
===
--- lib/Format/UnwrappedLineParser.h
+++ lib/Format/UnwrappedLineParser.h
@@ -125,6 +125,7 @@
   bool eof() const;
   void nextToken();
   const FormatToken *getPreviousToken();
+  const FormatToken *getPrePreviousToken();
   void readToken();
 
   // Decides which comment tokens should be added to the current line and which
Index: lib/Format/UnwrappedLineParser.cpp
===
--- lib/Format/UnwrappedLineParser.cpp
+++ lib/Format/UnwrappedLineParser.cpp
@@ -1211,9 +1211,12 @@
 return false;
   }
   const FormatToken* Previous = getPreviousToken();
+  const FormatToken* PrePrevious = getPrePreviousToken();
   if (Previous &&
   (Previous->isOneOf(tok::identifier, tok::kw_operator, tok::kw_new,
- tok::kw_delete) ||
+ tok::kw_delete, tok::kw_auto) ||
+   (PrePrevious && Previous->isOneOf(tok::amp, tok::ampamp) &&
+PrePrevious->is(tok::kw_auto)) ||
Previous->closesScope() || Previous->isSimpleTypeSpecifier())) {
 nextToken();
 return false;
@@ -2306,6 +2309,12 @@
   return Line->Tokens.back().Tok;
 }
 
+const FormatToken *UnwrappedLineParser::getPrePreviousToken() {
+  if (!Line || Line->Tokens.size() < 2)
+return nullptr;
+  return std::prev(Line->Tokens.end(), 2)->Tok;
+}
+
 void UnwrappedLineParser::distributeComments(
 const SmallVectorImpl &Comments,
 const FormatToken *NextTok) {
Index: lib/Format/TokenAnnotator.cpp
===
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -330,8 +330,15 @@
 (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
  Contexts.back().InTemplateArgument);
 
+bool CppStructuredBindingDecl =
+!CppArrayTemplates && Style.isCpp() && Parent &&
+(Parent->is(tok::kw_auto) ||
+ (Parent->isOneOf(tok::amp, tok::ampamp) &&
+  Parent->getPreviousNonComment() &&
+  Parent->getPreviousNonComment()->is(tok::kw_auto)));
+
 bool StartsObjCMethodExpr =
-!CppArrayTemplates && Style.isCpp() &&
+!CppStructuredBindingDecl && !CppArrayTemplates && Style.isCpp() &&
 Contexts.back().CanBeExpression && Le

[PATCH] D35372: [clang-tidy] Refactor the code and add a close-on-exec check on memfd_create() in Android module.

2017-08-03 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 109589.
yawanng marked 9 inline comments as done.

https://reviews.llvm.org/D35372

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecCheck.cpp
  clang-tidy/android/CloexecCheck.h
  clang-tidy/android/CloexecMemfdCreateCheck.cpp
  clang-tidy/android/CloexecMemfdCreateCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-memfd-create.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-memfd-create.cpp

Index: test/clang-tidy/android-cloexec-memfd-create.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-memfd-create.cpp
@@ -0,0 +1,63 @@
+// RUN: %check_clang_tidy %s android-cloexec-memfd-create %t
+
+#define MFD_ALLOW_SEALING 1
+#define __O_CLOEXEC 3
+#define MFD_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({\
+int _rc;\
+do {\
+  _rc = (exp);  \
+} while (_rc == -1);\
+  })
+#define NULL 0
+
+extern "C" int memfd_create(const char *name, unsigned int flags);
+
+void a() {
+  memfd_create(NULL, MFD_ALLOW_SEALING);
+  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: 'memfd_create' should use MFD_CLOEXEC where possible [android-cloexec-memfd-create]
+  // CHECK-FIXES: memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC)
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+  // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: 'memfd_create'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC))
+}
+
+void f() {
+  memfd_create(NULL, 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'memfd_create'
+  // CHECK-FIXES: memfd_create(NULL, 3 | MFD_CLOEXEC)
+  TEMP_FAILURE_RETRY(memfd_create(NULL, 3));
+  // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: 'memfd_create'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, 3 | MFD_CLOEXEC))
+
+  int flag = 3;
+  memfd_create(NULL, flag);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, flag));
+}
+
+namespace i {
+int memfd_create(const char *name, unsigned int flags);
+
+void d() {
+  memfd_create(NULL, MFD_ALLOW_SEALING);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+}
+
+} // namespace i
+
+void e() {
+  memfd_create(NULL, MFD_CLOEXEC);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_CLOEXEC));
+  memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC));
+}
+
+class G {
+public:
+  int memfd_create(const char *name, unsigned int flags);
+  void d() {
+memfd_create(NULL, MFD_ALLOW_SEALING);
+TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -6,6 +6,7 @@
 .. toctree::
android-cloexec-creat
android-cloexec-fopen
+   android-cloexec-memfd-create
android-cloexec-open
android-cloexec-socket
boost-use-to-string
Index: docs/clang-tidy/checks/android-cloexec-memfd-create.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-memfd-create.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-memfd-create
+
+android-cloexec-memfd-create
+
+
+``memfd_create()`` should include ``MFD_CLOEXEC`` in its type argument to avoid
+the file descriptor leakage. Without this flag, an opened sensitive file would
+remain open across a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  memfd_create(name, MFD_ALLOW_SEALING);
+
+  // becomes
+
+  memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -73,6 +73,12 @@
 
   Checks if the required mode ``e`` exists in the mode argument of ``fopen()``.
 
+- New `android-cloexec-memfd_create
+  `_ check
+
+  Checks if the required file flag ``MFD_CLOEXEC`` is present in the argument of
+  ``memfd_create()``.
+
 - New `android-cloexec-socket
   `_ check
 
Index: clang-tidy/android/CloexecMemfdCreateCheck.h
===
--- /dev/null
+++ clang-tidy/android/CloexecMemfdCreateCheck.h
@@ -0,0 +1,35 @@
+//===--- CloexecMemfdCreateCheck.h - clang-tidy-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---

[PATCH] D35372: [clang-tidy] Refactor the code and add a close-on-exec check on memfd_create() in Android module.

2017-08-03 Thread Yan Wang via Phabricator via cfe-commits
yawanng added inline comments.



Comment at: clang-tidy/android/CloexecCheck.h:35
+
+  // This issue has three types.
+  // Type1 is to insert the necessary macro flag in the flag argument.

hokein wrote:
> It is unclear to me what the "issue" means here? I assume there are three 
> types of fixes?
Yes. It means three types of fixes :-)



Comment at: clang-tidy/android/CloexecCheck.h:36
+  // This issue has three types.
+  // Type1 is to insert the necessary macro flag in the flag argument.
+  void

hokein wrote:
> Deserve a document on the behavior of the method, would be better to give an 
> example. The same below.
> 
> Is `Flag` required to be a macro flag? looks like it could be any string.
Yes, the flag is expected to be a string of the required macro name.




Comment at: clang-tidy/android/CloexecCheck.h:75
+  inline ast_matchers::internal::Matcher
+  hasSockAddrPointerTypeParameter(int n) {
+return ast_matchers::hasParameter(

hokein wrote:
> should we put this method and below in the base class? They seem to be 
> check-specific, I think? 
Only the 'mode_t' one is currently only used by one check. The reason for 
putting them all together here is to be kind of uniform and maybe facilitate 
possible future checks that may contain this type.


https://reviews.llvm.org/D35372



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35372: [clang-tidy] Refactor the code and add a close-on-exec check on memfd_create() in Android module.

2017-08-04 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 109778.
yawanng marked 13 inline comments as done.

https://reviews.llvm.org/D35372

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecCheck.cpp
  clang-tidy/android/CloexecCheck.h
  clang-tidy/android/CloexecMemfdCreateCheck.cpp
  clang-tidy/android/CloexecMemfdCreateCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-memfd-create.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-memfd-create.cpp

Index: test/clang-tidy/android-cloexec-memfd-create.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-memfd-create.cpp
@@ -0,0 +1,63 @@
+// RUN: %check_clang_tidy %s android-cloexec-memfd-create %t
+
+#define MFD_ALLOW_SEALING 1
+#define __O_CLOEXEC 3
+#define MFD_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({\
+int _rc;\
+do {\
+  _rc = (exp);  \
+} while (_rc == -1);\
+  })
+#define NULL 0
+
+extern "C" int memfd_create(const char *name, unsigned int flags);
+
+void a() {
+  memfd_create(NULL, MFD_ALLOW_SEALING);
+  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: 'memfd_create' should use MFD_CLOEXEC where possible [android-cloexec-memfd-create]
+  // CHECK-FIXES: memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC)
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+  // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: 'memfd_create'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC))
+}
+
+void f() {
+  memfd_create(NULL, 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'memfd_create'
+  // CHECK-FIXES: memfd_create(NULL, 3 | MFD_CLOEXEC)
+  TEMP_FAILURE_RETRY(memfd_create(NULL, 3));
+  // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: 'memfd_create'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, 3 | MFD_CLOEXEC))
+
+  int flag = 3;
+  memfd_create(NULL, flag);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, flag));
+}
+
+namespace i {
+int memfd_create(const char *name, unsigned int flags);
+
+void d() {
+  memfd_create(NULL, MFD_ALLOW_SEALING);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+}
+
+} // namespace i
+
+void e() {
+  memfd_create(NULL, MFD_CLOEXEC);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_CLOEXEC));
+  memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC));
+}
+
+class G {
+public:
+  int memfd_create(const char *name, unsigned int flags);
+  void d() {
+memfd_create(NULL, MFD_ALLOW_SEALING);
+TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -6,6 +6,7 @@
 .. toctree::
android-cloexec-creat
android-cloexec-fopen
+   android-cloexec-memfd-create
android-cloexec-open
android-cloexec-socket
boost-use-to-string
Index: docs/clang-tidy/checks/android-cloexec-memfd-create.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-memfd-create.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-memfd-create
+
+android-cloexec-memfd-create
+
+
+``memfd_create()`` should include ``MFD_CLOEXEC`` in its type argument to avoid
+the file descriptor leakage. Without this flag, an opened sensitive file would
+remain open across a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  memfd_create(name, MFD_ALLOW_SEALING);
+
+  // becomes
+
+  memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -73,6 +73,12 @@
 
   Checks if the required mode ``e`` exists in the mode argument of ``fopen()``.
 
+- New `android-cloexec-memfd_create
+  `_ check
+
+  Checks if the required file flag ``MFD_CLOEXEC`` is present in the argument of
+  ``memfd_create()``.
+
 - New `android-cloexec-socket
   `_ check
 
Index: clang-tidy/android/CloexecMemfdCreateCheck.h
===
--- /dev/null
+++ clang-tidy/android/CloexecMemfdCreateCheck.h
@@ -0,0 +1,35 @@
+//===--- CloexecMemfdCreateCheck.h - clang-tidy-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--

[PATCH] D35372: [clang-tidy] Refactor the code and add a close-on-exec check on memfd_create() in Android module.

2017-08-04 Thread Yan Wang via Phabricator via cfe-commits
yawanng added inline comments.



Comment at: clang-tidy/android/CloexecCheck.h:72
+  StringRef getSpellingArg(const ast_matchers::MatchFinder::MatchResult 
&Result,
+   int n);
+

hokein wrote:
> `n` should be capital `N`. I think we can make it a const member method. And 
> I can't see any usage of this method in this patch.
It's not used in this one, but in others.


https://reviews.llvm.org/D35372



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35372: [clang-tidy] Refactor the code and add a close-on-exec check on memfd_create() in Android module.

2017-08-07 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 110065.
yawanng marked 4 inline comments as done.

https://reviews.llvm.org/D35372

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecCheck.cpp
  clang-tidy/android/CloexecCheck.h
  clang-tidy/android/CloexecMemfdCreateCheck.cpp
  clang-tidy/android/CloexecMemfdCreateCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-memfd-create.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-memfd-create.cpp

Index: test/clang-tidy/android-cloexec-memfd-create.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-memfd-create.cpp
@@ -0,0 +1,63 @@
+// RUN: %check_clang_tidy %s android-cloexec-memfd-create %t
+
+#define MFD_ALLOW_SEALING 1
+#define __O_CLOEXEC 3
+#define MFD_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({\
+int _rc;\
+do {\
+  _rc = (exp);  \
+} while (_rc == -1);\
+  })
+#define NULL 0
+
+extern "C" int memfd_create(const char *name, unsigned int flags);
+
+void a() {
+  memfd_create(NULL, MFD_ALLOW_SEALING);
+  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: 'memfd_create' should use MFD_CLOEXEC where possible [android-cloexec-memfd-create]
+  // CHECK-FIXES: memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC)
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+  // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: 'memfd_create'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC))
+}
+
+void f() {
+  memfd_create(NULL, 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'memfd_create'
+  // CHECK-FIXES: memfd_create(NULL, 3 | MFD_CLOEXEC)
+  TEMP_FAILURE_RETRY(memfd_create(NULL, 3));
+  // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: 'memfd_create'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, 3 | MFD_CLOEXEC))
+
+  int flag = 3;
+  memfd_create(NULL, flag);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, flag));
+}
+
+namespace i {
+int memfd_create(const char *name, unsigned int flags);
+
+void d() {
+  memfd_create(NULL, MFD_ALLOW_SEALING);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+}
+
+} // namespace i
+
+void e() {
+  memfd_create(NULL, MFD_CLOEXEC);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_CLOEXEC));
+  memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC));
+}
+
+class G {
+public:
+  int memfd_create(const char *name, unsigned int flags);
+  void d() {
+memfd_create(NULL, MFD_ALLOW_SEALING);
+TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -6,6 +6,7 @@
 .. toctree::
android-cloexec-creat
android-cloexec-fopen
+   android-cloexec-memfd-create
android-cloexec-open
android-cloexec-socket
boost-use-to-string
Index: docs/clang-tidy/checks/android-cloexec-memfd-create.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-memfd-create.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-memfd-create
+
+android-cloexec-memfd-create
+
+
+``memfd_create()`` should include ``MFD_CLOEXEC`` in its type argument to avoid
+the file descriptor leakage. Without this flag, an opened sensitive file would
+remain open across a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  memfd_create(name, MFD_ALLOW_SEALING);
+
+  // becomes
+
+  memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -73,6 +73,12 @@
 
   Checks if the required mode ``e`` exists in the mode argument of ``fopen()``.
 
+- New `android-cloexec-memfd_create
+  `_ check
+
+  Checks if the required file flag ``MFD_CLOEXEC`` is present in the argument of
+  ``memfd_create()``.
+
 - New `android-cloexec-socket
   `_ check
 
Index: clang-tidy/android/CloexecMemfdCreateCheck.h
===
--- /dev/null
+++ clang-tidy/android/CloexecMemfdCreateCheck.h
@@ -0,0 +1,35 @@
+//===--- CloexecMemfdCreateCheck.h - clang-tidy-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---

[PATCH] D35372: [clang-tidy] Refactor the code and add a close-on-exec check on memfd_create() in Android module.

2017-08-07 Thread Yan Wang via Phabricator via cfe-commits
yawanng added a comment.

In https://reviews.llvm.org/D35372#834238, @hokein wrote:

> Looks good to me, a few nits. Thanks for improving it continuously.
>
> I'd hold it for a while to see whether @alexfh has further comments before 
> submitting it.


Thank you for the reviewing :-)


https://reviews.llvm.org/D35372



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35372: [clang-tidy] Refactor the code and add a close-on-exec check on memfd_create() in Android module.

2017-08-09 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 110443.
yawanng marked 5 inline comments as done.

https://reviews.llvm.org/D35372

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecCheck.cpp
  clang-tidy/android/CloexecCheck.h
  clang-tidy/android/CloexecMemfdCreateCheck.cpp
  clang-tidy/android/CloexecMemfdCreateCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-memfd-create.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-memfd-create.cpp

Index: test/clang-tidy/android-cloexec-memfd-create.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-memfd-create.cpp
@@ -0,0 +1,63 @@
+// RUN: %check_clang_tidy %s android-cloexec-memfd-create %t
+
+#define MFD_ALLOW_SEALING 1
+#define __O_CLOEXEC 3
+#define MFD_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({\
+int _rc;\
+do {\
+  _rc = (exp);  \
+} while (_rc == -1);\
+  })
+#define NULL 0
+
+extern "C" int memfd_create(const char *name, unsigned int flags);
+
+void a() {
+  memfd_create(NULL, MFD_ALLOW_SEALING);
+  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: 'memfd_create' should use MFD_CLOEXEC where possible [android-cloexec-memfd-create]
+  // CHECK-FIXES: memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC)
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+  // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: 'memfd_create'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC))
+}
+
+void f() {
+  memfd_create(NULL, 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'memfd_create'
+  // CHECK-FIXES: memfd_create(NULL, 3 | MFD_CLOEXEC)
+  TEMP_FAILURE_RETRY(memfd_create(NULL, 3));
+  // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: 'memfd_create'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, 3 | MFD_CLOEXEC))
+
+  int flag = 3;
+  memfd_create(NULL, flag);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, flag));
+}
+
+namespace i {
+int memfd_create(const char *name, unsigned int flags);
+
+void d() {
+  memfd_create(NULL, MFD_ALLOW_SEALING);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+}
+
+} // namespace i
+
+void e() {
+  memfd_create(NULL, MFD_CLOEXEC);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_CLOEXEC));
+  memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC));
+}
+
+class G {
+public:
+  int memfd_create(const char *name, unsigned int flags);
+  void d() {
+memfd_create(NULL, MFD_ALLOW_SEALING);
+TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -6,6 +6,7 @@
 .. toctree::
android-cloexec-creat
android-cloexec-fopen
+   android-cloexec-memfd-create
android-cloexec-open
android-cloexec-socket
boost-use-to-string
Index: docs/clang-tidy/checks/android-cloexec-memfd-create.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-memfd-create.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-memfd-create
+
+android-cloexec-memfd-create
+
+
+``memfd_create()`` should include ``MFD_CLOEXEC`` in its type argument to avoid
+the file descriptor leakage. Without this flag, an opened sensitive file would
+remain open across a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  memfd_create(name, MFD_ALLOW_SEALING);
+
+  // becomes
+
+  memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -73,6 +73,12 @@
 
   Checks if the required mode ``e`` exists in the mode argument of ``fopen()``.
 
+- New `android-cloexec-memfd_create
+  `_ check
+
+  Checks if the required file flag ``MFD_CLOEXEC`` is present in the argument of
+  ``memfd_create()``.
+
 - New `android-cloexec-socket
   `_ check
 
Index: clang-tidy/android/CloexecMemfdCreateCheck.h
===
--- /dev/null
+++ clang-tidy/android/CloexecMemfdCreateCheck.h
@@ -0,0 +1,35 @@
+//===--- CloexecMemfdCreateCheck.h - clang-tidy-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---

[PATCH] D35372: [clang-tidy] Refactor the code and add a close-on-exec check on memfd_create() in Android module.

2017-08-10 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 110606.
yawanng marked 3 inline comments as done.

https://reviews.llvm.org/D35372

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecCheck.cpp
  clang-tidy/android/CloexecCheck.h
  clang-tidy/android/CloexecMemfdCreateCheck.cpp
  clang-tidy/android/CloexecMemfdCreateCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-memfd-create.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-memfd-create.cpp

Index: test/clang-tidy/android-cloexec-memfd-create.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-memfd-create.cpp
@@ -0,0 +1,63 @@
+// RUN: %check_clang_tidy %s android-cloexec-memfd-create %t
+
+#define MFD_ALLOW_SEALING 1
+#define __O_CLOEXEC 3
+#define MFD_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({\
+int _rc;\
+do {\
+  _rc = (exp);  \
+} while (_rc == -1);\
+  })
+#define NULL 0
+
+extern "C" int memfd_create(const char *name, unsigned int flags);
+
+void a() {
+  memfd_create(NULL, MFD_ALLOW_SEALING);
+  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: 'memfd_create' should use MFD_CLOEXEC where possible [android-cloexec-memfd-create]
+  // CHECK-FIXES: memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC)
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+  // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: 'memfd_create'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC))
+}
+
+void f() {
+  memfd_create(NULL, 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'memfd_create'
+  // CHECK-FIXES: memfd_create(NULL, 3 | MFD_CLOEXEC)
+  TEMP_FAILURE_RETRY(memfd_create(NULL, 3));
+  // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: 'memfd_create'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, 3 | MFD_CLOEXEC))
+
+  int flag = 3;
+  memfd_create(NULL, flag);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, flag));
+}
+
+namespace i {
+int memfd_create(const char *name, unsigned int flags);
+
+void d() {
+  memfd_create(NULL, MFD_ALLOW_SEALING);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+}
+
+} // namespace i
+
+void e() {
+  memfd_create(NULL, MFD_CLOEXEC);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_CLOEXEC));
+  memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC));
+}
+
+class G {
+public:
+  int memfd_create(const char *name, unsigned int flags);
+  void d() {
+memfd_create(NULL, MFD_ALLOW_SEALING);
+TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -6,6 +6,7 @@
 .. toctree::
android-cloexec-creat
android-cloexec-fopen
+   android-cloexec-memfd-create
android-cloexec-open
android-cloexec-socket
boost-use-to-string
Index: docs/clang-tidy/checks/android-cloexec-memfd-create.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-memfd-create.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-memfd-create
+
+android-cloexec-memfd-create
+
+
+``memfd_create()`` should include ``MFD_CLOEXEC`` in its type argument to avoid
+the file descriptor leakage. Without this flag, an opened sensitive file would
+remain open across a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  memfd_create(name, MFD_ALLOW_SEALING);
+
+  // becomes
+
+  memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -73,6 +73,12 @@
 
   Checks if the required mode ``e`` exists in the mode argument of ``fopen()``.
 
+- New `android-cloexec-memfd_create
+  `_ check
+
+  Checks if the required file flag ``MFD_CLOEXEC`` is present in the argument of
+  ``memfd_create()``.
+
 - New `android-cloexec-socket
   `_ check
 
Index: clang-tidy/android/CloexecMemfdCreateCheck.h
===
--- /dev/null
+++ clang-tidy/android/CloexecMemfdCreateCheck.h
@@ -0,0 +1,35 @@
+//===--- CloexecMemfdCreateCheck.h - clang-tidy-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---

[PATCH] D35743: [clang-format] Handle Structured binding declaration in C++17

2017-08-10 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 110640.
yawanng added a comment.

Show full context.


https://reviews.llvm.org/D35743

Files:
  lib/Format/TokenAnnotator.cpp
  lib/Format/UnwrappedLineParser.cpp
  lib/Format/UnwrappedLineParser.h
  unittests/Format/FormatTest.cpp

Index: unittests/Format/FormatTest.cpp
===
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -11085,6 +11085,41 @@
   EXPECT_EQ("auto c = u8'a';", format("auto c = u8'a';"));
 }
 
+TEST_F(FormatTest, StructuredBindingDeclaration) {
+  // structured-binding-declaration is a C++17 feature.
+  EXPECT_EQ("auto [x, y] = a;", format("auto[x, y] = a;"));
+  EXPECT_EQ("auto &[x, y] = a;", format("auto   &   [x, y] = a;"));
+  EXPECT_EQ("auto &&[x, y] = a;", format("auto &&   [x, y] = a;"));
+  EXPECT_EQ("auto &&[x, y] = a;", format("auto &&   [x, y] = a;"));
+  EXPECT_EQ("auto [x] = a;", format("auto[x] = a;"));
+  EXPECT_EQ("auto &[x] = a;", format("auto   &   [x] = a;"));
+  EXPECT_EQ("auto &&[x] = a;", format("auto &&   [x] = a;"));
+  EXPECT_EQ("const auto [x, y] = f();", format("const auto[x, y] = f();"));
+  EXPECT_EQ("const auto &[x, y] = f();", format("const auto  &   [x, y] = f();"));
+  EXPECT_EQ("const auto &&[x, y] = f();", format("const auto  &&   [x, y] = f();"));
+  EXPECT_EQ("auto [x, y] = A{};", format("auto[x,y] = A{};"));
+  EXPECT_EQ("auto &[x, y] = A{};", format("auto   &   [x,y] = A{};"));
+  EXPECT_EQ("auto &&[x, y] = A{};", format("auto   &&   [x,y] = A{};"));
+  EXPECT_EQ("for (const auto &&[a, b] : some_range) {\n"
+"}",
+format("for (const auto   &&   [a, b] : some_range) {\n"
+"}"));
+  EXPECT_EQ("for (const auto &[a, b] : some_range) {\n"
+"}",
+format("for (const auto   &   [a, b] : some_range) {\n"
+"}"));
+  EXPECT_EQ("for (const auto [a, b] : some_range) {\n"
+"}",
+format("for (const auto[a, b] : some_range) {\n"
+"}"));
+  EXPECT_EQ("auto [x, y](expr);", format("auto[x,y]  (expr);"));
+  EXPECT_EQ("auto &[x, y](expr);", format("auto   &   [x,y](expr);"));
+  EXPECT_EQ("auto &&[x, y](expr);", format("auto   &&   [x,y](expr);"));
+  EXPECT_EQ("auto [x, y]{expr};", format("auto[x,y] {expr};"));
+  EXPECT_EQ("auto &[x, y]{expr};", format("auto   &   [x,y]  {expr};"));
+  EXPECT_EQ("auto &&[x, y]{expr};", format("auto   &&   [x,y]  {expr};"));
+}
+
 } // end namespace
 } // end namespace format
 } // end namespace clang
Index: lib/Format/UnwrappedLineParser.h
===
--- lib/Format/UnwrappedLineParser.h
+++ lib/Format/UnwrappedLineParser.h
@@ -125,6 +125,7 @@
   bool eof() const;
   void nextToken();
   const FormatToken *getPreviousToken();
+  const FormatToken *getPrePreviousToken();
   void readToken();
 
   // Decides which comment tokens should be added to the current line and which
Index: lib/Format/UnwrappedLineParser.cpp
===
--- lib/Format/UnwrappedLineParser.cpp
+++ lib/Format/UnwrappedLineParser.cpp
@@ -1211,9 +1211,12 @@
 return false;
   }
   const FormatToken* Previous = getPreviousToken();
+  const FormatToken* PrePrevious = getPrePreviousToken();
   if (Previous &&
   (Previous->isOneOf(tok::identifier, tok::kw_operator, tok::kw_new,
- tok::kw_delete) ||
+ tok::kw_delete, tok::kw_auto) ||
+   (PrePrevious && Previous->isOneOf(tok::amp, tok::ampamp) &&
+PrePrevious->is(tok::kw_auto)) ||
Previous->closesScope() || Previous->isSimpleTypeSpecifier())) {
 nextToken();
 return false;
@@ -2306,6 +2309,12 @@
   return Line->Tokens.back().Tok;
 }
 
+const FormatToken *UnwrappedLineParser::getPrePreviousToken() {
+  if (!Line || Line->Tokens.size() < 2)
+return nullptr;
+  return std::prev(Line->Tokens.end(), 2)->Tok;
+}
+
 void UnwrappedLineParser::distributeComments(
 const SmallVectorImpl &Comments,
 const FormatToken *NextTok) {
Index: lib/Format/TokenAnnotator.cpp
===
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -330,8 +330,15 @@
 (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
  Contexts.back().InTemplateArgument);
 
+bool CppStructuredBindingDecl =
+!CppArrayTemplates && Style.isCpp() && Parent &&
+(Parent->is(tok::kw_auto) ||
+ (Parent->isOneOf(tok::amp, tok::ampamp) &&
+  Parent->getPreviousNonComment() &&
+  Parent->getPreviousNonComment()->is(tok::kw_auto)));
+
 bool StartsObjCMethodExpr =
-!CppArrayTemplates && Style.isCpp() &&
+!CppStructuredBindingDecl && !CppArrayTemplates && Style.isCpp() &&
 Contexts.back().CanBeExpression && Left->isNot(TT_Lambd

[PATCH] D35372: [clang-tidy] Refactor the code and add a close-on-exec check on memfd_create() in Android module.

2017-08-10 Thread Yan Wang via Phabricator via cfe-commits
yawanng added a comment.

https://reviews.llvm.org/rL310669 is the latest and complete version. It fixes 
an issue in windows platform.


https://reviews.llvm.org/D35372



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35370: [clang-tidy] Add a close-on-exec check on inotify_init() in Android module.

2017-08-10 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 110646.

https://reviews.llvm.org/D35370

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecInotifyInitCheck.cpp
  clang-tidy/android/CloexecInotifyInitCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-inotify-init.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-inotify-init.cpp

Index: test/clang-tidy/android-cloexec-inotify-init.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-inotify-init.cpp
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s android-cloexec-inotify-init %t
+
+extern "C" int inotify_init();
+
+void f() {
+  inotify_init();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer inotify_init() to inotify_init1() because inotify_init1() allows IN_CLOEXEC [android-cloexec-inotify-init]
+  // CHECK-FIXES: inotify_init1(IN_CLOEXEC)
+}
+
+namespace i {
+int inotify_init();
+void g() {
+  inotify_init();
+}
+} // namespace i
+
+class C {
+public:
+  int inotify_init();
+  void h() {
+inotify_init();
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -6,6 +6,7 @@
 .. toctree::
android-cloexec-creat
android-cloexec-fopen
+   android-cloexec-inotify-init
android-cloexec-memfd-create
android-cloexec-open
android-cloexec-socket
Index: docs/clang-tidy/checks/android-cloexec-inotify-init.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-inotify-init.rst
@@ -0,0 +1,17 @@
+.. title:: clang-tidy - android-cloexec-inotify-init
+
+android-cloexec-inotify-init
+
+
+The usage of ``inotify_init()`` is not recommended, it's better to use
+``inotify_init1()``.
+
+Examples:
+
+.. code-block:: c++
+
+  inotify_init();
+
+  // becomes
+
+  inotify_init1(IN_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -70,6 +70,11 @@
   ``AllowConditionalIntegerCasts`` -> ``AllowIntegerConditions``,
   ``AllowConditionalPointerCasts`` -> ``AllowPointerConditions``.
 
+- New `android-cloexec-inotify-init
+  `_ check
+
+  Detects usage of ``inotify_init()``.
+
 - New `android-cloexec-memfd_create
   `_ check
 
Index: clang-tidy/android/CloexecInotifyInitCheck.h
===
--- /dev/null
+++ clang-tidy/android/CloexecInotifyInitCheck.h
@@ -0,0 +1,35 @@
+//===--- CloexecInotifyInitCheck.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_INOTIFY_INIT_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_INOTIFY_INIT_H
+
+#include "CloexecCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+/// inotify_init() is better to be replaced by inotify_init1().
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-inotify-init.html
+class CloexecInotifyInitCheck : public CloexecCheck {
+public:
+  CloexecInotifyInitCheck(StringRef Name, ClangTidyContext *Context)
+  : CloexecCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace android
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_INOTIFY_INIT_H
Index: clang-tidy/android/CloexecInotifyInitCheck.cpp
===
--- /dev/null
+++ clang-tidy/android/CloexecInotifyInitCheck.cpp
@@ -0,0 +1,34 @@
+//===--- CloexecInotifyInitCheck.cpp - clang-tidy--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "CloexecInotifyInitCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+void CloexecInotifyInitCheck::registerMatchers(MatchFinder *Finder) 

[PATCH] D35368: [clang-tidy] Add a close-on-exec check on inotify_init1() in Android module.

2017-08-10 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 110649.

https://reviews.llvm.org/D35368

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecInotifyInit1Check.cpp
  clang-tidy/android/CloexecInotifyInit1Check.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-inotify-init1.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-inotify-init1.cpp

Index: test/clang-tidy/android-cloexec-inotify-init1.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-inotify-init1.cpp
@@ -0,0 +1,64 @@
+// RUN: %check_clang_tidy %s android-cloexec-inotify-init1 %t
+
+#define IN_NONBLOCK 1
+#define __O_CLOEXEC 3
+#define IN_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({\
+int _rc;\
+do {\
+  _rc = (exp);  \
+} while (_rc == -1);\
+  })
+
+extern "C" int inotify_init1(int flags);
+
+void a() {
+  inotify_init1(IN_NONBLOCK);
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: 'inotify_init1' should use IN_CLOEXEC where possible [android-cloexec-inotify-init1]
+  // CHECK-FIXES: inotify_init1(IN_NONBLOCK | IN_CLOEXEC)
+  TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK));
+  // CHECK-MESSAGES: :[[@LINE-1]]:47: warning: 'inotify_init1'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK | IN_CLOEXEC))
+}
+
+void f() {
+  inotify_init1(0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'inotify_init1'
+  // CHECK-FIXES: inotify_init1(IN_CLOEXEC)
+  TEMP_FAILURE_RETRY(inotify_init1(0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'inotify_init1'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(inotify_init1(IN_CLOEXEC))
+
+  int flag = 1;
+  inotify_init1(flag);
+  TEMP_FAILURE_RETRY(inotify_init1(flag));
+}
+
+namespace i {
+int inotify_init1(int flags);
+
+void d() {
+  inotify_init1(IN_NONBLOCK);
+  TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK));
+}
+
+} // namespace i
+
+void e() {
+  inotify_init1(IN_CLOEXEC);
+  TEMP_FAILURE_RETRY(inotify_init1(IN_CLOEXEC));
+  inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+  TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK | IN_CLOEXEC));
+}
+
+class G {
+public:
+  int inotify_init1(int flags);
+  void d() {
+inotify_init1(IN_CLOEXEC);
+TEMP_FAILURE_RETRY(inotify_init1(IN_CLOEXEC));
+inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK | IN_CLOEXEC));
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -6,6 +6,7 @@
 .. toctree::
android-cloexec-creat
android-cloexec-fopen
+   android-cloexec-inotify-init1
android-cloexec-memfd-create
android-cloexec-open
android-cloexec-socket
Index: docs/clang-tidy/checks/android-cloexec-inotify-init1.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-inotify-init1.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-inotify-init1
+
+android-cloexec-inotify-init1
+=
+
+``inotify_init1()`` should include ``IN_CLOEXEC`` in its type argument to avoid the
+file descriptor leakage. Without this flag, an opened sensitive file would
+remain open across a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  inotify_init1(IN_NONBLOCK);
+
+  // becomes
+
+  inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -82,6 +82,12 @@
   Finds cases where integer division in a floating point context is likely to
   cause unintended loss of precision.
 
+- New `android-cloexec-inotify-init1
+  `_ check
+
+  Checks if the required file flag ``IN_CLOEXEC`` is present in the argument of
+  ``inotify_init1()``.
+
 - New `readability-static-accessed-through-instance
   `_ check
 
Index: clang-tidy/android/CloexecInotifyInit1Check.h
===
--- /dev/null
+++ clang-tidy/android/CloexecInotifyInit1Check.h
@@ -0,0 +1,35 @@
+//===--- CloexecInotifyInit1Check.h - clang-tidy-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_INOTIFY_INIT1_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_I

[PATCH] D35367: [clang-tidy] Add a close-on-exec check on epoll_create() in Android module.

2017-08-10 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 110650.

https://reviews.llvm.org/D35367

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecEpollCreateCheck.cpp
  clang-tidy/android/CloexecEpollCreateCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-epoll-create.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-epoll-create.cpp

Index: test/clang-tidy/android-cloexec-epoll-create.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-epoll-create.cpp
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s android-cloexec-epoll-create %t
+
+extern "C" int epoll_create(int size);
+
+void f() {
+  epoll_create(0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer epoll_create() to epoll_create1() because epoll_create1() allows EPOLL_CLOEXEC [android-cloexec-epoll-create]
+  // CHECK-FIXES: epoll_create1(EPOLL_CLOEXEC)
+}
+
+namespace i {
+int epoll_create(int size);
+void g() {
+  epoll_create(0);
+}
+} // namespace i
+
+class C {
+public:
+  int epoll_create(int size);
+  void h() {
+epoll_create(0);
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -5,6 +5,7 @@
 
 .. toctree::
android-cloexec-creat
+   android-cloexec-epoll-create
android-cloexec-fopen
android-cloexec-memfd-create
android-cloexec-open
Index: docs/clang-tidy/checks/android-cloexec-epoll-create.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-epoll-create.rst
@@ -0,0 +1,17 @@
+.. title:: clang-tidy - android-cloexec-epoll-create
+
+android-cloexec-epoll-create
+
+
+The usage of ``epoll_create()`` is not recommended, it's better to use
+``epoll_create1()``, which allows close-on-exec.
+
+Examples:
+
+.. code-block:: c++
+
+  epoll_create(size);
+
+  // becomes
+
+  epoll_create1(EPOLL_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -70,6 +70,11 @@
   ``AllowConditionalIntegerCasts`` -> ``AllowIntegerConditions``,
   ``AllowConditionalPointerCasts`` -> ``AllowPointerConditions``.
 
+- New `android-cloexec-epoll-create
+  `_ check
+
+  Detects usage of ``epoll_create()``.
+
 - New `android-cloexec-memfd_create
   `_ check
 
Index: clang-tidy/android/CloexecEpollCreateCheck.h
===
--- /dev/null
+++ clang-tidy/android/CloexecEpollCreateCheck.h
@@ -0,0 +1,35 @@
+//===--- CloexecEpollCreateCheck.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_EPOLL_CREATE_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_EPOLL_CREATE_H
+
+#include "CloexecCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+/// epoll_create() is better to be replaced by epoll_create1().
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-epoll-create.html
+class CloexecEpollCreateCheck : public CloexecCheck {
+public:
+  CloexecEpollCreateCheck(StringRef Name, ClangTidyContext *Context)
+  : CloexecCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace android
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_EPOLL_CREATE_H
Index: clang-tidy/android/CloexecEpollCreateCheck.cpp
===
--- /dev/null
+++ clang-tidy/android/CloexecEpollCreateCheck.cpp
@@ -0,0 +1,36 @@
+//===--- CloexecEpollCreateCheck.cpp - clang-tidy--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "CloexecEpollCreateCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+void CloexecEpollCreateCh

[PATCH] D35365: [clang-tidy] Add a close-on-exec check on epoll_create1() in Android module.

2017-08-10 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 110652.

https://reviews.llvm.org/D35365

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecEpollCreate1Check.cpp
  clang-tidy/android/CloexecEpollCreate1Check.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-epoll-create1.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-epoll-create1.cpp

Index: test/clang-tidy/android-cloexec-epoll-create1.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-epoll-create1.cpp
@@ -0,0 +1,59 @@
+// RUN: %check_clang_tidy %s android-cloexec-epoll-create1 %t
+
+#define __O_CLOEXEC 3
+#define EPOLL_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({\
+int _rc;\
+do {\
+  _rc = (exp);  \
+} while (_rc == -1);\
+  })
+
+extern "C" int epoll_create1(int flags);
+
+void a() {
+  epoll_create1(0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'epoll_create1' should use EPOLL_CLOEXEC where possible [android-cloexec-epoll-create1]
+  // CHECK-FIXES: epoll_create1(EPOLL_CLOEXEC)
+  TEMP_FAILURE_RETRY(epoll_create1(0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'epoll_create1'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC))
+}
+
+void f() {
+  epoll_create1(3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'epoll_create1'
+  // CHECK-FIXES: epoll_create1(EPOLL_CLOEXEC)
+  TEMP_FAILURE_RETRY(epoll_create1(3));
+  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'epoll_create1'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC))
+
+  int flag = 0;
+  epoll_create1(EPOLL_CLOEXEC);
+  TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
+}
+
+namespace i {
+int epoll_create1(int flags);
+
+void d() {
+  epoll_create1(0);
+  TEMP_FAILURE_RETRY(epoll_create1(0));
+}
+
+} // namespace i
+
+void e() {
+  epoll_create1(EPOLL_CLOEXEC);
+  TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
+}
+
+class G {
+public:
+  int epoll_create1(int flags);
+  void d() {
+epoll_create1(EPOLL_CLOEXEC);
+TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -5,6 +5,7 @@
 
 .. toctree::
android-cloexec-creat
+   android-cloexec-epoll-create1
android-cloexec-fopen
android-cloexec-memfd-create
android-cloexec-open
Index: docs/clang-tidy/checks/android-cloexec-epoll-create1.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-epoll-create1.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-epoll-create1
+
+android-cloexec-epoll-create1
+=
+
+``epoll_create1()`` should include ``EPOLL_CLOEXEC`` in its type argument to
+avoid the file descriptor leakage. Without this flag, an opened sensitive file
+would remain open across a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  epoll_create1(0);
+
+  // becomes
+
+  epoll_create1(EPOLL_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -70,6 +70,12 @@
   ``AllowConditionalIntegerCasts`` -> ``AllowIntegerConditions``,
   ``AllowConditionalPointerCasts`` -> ``AllowPointerConditions``.
 
+- New `android-cloexec-epoll-create1
+  `_ check
+
+  Checks if the required file flag ``EPOLL_CLOEXEC`` is present in the argument of
+  ``epoll_create1()``.
+
 - New `android-cloexec-memfd_create
   `_ check
 
Index: clang-tidy/android/CloexecEpollCreate1Check.h
===
--- /dev/null
+++ clang-tidy/android/CloexecEpollCreate1Check.h
@@ -0,0 +1,35 @@
+//===--- CloexecEpollCreate1Check.h - clang-tidy-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_EPOLL_CREATE1_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_EPOLL_CREATE1_H
+
+#include "CloexecCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+/// Finds code that uses epoll_create1() without using the EPOLL_CLOEXEC flag.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-epoll-cre

[PATCH] D35364: [clang-tidy] Add a close-on-exec check on dup() in Android module.

2017-08-10 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 110654.

https://reviews.llvm.org/D35364

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecCheck.cpp
  clang-tidy/android/CloexecCheck.h
  clang-tidy/android/CloexecDupCheck.cpp
  clang-tidy/android/CloexecDupCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-dup.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-dup.cpp

Index: test/clang-tidy/android-cloexec-dup.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-dup.cpp
@@ -0,0 +1,31 @@
+// RUN: %check_clang_tidy %s android-cloexec-dup %t
+
+extern "C" int dup(int oldfd);
+void f() {
+  dup(1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer fcntl() to dup() because fcntl() allows F_DUPFD_CLOEXEC [android-cloexec-dup]
+  // CHECK-FIXES: fcntl(1, F_DUPFD_CLOEXEC)
+  int oldfd = 0;
+  dup(oldfd);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer
+  // CHECK-FIXES: fcntl(oldfd, F_DUPFD_CLOEXEC)
+}
+
+namespace i {
+int dup(int oldfd);
+void g() {
+  dup(0);
+  int oldfd = 1;
+  dup(oldfd);
+}
+} // namespace i
+
+class C {
+public:
+  int dup(int oldfd);
+  void h() {
+dup(0);
+int oldfd = 1;
+dup(oldfd);
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -5,6 +5,7 @@
 
 .. toctree::
android-cloexec-creat
+   android-cloexec-dup
android-cloexec-fopen
android-cloexec-memfd-create
android-cloexec-open
Index: docs/clang-tidy/checks/android-cloexec-dup.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-dup.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-dup
+
+android-cloexec-dup
+===
+
+The usage of ``dup()`` is not recommended, it's better to use ``fcntl()``,
+which can set the close-on-exec flag. Otherwise, an opened sensitive file would
+remain open across a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  int fd = dup(oldfd);
+
+  // becomes
+
+  int fd = fcntl(oldfd, F_DUPFD_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -70,6 +70,11 @@
   ``AllowConditionalIntegerCasts`` -> ``AllowIntegerConditions``,
   ``AllowConditionalPointerCasts`` -> ``AllowPointerConditions``.
 
+- New `android-cloexec-dup
+  `_ check
+
+  Detects usage of ``dup()``.
+
 - New `android-cloexec-memfd_create
   `_ check
 
Index: clang-tidy/android/CloexecDupCheck.h
===
--- /dev/null
+++ clang-tidy/android/CloexecDupCheck.h
@@ -0,0 +1,36 @@
+//===--- CloexecDupCheck.h - clang-tidy-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_DUP_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_DUP_H
+
+#include "CloexecCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+/// dup() is better to be replaced by fcntl(), which has close-on-exec flag.
+/// Find the usage of dup() and redirect user to use fcntl().
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-dup.html
+class CloexecDupCheck : public CloexecCheck {
+public:
+  CloexecDupCheck(StringRef Name, ClangTidyContext *Context)
+  : CloexecCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace android
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_DUP_H
Index: clang-tidy/android/CloexecDupCheck.cpp
===
--- /dev/null
+++ clang-tidy/android/CloexecDupCheck.cpp
@@ -0,0 +1,38 @@
+//===--- CloexecDupCheck.cpp - clang-tidy--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "CloexecDupCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatche

[PATCH] D35363: [clang-tidy] Add a close-on-exec check on accept4() in Android module.

2017-08-10 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 110655.

https://reviews.llvm.org/D35363

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecAccept4Check.cpp
  clang-tidy/android/CloexecAccept4Check.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-accept4.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-accept4.cpp

Index: test/clang-tidy/android-cloexec-accept4.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-accept4.cpp
@@ -0,0 +1,66 @@
+// RUN: %check_clang_tidy %s android-cloexec-accept4 %t
+
+typedef int socklen_t;
+struct sockaddr {};
+
+#define SOCK_NONBLOCK 1
+#define __O_CLOEXEC 3
+#define SOCK_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({\
+int _rc;\
+do {\
+  _rc = (exp);  \
+} while (_rc == -1);\
+  })
+#define NULL 0
+
+extern "C" int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
+
+void a() {
+  accept4(0, NULL, NULL, SOCK_NONBLOCK);
+  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: 'accept4' should use SOCK_CLOEXEC where possible [android-cloexec-accept4]
+  // CHECK-FIXES: accept4(0, NULL, NULL, SOCK_NONBLOCK | SOCK_CLOEXEC);
+  TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, SOCK_NONBLOCK));
+  // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: 'accept4'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, SOCK_NONBLOCK | SOCK_CLOEXEC))
+}
+
+void f() {
+  accept4(0, NULL, NULL, 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'accept4'
+  // CHECK-FIXES: accept4(0, NULL, NULL, 3 | SOCK_CLOEXEC)
+  TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, 3));
+  // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: 'accept4'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, 3 | SOCK_CLOEXEC))
+
+  int flag = SOCK_NONBLOCK;
+  accept4(0, NULL, NULL, flag);
+  TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, flag));
+}
+
+namespace i {
+int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
+
+void d() {
+  accept4(0, NULL, NULL, SOCK_NONBLOCK);
+  TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, SOCK_NONBLOCK));
+}
+
+} // namespace i
+
+void e() {
+  accept4(0, NULL, NULL, SOCK_CLOEXEC);
+  TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, SOCK_CLOEXEC));
+  accept4(0, NULL, NULL, SOCK_NONBLOCK | SOCK_CLOEXEC);
+  TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, SOCK_NONBLOCK | SOCK_CLOEXEC));
+}
+
+class G {
+public:
+  int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
+  void d() {
+accept4(0, NULL, NULL, SOCK_NONBLOCK);
+TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, SOCK_NONBLOCK));
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -4,6 +4,7 @@
 =
 
 .. toctree::
+   android-cloexec-accept4
android-cloexec-creat
android-cloexec-dup
android-cloexec-fopen
Index: docs/clang-tidy/checks/android-cloexec-accept4.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-accept4.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-accept4
+
+android-cloexec-accept4
+===
+
+``accept4()`` should include ``SOCK_CLOEXEC`` in its type argument to avoid the
+file descriptor leakage. Without this flag, an opened sensitive file would
+remain open across a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  accept4(sockfd, addr, addrlen, SOCK_NONBLOCK);
+
+  // becomes
+
+  accept4(sockfd, addr, addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -70,6 +70,12 @@
   ``AllowConditionalIntegerCasts`` -> ``AllowIntegerConditions``,
   ``AllowConditionalPointerCasts`` -> ``AllowPointerConditions``.
 
+- New `android-cloexec-accept4
+  `_ check
+
+  Checks if the required file flag ``SOCK_CLOEXEC`` is present in the argument of
+  ``accept4()``.
+
 - New `android-cloexec-dup
   `_ check
 
Index: clang-tidy/android/CloexecAccept4Check.h
===
--- /dev/null
+++ clang-tidy/android/CloexecAccept4Check.h
@@ -0,0 +1,35 @@
+//===--- CloexecAccept4Check.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--

[PATCH] D35362: [clang-tidy] Add a close-on-exec check on accept() in Android module.

2017-08-10 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 110659.

https://reviews.llvm.org/D35362

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecAcceptCheck.cpp
  clang-tidy/android/CloexecAcceptCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-accept.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-accept.cpp

Index: test/clang-tidy/android-cloexec-accept.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-accept.cpp
@@ -0,0 +1,28 @@
+// RUN: %check_clang_tidy %s android-cloexec-accept %t
+
+struct sockaddr {};
+typedef int socklen_t;
+#define NULL 0
+
+extern "C" int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
+
+void f() {
+  accept(0, NULL, NULL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer accept4() to accept() because accept4() allows SOCK_CLOEXEC [android-cloexec-accept]
+  // CHECK-FIXES: accept4(0, NULL, NULL, SOCK_CLOEXEC)
+}
+
+namespace i {
+int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
+void g() {
+  accept(0, NULL, NULL);
+}
+} // namespace i
+
+class C {
+public:
+  int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
+  void h() {
+accept(0, NULL, NULL);
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -4,6 +4,7 @@
 =
 
 .. toctree::
+   android-cloexec-accept
android-cloexec-creat
android-cloexec-dup
android-cloexec-fopen
Index: docs/clang-tidy/checks/android-cloexec-accept.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-accept.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-accept
+
+android-cloexec-accept
+==
+
+The usage of ``accept()`` is not recommended, it's better to use ``accept4()``.
+Without this flag, an opened sensitive file descriptor would remain open across
+a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  accept(sockfd, addr, addrlen);
+
+  // becomes
+
+  accept4(sockfd, addr, addrlen, SOCK_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -70,6 +70,11 @@
   ``AllowConditionalIntegerCasts`` -> ``AllowIntegerConditions``,
   ``AllowConditionalPointerCasts`` -> ``AllowPointerConditions``.
 
+- New `android-cloexec-accept
+  `_ check
+
+  Detects usage of ``accept()``.
+
 - New `android-cloexec-dup
   `_ check
 
Index: clang-tidy/android/CloexecAcceptCheck.h
===
--- /dev/null
+++ clang-tidy/android/CloexecAcceptCheck.h
@@ -0,0 +1,35 @@
+//===--- CloexecAcceptCheck.h - clang-tidy---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_ACCEPT_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_ACCEPT_H
+
+#include "CloexecCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+/// accept() is better to be replaced by accept4().
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-accept.html
+class CloexecAcceptCheck : public CloexecCheck {
+public:
+  CloexecAcceptCheck(StringRef Name, ClangTidyContext *Context)
+  : CloexecCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace android
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_ACCEPT_H
Index: clang-tidy/android/CloexecAcceptCheck.cpp
===
--- /dev/null
+++ clang-tidy/android/CloexecAcceptCheck.cpp
@@ -0,0 +1,47 @@
+//===--- CloexecAcceptCheck.cpp - clang-tidy---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "CloexecAcceptCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::a

[PATCH] D35370: [clang-tidy] Add a close-on-exec check on inotify_init() in Android module.

2017-08-11 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 110749.
yawanng marked an inline comment as done.

https://reviews.llvm.org/D35370

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecInotifyInitCheck.cpp
  clang-tidy/android/CloexecInotifyInitCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-inotify-init.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-inotify-init.cpp

Index: test/clang-tidy/android-cloexec-inotify-init.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-inotify-init.cpp
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s android-cloexec-inotify-init %t
+
+extern "C" int inotify_init();
+
+void f() {
+  inotify_init();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer inotify_init() to inotify_init1() because inotify_init1() allows IN_CLOEXEC [android-cloexec-inotify-init]
+  // CHECK-FIXES: inotify_init1(IN_CLOEXEC);
+}
+
+namespace i {
+int inotify_init();
+void g() {
+  inotify_init();
+}
+} // namespace i
+
+class C {
+public:
+  int inotify_init();
+  void h() {
+inotify_init();
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -6,6 +6,7 @@
 .. toctree::
android-cloexec-creat
android-cloexec-fopen
+   android-cloexec-inotify-init
android-cloexec-memfd-create
android-cloexec-open
android-cloexec-socket
Index: docs/clang-tidy/checks/android-cloexec-inotify-init.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-inotify-init.rst
@@ -0,0 +1,17 @@
+.. title:: clang-tidy - android-cloexec-inotify-init
+
+android-cloexec-inotify-init
+
+
+The usage of ``inotify_init()`` is not recommended, it's better to use
+``inotify_init1()``.
+
+Examples:
+
+.. code-block:: c++
+
+  inotify_init();
+
+  // becomes
+
+  inotify_init1(IN_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -70,6 +70,11 @@
   ``AllowConditionalIntegerCasts`` -> ``AllowIntegerConditions``,
   ``AllowConditionalPointerCasts`` -> ``AllowPointerConditions``.
 
+- New `android-cloexec-inotify-init
+  `_ check
+
+  Detects usage of ``inotify_init()``.
+
 - New `android-cloexec-memfd_create
   `_ check
 
Index: clang-tidy/android/CloexecInotifyInitCheck.h
===
--- /dev/null
+++ clang-tidy/android/CloexecInotifyInitCheck.h
@@ -0,0 +1,35 @@
+//===--- CloexecInotifyInitCheck.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_INOTIFY_INIT_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_INOTIFY_INIT_H
+
+#include "CloexecCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+/// inotify_init() is better to be replaced by inotify_init1().
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-inotify-init.html
+class CloexecInotifyInitCheck : public CloexecCheck {
+public:
+  CloexecInotifyInitCheck(StringRef Name, ClangTidyContext *Context)
+  : CloexecCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace android
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_INOTIFY_INIT_H
Index: clang-tidy/android/CloexecInotifyInitCheck.cpp
===
--- /dev/null
+++ clang-tidy/android/CloexecInotifyInitCheck.cpp
@@ -0,0 +1,34 @@
+//===--- CloexecInotifyInitCheck.cpp - clang-tidy--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "CloexecInotifyInitCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+void CloexecInotifyInitCh

[PATCH] D35367: [clang-tidy] Add a close-on-exec check on epoll_create() in Android module.

2017-08-11 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 110751.

https://reviews.llvm.org/D35367

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecEpollCreateCheck.cpp
  clang-tidy/android/CloexecEpollCreateCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-epoll-create.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-epoll-create.cpp

Index: test/clang-tidy/android-cloexec-epoll-create.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-epoll-create.cpp
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s android-cloexec-epoll-create %t
+
+extern "C" int epoll_create(int size);
+
+void f() {
+  epoll_create(0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer epoll_create() to epoll_create1() because epoll_create1() allows EPOLL_CLOEXEC [android-cloexec-epoll-create]
+  // CHECK-FIXES: epoll_create1(EPOLL_CLOEXEC);
+}
+
+namespace i {
+int epoll_create(int size);
+void g() {
+  epoll_create(0);
+}
+} // namespace i
+
+class C {
+public:
+  int epoll_create(int size);
+  void h() {
+epoll_create(0);
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -5,6 +5,7 @@
 
 .. toctree::
android-cloexec-creat
+   android-cloexec-epoll-create
android-cloexec-fopen
android-cloexec-memfd-create
android-cloexec-open
Index: docs/clang-tidy/checks/android-cloexec-epoll-create.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-epoll-create.rst
@@ -0,0 +1,17 @@
+.. title:: clang-tidy - android-cloexec-epoll-create
+
+android-cloexec-epoll-create
+
+
+The usage of ``epoll_create()`` is not recommended, it's better to use
+``epoll_create1()``, which allows close-on-exec.
+
+Examples:
+
+.. code-block:: c++
+
+  epoll_create(size);
+
+  // becomes
+
+  epoll_create1(EPOLL_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -70,6 +70,11 @@
   ``AllowConditionalIntegerCasts`` -> ``AllowIntegerConditions``,
   ``AllowConditionalPointerCasts`` -> ``AllowPointerConditions``.
 
+- New `android-cloexec-epoll-create
+  `_ check
+
+  Detects usage of ``epoll_create()``.
+
 - New `android-cloexec-memfd_create
   `_ check
 
Index: clang-tidy/android/CloexecEpollCreateCheck.h
===
--- /dev/null
+++ clang-tidy/android/CloexecEpollCreateCheck.h
@@ -0,0 +1,35 @@
+//===--- CloexecEpollCreateCheck.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_EPOLL_CREATE_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_EPOLL_CREATE_H
+
+#include "CloexecCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+/// epoll_create() is better to be replaced by epoll_create1().
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-epoll-create.html
+class CloexecEpollCreateCheck : public CloexecCheck {
+public:
+  CloexecEpollCreateCheck(StringRef Name, ClangTidyContext *Context)
+  : CloexecCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace android
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_EPOLL_CREATE_H
Index: clang-tidy/android/CloexecEpollCreateCheck.cpp
===
--- /dev/null
+++ clang-tidy/android/CloexecEpollCreateCheck.cpp
@@ -0,0 +1,36 @@
+//===--- CloexecEpollCreateCheck.cpp - clang-tidy--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "CloexecEpollCreateCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+void CloexecEpollCreateC

[PATCH] D35368: [clang-tidy] Add a close-on-exec check on inotify_init1() in Android module.

2017-08-11 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 110750.
yawanng marked 2 inline comments as done.

https://reviews.llvm.org/D35368

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecInotifyInit1Check.cpp
  clang-tidy/android/CloexecInotifyInit1Check.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-inotify-init1.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-inotify-init1.cpp

Index: test/clang-tidy/android-cloexec-inotify-init1.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-inotify-init1.cpp
@@ -0,0 +1,64 @@
+// RUN: %check_clang_tidy %s android-cloexec-inotify-init1 %t
+
+#define IN_NONBLOCK 1
+#define __O_CLOEXEC 3
+#define IN_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({\
+int _rc;\
+do {\
+  _rc = (exp);  \
+} while (_rc == -1);\
+  })
+
+extern "C" int inotify_init1(int flags);
+
+void a() {
+  inotify_init1(IN_NONBLOCK);
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: 'inotify_init1' should use IN_CLOEXEC where possible [android-cloexec-inotify-init1]
+  // CHECK-FIXES: inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+  TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK));
+  // CHECK-MESSAGES: :[[@LINE-1]]:47: warning: 'inotify_init1'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK | IN_CLOEXEC));
+}
+
+void f() {
+  inotify_init1(0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'inotify_init1'
+  // CHECK-FIXES: inotify_init1(IN_CLOEXEC);
+  TEMP_FAILURE_RETRY(inotify_init1(0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'inotify_init1'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(inotify_init1(IN_CLOEXEC));
+
+  int flag = 1;
+  inotify_init1(flag);
+  TEMP_FAILURE_RETRY(inotify_init1(flag));
+}
+
+namespace i {
+int inotify_init1(int flags);
+
+void d() {
+  inotify_init1(IN_NONBLOCK);
+  TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK));
+}
+
+} // namespace i
+
+void e() {
+  inotify_init1(IN_CLOEXEC);
+  TEMP_FAILURE_RETRY(inotify_init1(IN_CLOEXEC));
+  inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+  TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK | IN_CLOEXEC));
+}
+
+class G {
+public:
+  int inotify_init1(int flags);
+  void d() {
+inotify_init1(IN_CLOEXEC);
+TEMP_FAILURE_RETRY(inotify_init1(IN_CLOEXEC));
+inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK | IN_CLOEXEC));
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -6,6 +6,7 @@
 .. toctree::
android-cloexec-creat
android-cloexec-fopen
+   android-cloexec-inotify-init1
android-cloexec-memfd-create
android-cloexec-open
android-cloexec-socket
Index: docs/clang-tidy/checks/android-cloexec-inotify-init1.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-inotify-init1.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-inotify-init1
+
+android-cloexec-inotify-init1
+=
+
+``inotify_init1()`` should include ``IN_CLOEXEC`` in its type argument to avoid the
+file descriptor leakage. Without this flag, an opened sensitive file would
+remain open across a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  inotify_init1(IN_NONBLOCK);
+
+  // becomes
+
+  inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -82,6 +82,12 @@
   Finds cases where integer division in a floating point context is likely to
   cause unintended loss of precision.
 
+- New `android-cloexec-inotify-init1
+  `_ check
+
+  Checks if the required file flag ``IN_CLOEXEC`` is present in the argument of
+  ``inotify_init1()``.
+
 - New `readability-static-accessed-through-instance
   `_ check
 
Index: clang-tidy/android/CloexecInotifyInit1Check.h
===
--- /dev/null
+++ clang-tidy/android/CloexecInotifyInit1Check.h
@@ -0,0 +1,35 @@
+//===--- CloexecInotifyInit1Check.h - clang-tidy-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_INOTIFY_INIT1_H
+#define LLVM_

[PATCH] D35365: [clang-tidy] Add a close-on-exec check on epoll_create1() in Android module.

2017-08-11 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 110752.

https://reviews.llvm.org/D35365

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecEpollCreate1Check.cpp
  clang-tidy/android/CloexecEpollCreate1Check.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-epoll-create1.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-epoll-create1.cpp

Index: test/clang-tidy/android-cloexec-epoll-create1.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-epoll-create1.cpp
@@ -0,0 +1,59 @@
+// RUN: %check_clang_tidy %s android-cloexec-epoll-create1 %t
+
+#define __O_CLOEXEC 3
+#define EPOLL_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({\
+int _rc;\
+do {\
+  _rc = (exp);  \
+} while (_rc == -1);\
+  })
+
+extern "C" int epoll_create1(int flags);
+
+void a() {
+  epoll_create1(0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'epoll_create1' should use EPOLL_CLOEXEC where possible [android-cloexec-epoll-create1]
+  // CHECK-FIXES: epoll_create1(EPOLL_CLOEXEC);
+  TEMP_FAILURE_RETRY(epoll_create1(0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'epoll_create1'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
+}
+
+void f() {
+  epoll_create1(3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'epoll_create1'
+  // CHECK-FIXES: epoll_create1(EPOLL_CLOEXEC);
+  TEMP_FAILURE_RETRY(epoll_create1(3));
+  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'epoll_create1'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
+
+  int flag = 0;
+  epoll_create1(EPOLL_CLOEXEC);
+  TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
+}
+
+namespace i {
+int epoll_create1(int flags);
+
+void d() {
+  epoll_create1(0);
+  TEMP_FAILURE_RETRY(epoll_create1(0));
+}
+
+} // namespace i
+
+void e() {
+  epoll_create1(EPOLL_CLOEXEC);
+  TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
+}
+
+class G {
+public:
+  int epoll_create1(int flags);
+  void d() {
+epoll_create1(EPOLL_CLOEXEC);
+TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -5,6 +5,7 @@
 
 .. toctree::
android-cloexec-creat
+   android-cloexec-epoll-create1
android-cloexec-fopen
android-cloexec-memfd-create
android-cloexec-open
Index: docs/clang-tidy/checks/android-cloexec-epoll-create1.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-epoll-create1.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-epoll-create1
+
+android-cloexec-epoll-create1
+=
+
+``epoll_create1()`` should include ``EPOLL_CLOEXEC`` in its type argument to
+avoid the file descriptor leakage. Without this flag, an opened sensitive file
+would remain open across a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  epoll_create1(0);
+
+  // becomes
+
+  epoll_create1(EPOLL_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -70,6 +70,12 @@
   ``AllowConditionalIntegerCasts`` -> ``AllowIntegerConditions``,
   ``AllowConditionalPointerCasts`` -> ``AllowPointerConditions``.
 
+- New `android-cloexec-epoll-create1
+  `_ check
+
+  Checks if the required file flag ``EPOLL_CLOEXEC`` is present in the argument of
+  ``epoll_create1()``.
+
 - New `android-cloexec-memfd_create
   `_ check
 
Index: clang-tidy/android/CloexecEpollCreate1Check.h
===
--- /dev/null
+++ clang-tidy/android/CloexecEpollCreate1Check.h
@@ -0,0 +1,35 @@
+//===--- CloexecEpollCreate1Check.h - clang-tidy-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_EPOLL_CREATE1_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_EPOLL_CREATE1_H
+
+#include "CloexecCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+/// Finds code that uses epoll_create1() without using the EPOLL_CLOEXEC flag.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-epoll

[PATCH] D35364: [clang-tidy] Add a close-on-exec check on dup() in Android module.

2017-08-11 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 110753.
yawanng marked an inline comment as done.

https://reviews.llvm.org/D35364

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecCheck.cpp
  clang-tidy/android/CloexecCheck.h
  clang-tidy/android/CloexecDupCheck.cpp
  clang-tidy/android/CloexecDupCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-dup.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-dup.cpp

Index: test/clang-tidy/android-cloexec-dup.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-dup.cpp
@@ -0,0 +1,31 @@
+// RUN: %check_clang_tidy %s android-cloexec-dup %t
+
+extern "C" int dup(int oldfd);
+void f() {
+  dup(1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer fcntl() to dup() because fcntl() allows F_DUPFD_CLOEXEC [android-cloexec-dup]
+  // CHECK-FIXES: fcntl(1, F_DUPFD_CLOEXEC);
+  int oldfd = 0;
+  dup(oldfd);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer
+  // CHECK-FIXES: fcntl(oldfd, F_DUPFD_CLOEXEC);
+}
+
+namespace i {
+int dup(int oldfd);
+void g() {
+  dup(0);
+  int oldfd = 1;
+  dup(oldfd);
+}
+} // namespace i
+
+class C {
+public:
+  int dup(int oldfd);
+  void h() {
+dup(0);
+int oldfd = 1;
+dup(oldfd);
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -5,6 +5,7 @@
 
 .. toctree::
android-cloexec-creat
+   android-cloexec-dup
android-cloexec-fopen
android-cloexec-memfd-create
android-cloexec-open
Index: docs/clang-tidy/checks/android-cloexec-dup.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-dup.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-dup
+
+android-cloexec-dup
+===
+
+The usage of ``dup()`` is not recommended, it's better to use ``fcntl()``,
+which can set the close-on-exec flag. Otherwise, an opened sensitive file would
+remain open across a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  int fd = dup(oldfd);
+
+  // becomes
+
+  int fd = fcntl(oldfd, F_DUPFD_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -70,6 +70,11 @@
   ``AllowConditionalIntegerCasts`` -> ``AllowIntegerConditions``,
   ``AllowConditionalPointerCasts`` -> ``AllowPointerConditions``.
 
+- New `android-cloexec-dup
+  `_ check
+
+  Detects usage of ``dup()``.
+
 - New `android-cloexec-memfd_create
   `_ check
 
Index: clang-tidy/android/CloexecDupCheck.h
===
--- /dev/null
+++ clang-tidy/android/CloexecDupCheck.h
@@ -0,0 +1,36 @@
+//===--- CloexecDupCheck.h - clang-tidy-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_DUP_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_DUP_H
+
+#include "CloexecCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+/// dup() is better to be replaced by fcntl(), which has close-on-exec flag.
+/// Find the usage of dup() and redirect user to use fcntl().
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-dup.html
+class CloexecDupCheck : public CloexecCheck {
+public:
+  CloexecDupCheck(StringRef Name, ClangTidyContext *Context)
+  : CloexecCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace android
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_DUP_H
Index: clang-tidy/android/CloexecDupCheck.cpp
===
--- /dev/null
+++ clang-tidy/android/CloexecDupCheck.cpp
@@ -0,0 +1,38 @@
+//===--- CloexecDupCheck.cpp - clang-tidy--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "CloexecDupCheck.h"
+#include "clang/

[PATCH] D35364: [clang-tidy] Add a close-on-exec check on dup() in Android module.

2017-08-11 Thread Yan Wang via Phabricator via cfe-commits
yawanng added inline comments.



Comment at: clang-tidy/android/CloexecCheck.h:91
+  /// Helper function to get the spelling of a particular argument.
+  StringRef getSpellingArg(const ast_matchers::MatchFinder::MatchResult 
&Result,
+   int N) const;

hokein wrote:
> This method seems only be used in one check. Maybe move it to the 
> implementation of that specific check? And you can make the  private members 
> `FuncBindingStr` and `FuncDeclBindingStr` to protected member.
Actually, this  method will be used in three checks. 


https://reviews.llvm.org/D35364



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35363: [clang-tidy] Add a close-on-exec check on accept4() in Android module.

2017-08-11 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 110755.

https://reviews.llvm.org/D35363

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecAccept4Check.cpp
  clang-tidy/android/CloexecAccept4Check.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-accept4.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-accept4.cpp

Index: test/clang-tidy/android-cloexec-accept4.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-accept4.cpp
@@ -0,0 +1,66 @@
+// RUN: %check_clang_tidy %s android-cloexec-accept4 %t
+
+typedef int socklen_t;
+struct sockaddr {};
+
+#define SOCK_NONBLOCK 1
+#define __O_CLOEXEC 3
+#define SOCK_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({\
+int _rc;\
+do {\
+  _rc = (exp);  \
+} while (_rc == -1);\
+  })
+#define NULL 0
+
+extern "C" int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
+
+void a() {
+  accept4(0, NULL, NULL, SOCK_NONBLOCK);
+  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: 'accept4' should use SOCK_CLOEXEC where possible [android-cloexec-accept4]
+  // CHECK-FIXES: accept4(0, NULL, NULL, SOCK_NONBLOCK | SOCK_CLOEXEC);
+  TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, SOCK_NONBLOCK));
+  // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: 'accept4'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, SOCK_NONBLOCK | SOCK_CLOEXEC));
+}
+
+void f() {
+  accept4(0, NULL, NULL, 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'accept4'
+  // CHECK-FIXES: accept4(0, NULL, NULL, 3 | SOCK_CLOEXEC);
+  TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, 3));
+  // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: 'accept4'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, 3 | SOCK_CLOEXEC));
+
+  int flag = SOCK_NONBLOCK;
+  accept4(0, NULL, NULL, flag);
+  TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, flag));
+}
+
+namespace i {
+int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
+
+void d() {
+  accept4(0, NULL, NULL, SOCK_NONBLOCK);
+  TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, SOCK_NONBLOCK));
+}
+
+} // namespace i
+
+void e() {
+  accept4(0, NULL, NULL, SOCK_CLOEXEC);
+  TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, SOCK_CLOEXEC));
+  accept4(0, NULL, NULL, SOCK_NONBLOCK | SOCK_CLOEXEC);
+  TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, SOCK_NONBLOCK | SOCK_CLOEXEC));
+}
+
+class G {
+public:
+  int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
+  void d() {
+accept4(0, NULL, NULL, SOCK_NONBLOCK);
+TEMP_FAILURE_RETRY(accept4(0, NULL, NULL, SOCK_NONBLOCK));
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -4,6 +4,7 @@
 =
 
 .. toctree::
+   android-cloexec-accept4
android-cloexec-creat
android-cloexec-dup
android-cloexec-fopen
Index: docs/clang-tidy/checks/android-cloexec-accept4.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-accept4.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-accept4
+
+android-cloexec-accept4
+===
+
+``accept4()`` should include ``SOCK_CLOEXEC`` in its type argument to avoid the
+file descriptor leakage. Without this flag, an opened sensitive file would
+remain open across a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  accept4(sockfd, addr, addrlen, SOCK_NONBLOCK);
+
+  // becomes
+
+  accept4(sockfd, addr, addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -70,6 +70,12 @@
   ``AllowConditionalIntegerCasts`` -> ``AllowIntegerConditions``,
   ``AllowConditionalPointerCasts`` -> ``AllowPointerConditions``.
 
+- New `android-cloexec-accept4
+  `_ check
+
+  Checks if the required file flag ``SOCK_CLOEXEC`` is present in the argument of
+  ``accept4()``.
+
 - New `android-cloexec-dup
   `_ check
 
Index: clang-tidy/android/CloexecAccept4Check.h
===
--- /dev/null
+++ clang-tidy/android/CloexecAccept4Check.h
@@ -0,0 +1,35 @@
+//===--- CloexecAccept4Check.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---

[PATCH] D35362: [clang-tidy] Add a close-on-exec check on accept() in Android module.

2017-08-11 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 110758.

https://reviews.llvm.org/D35362

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecAcceptCheck.cpp
  clang-tidy/android/CloexecAcceptCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-accept.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-accept.cpp

Index: test/clang-tidy/android-cloexec-accept.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-accept.cpp
@@ -0,0 +1,28 @@
+// RUN: %check_clang_tidy %s android-cloexec-accept %t
+
+struct sockaddr {};
+typedef int socklen_t;
+#define NULL 0
+
+extern "C" int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
+
+void f() {
+  accept(0, NULL, NULL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer accept4() to accept() because accept4() allows SOCK_CLOEXEC [android-cloexec-accept]
+  // CHECK-FIXES: accept4(0, NULL, NULL, SOCK_CLOEXEC);
+}
+
+namespace i {
+int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
+void g() {
+  accept(0, NULL, NULL);
+}
+} // namespace i
+
+class C {
+public:
+  int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
+  void h() {
+accept(0, NULL, NULL);
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -4,6 +4,7 @@
 =
 
 .. toctree::
+   android-cloexec-accept
android-cloexec-creat
android-cloexec-dup
android-cloexec-fopen
Index: docs/clang-tidy/checks/android-cloexec-accept.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-accept.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-accept
+
+android-cloexec-accept
+==
+
+The usage of ``accept()`` is not recommended, it's better to use ``accept4()``.
+Without this flag, an opened sensitive file descriptor would remain open across
+a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  accept(sockfd, addr, addrlen);
+
+  // becomes
+
+  accept4(sockfd, addr, addrlen, SOCK_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -70,6 +70,11 @@
   ``AllowConditionalIntegerCasts`` -> ``AllowIntegerConditions``,
   ``AllowConditionalPointerCasts`` -> ``AllowPointerConditions``.
 
+- New `android-cloexec-accept
+  `_ check
+
+  Detects usage of ``accept()``.
+
 - New `android-cloexec-dup
   `_ check
 
Index: clang-tidy/android/CloexecAcceptCheck.h
===
--- /dev/null
+++ clang-tidy/android/CloexecAcceptCheck.h
@@ -0,0 +1,35 @@
+//===--- CloexecAcceptCheck.h - clang-tidy---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_ACCEPT_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_ACCEPT_H
+
+#include "CloexecCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+/// accept() is better to be replaced by accept4().
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-accept.html
+class CloexecAcceptCheck : public CloexecCheck {
+public:
+  CloexecAcceptCheck(StringRef Name, ClangTidyContext *Context)
+  : CloexecCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace android
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_ACCEPT_H
Index: clang-tidy/android/CloexecAcceptCheck.cpp
===
--- /dev/null
+++ clang-tidy/android/CloexecAcceptCheck.cpp
@@ -0,0 +1,47 @@
+//===--- CloexecAcceptCheck.cpp - clang-tidy---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "CloexecAcceptCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::

[PATCH] D34633: [clang-tidy] Fix a bug in android-file-open-flag

2017-06-28 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 104574.
yawanng added a comment.
Herald added subscribers: mgorny, srhines.

rename the check.


https://reviews.llvm.org/D34633

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecOpenCheck.cpp
  clang-tidy/android/CloexecOpenCheck.h
  clang-tidy/android/FileOpenFlagCheck.cpp
  clang-tidy/android/FileOpenFlagCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-open.rst
  docs/clang-tidy/checks/android-file-open-flag.rst
  test/clang-tidy/android-cloexec-open.cpp
  test/clang-tidy/android-file-open-flag.cpp

Index: test/clang-tidy/android-cloexec-open.cpp
===
--- test/clang-tidy/android-cloexec-open.cpp
+++ test/clang-tidy/android-cloexec-open.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s android-file-open-flag %t
+// RUN: %check_clang_tidy %s android-cloexec-open %t
 
 #define O_RDWR 1
 #define O_EXCL 2
@@ -18,7 +18,7 @@
 
 void a() {
   open("filename", O_RDWR);
-  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'open' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'open' should use O_CLOEXEC where possible [android-cloexec-open]
   // CHECK-FIXES: O_RDWR | O_CLOEXEC
   TEMP_FAILURE_RETRY(open("filename", O_RDWR));
   // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: 'open' should use O_CLOEXEC where
@@ -33,7 +33,7 @@
 
 void b() {
   open64("filename", O_RDWR);
-  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: 'open64' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: 'open64' should use O_CLOEXEC where possible [android-cloexec-open]
   // CHECK-FIXES: O_RDWR | O_CLOEXEC
   TEMP_FAILURE_RETRY(open64("filename", O_RDWR));
   // CHECK-MESSAGES: :[[@LINE-1]]:47: warning: 'open64' should use O_CLOEXEC where
@@ -48,7 +48,7 @@
 
 void c() {
   openat(0, "filename", O_RDWR);
-  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'openat' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'openat' should use O_CLOEXEC where possible [android-cloexec-open]
   // CHECK-FIXES: O_RDWR | O_CLOEXEC
   TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR));
   // CHECK-MESSAGES: :[[@LINE-1]]:50: warning: 'openat' should use O_CLOEXEC where
@@ -63,19 +63,19 @@
 
 void f() {
   open("filename", 3);
-  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'open' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'open' should use O_CLOEXEC where possible [android-cloexec-open]
   // CHECK-FIXES: 3 | O_CLOEXEC
   TEMP_FAILURE_RETRY(open("filename", 3));
   // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: 'open' should use O_CLOEXEC where
   // CHECK-FIXES: 3 | O_CLOEXEC
   open64("filename", 3);
-  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'open64' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'open64' should use O_CLOEXEC where possible [android-cloexec-open]
   // CHECK-FIXES: 3 | O_CLOEXEC
   TEMP_FAILURE_RETRY(open64("filename", 3));
   // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: 'open64' should use O_CLOEXEC where
   // CHECK-FIXES: 3 | O_CLOEXEC
   openat(0, "filename", 3);
-  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'openat' should use O_CLOEXEC where possible [android-file-open-flag]
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'openat' should use O_CLOEXEC where possible [android-cloexec-open]
   // CHECK-FIXES: 3 | O_CLOEXEC
   TEMP_FAILURE_RETRY(openat(0, "filename", 3));
   // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: 'openat' should use O_CLOEXEC where
Index: docs/clang-tidy/checks/android-cloexec-open.rst
===
--- docs/clang-tidy/checks/android-cloexec-open.rst
+++ docs/clang-tidy/checks/android-cloexec-open.rst
@@ -1,7 +1,7 @@
-.. title:: clang-tidy - android-file-open-flag
+.. title:: clang-tidy - android-cloexec-open
 
-android-file-open-flag
-==
+android-cloexec-open
+
 
 A common source of security bugs is code that opens a file without using the
 ``O_CLOEXEC`` flag.  Without that flag, an opened sensitive file would remain
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -57,8 +57,8 @@
 Improvements to clang-tidy
 --
 
-- New `android-file-open-flag
-  `_ check
+- New `android-cloexec-open
+  `_ check
 
   Checks if the required file flag ``O_CLOEXEC`` exists in ``open()``,
   ``open64()`` and ``openat()``.
Index: clang-tidy/android/CloexecOpenCheck.h
===

[PATCH] D34633: [clang-tidy] Fix a bug in android-file-open-flag

2017-06-29 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 104689.
yawanng added a comment.

Pull back the previous change. For some reason it's lost.


https://reviews.llvm.org/D34633

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecOpenCheck.cpp
  clang-tidy/android/CloexecOpenCheck.h
  clang-tidy/android/FileOpenFlagCheck.cpp
  clang-tidy/android/FileOpenFlagCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-open.rst
  docs/clang-tidy/checks/android-file-open-flag.rst
  test/clang-tidy/android-cloexec-open.cpp
  test/clang-tidy/android-file-open-flag.cpp

Index: test/clang-tidy/android-file-open-flag.cpp
===
--- test/clang-tidy/android-file-open-flag.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-// RUN: %check_clang_tidy %s android-file-open-flag %t
-
-#define O_RDWR 1
-#define O_EXCL 2
-#define __O_CLOEXEC 3
-#define O_CLOEXEC __O_CLOEXEC
-
-extern "C" int open(const char *fn, int flags, ...);
-extern "C" int open64(const char *fn, int flags, ...);
-extern "C" int openat(int dirfd, const char *pathname, int flags, ...);
-
-void a() {
-  open("filename", O_RDWR);
-  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'open' should use O_CLOEXEC where possible [android-file-open-flag]
-  // CHECK-FIXES: O_RDWR | O_CLOEXEC
-  open("filename", O_RDWR | O_EXCL);
-  // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: 'open' should use O_CLOEXEC where
-  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
-}
-
-void b() {
-  open64("filename", O_RDWR);
-  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: 'open64' should use O_CLOEXEC where possible [android-file-open-flag]
-  // CHECK-FIXES: O_RDWR | O_CLOEXEC
-  open64("filename", O_RDWR | O_EXCL);
-  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'open64' should use O_CLOEXEC where
-  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
-}
-
-void c() {
-  openat(0, "filename", O_RDWR);
-  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'openat' should use O_CLOEXEC where possible [android-file-open-flag]
-  // CHECK-FIXES: O_RDWR | O_CLOEXEC
-  openat(0, "filename", O_RDWR | O_EXCL);
-  // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: 'openat' should use O_CLOEXEC where
-  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
-}
-
-void f() {
-  open("filename", 3);
-  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'open' should use O_CLOEXEC where possible [android-file-open-flag]
-  // CHECK-FIXES: 3 | O_CLOEXEC
-  open64("filename", 3);
-  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'open64' should use O_CLOEXEC where possible [android-file-open-flag]
-  // CHECK-FIXES: 3 | O_CLOEXEC
-  openat(0, "filename", 3);
-  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'openat' should use O_CLOEXEC where possible [android-file-open-flag]
-  // CHECK-FIXES: 3 | O_CLOEXEC
-
-  int flag = 3;
-  open("filename", flag);
-  // CHECK-MESSAGES-NOT: warning:
-  open64("filename", flag);
-  // CHECK-MESSAGES-NOT: warning:
-  openat(0, "filename", flag);
-  // CHECK-MESSAGES-NOT: warning:
-}
-
-namespace i {
-int open(const char *pathname, int flags, ...);
-int open64(const char *pathname, int flags, ...);
-int openat(int dirfd, const char *pathname, int flags, ...);
-
-void d() {
-  open("filename", O_RDWR);
-  // CHECK-MESSAGES-NOT: warning:
-  open64("filename", O_RDWR);
-  // CHECK-MESSAGES-NOT: warning:
-  openat(0, "filename", O_RDWR);
-  // CHECK-MESSAGES-NOT: warning:
-}
-
-} // namespace i
-
-void e() {
-  open("filename", O_CLOEXEC);
-  // CHECK-MESSAGES-NOT: warning:
-  open("filename", O_RDWR | O_CLOEXEC);
-  // CHECK-MESSAGES-NOT: warning:
-  open("filename", O_RDWR | O_CLOEXEC | O_EXCL);
-  // CHECK-MESSAGES-NOT: warning:
-  open64("filename", O_CLOEXEC);
-  // CHECK-MESSAGES-NOT: warning:
-  open64("filename", O_RDWR | O_CLOEXEC);
-  // CHECK-MESSAGES-NOT: warning:
-  open64("filename", O_RDWR | O_CLOEXEC | O_EXCL);
-  // CHECK-MESSAGES-NOT: warning:
-  openat(0, "filename", O_CLOEXEC);
-  // CHECK-MESSAGES-NOT: warning:
-  openat(0, "filename", O_RDWR | O_CLOEXEC);
-  // CHECK-MESSAGES-NOT: warning:
-  openat(0, "filename", O_RDWR | O_CLOEXEC | O_EXCL);
-  // CHECK-MESSAGES-NOT: warning:
-}
-
-class G {
-public:
-  int open(const char *pathname, int flags, ...);
-  int open64(const char *pathname, int flags, ...);
-  int openat(int dirfd, const char *pathname, int flags, ...);
-
-  void h() {
-open("filename", O_RDWR);
-// CHECK-MESSAGES-NOT: warning:
-open64("filename", O_RDWR);
-// CHECK-MESSAGES-NOT: warning:
-openat(0, "filename", O_RDWR);
-// CHECK-MESSAGES-NOT: warning:
-  }
-};
Index: test/clang-tidy/android-cloexec-open.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-open.cpp
@@ -0,0 +1,180 @@
+// RUN: %check_clang_tidy %s android-cloexec-open %t
+
+#define O_RDWR 1
+#define O_EXCL 2
+#define __O_CLOEXEC 3
+#define O_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({ 

[PATCH] D34633: [clang-tidy] Rename android-file-open-flag and fix a bug

2017-06-29 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 104709.
yawanng added a comment.

Change the file name in toctree.


https://reviews.llvm.org/D34633

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecOpenCheck.cpp
  clang-tidy/android/CloexecOpenCheck.h
  clang-tidy/android/FileOpenFlagCheck.cpp
  clang-tidy/android/FileOpenFlagCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-open.rst
  docs/clang-tidy/checks/android-file-open-flag.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-open.cpp
  test/clang-tidy/android-file-open-flag.cpp

Index: test/clang-tidy/android-file-open-flag.cpp
===
--- test/clang-tidy/android-file-open-flag.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-// RUN: %check_clang_tidy %s android-file-open-flag %t
-
-#define O_RDWR 1
-#define O_EXCL 2
-#define __O_CLOEXEC 3
-#define O_CLOEXEC __O_CLOEXEC
-
-extern "C" int open(const char *fn, int flags, ...);
-extern "C" int open64(const char *fn, int flags, ...);
-extern "C" int openat(int dirfd, const char *pathname, int flags, ...);
-
-void a() {
-  open("filename", O_RDWR);
-  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'open' should use O_CLOEXEC where possible [android-file-open-flag]
-  // CHECK-FIXES: O_RDWR | O_CLOEXEC
-  open("filename", O_RDWR | O_EXCL);
-  // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: 'open' should use O_CLOEXEC where
-  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
-}
-
-void b() {
-  open64("filename", O_RDWR);
-  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: 'open64' should use O_CLOEXEC where possible [android-file-open-flag]
-  // CHECK-FIXES: O_RDWR | O_CLOEXEC
-  open64("filename", O_RDWR | O_EXCL);
-  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'open64' should use O_CLOEXEC where
-  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
-}
-
-void c() {
-  openat(0, "filename", O_RDWR);
-  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'openat' should use O_CLOEXEC where possible [android-file-open-flag]
-  // CHECK-FIXES: O_RDWR | O_CLOEXEC
-  openat(0, "filename", O_RDWR | O_EXCL);
-  // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: 'openat' should use O_CLOEXEC where
-  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
-}
-
-void f() {
-  open("filename", 3);
-  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'open' should use O_CLOEXEC where possible [android-file-open-flag]
-  // CHECK-FIXES: 3 | O_CLOEXEC
-  open64("filename", 3);
-  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'open64' should use O_CLOEXEC where possible [android-file-open-flag]
-  // CHECK-FIXES: 3 | O_CLOEXEC
-  openat(0, "filename", 3);
-  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'openat' should use O_CLOEXEC where possible [android-file-open-flag]
-  // CHECK-FIXES: 3 | O_CLOEXEC
-
-  int flag = 3;
-  open("filename", flag);
-  // CHECK-MESSAGES-NOT: warning:
-  open64("filename", flag);
-  // CHECK-MESSAGES-NOT: warning:
-  openat(0, "filename", flag);
-  // CHECK-MESSAGES-NOT: warning:
-}
-
-namespace i {
-int open(const char *pathname, int flags, ...);
-int open64(const char *pathname, int flags, ...);
-int openat(int dirfd, const char *pathname, int flags, ...);
-
-void d() {
-  open("filename", O_RDWR);
-  // CHECK-MESSAGES-NOT: warning:
-  open64("filename", O_RDWR);
-  // CHECK-MESSAGES-NOT: warning:
-  openat(0, "filename", O_RDWR);
-  // CHECK-MESSAGES-NOT: warning:
-}
-
-} // namespace i
-
-void e() {
-  open("filename", O_CLOEXEC);
-  // CHECK-MESSAGES-NOT: warning:
-  open("filename", O_RDWR | O_CLOEXEC);
-  // CHECK-MESSAGES-NOT: warning:
-  open("filename", O_RDWR | O_CLOEXEC | O_EXCL);
-  // CHECK-MESSAGES-NOT: warning:
-  open64("filename", O_CLOEXEC);
-  // CHECK-MESSAGES-NOT: warning:
-  open64("filename", O_RDWR | O_CLOEXEC);
-  // CHECK-MESSAGES-NOT: warning:
-  open64("filename", O_RDWR | O_CLOEXEC | O_EXCL);
-  // CHECK-MESSAGES-NOT: warning:
-  openat(0, "filename", O_CLOEXEC);
-  // CHECK-MESSAGES-NOT: warning:
-  openat(0, "filename", O_RDWR | O_CLOEXEC);
-  // CHECK-MESSAGES-NOT: warning:
-  openat(0, "filename", O_RDWR | O_CLOEXEC | O_EXCL);
-  // CHECK-MESSAGES-NOT: warning:
-}
-
-class G {
-public:
-  int open(const char *pathname, int flags, ...);
-  int open64(const char *pathname, int flags, ...);
-  int openat(int dirfd, const char *pathname, int flags, ...);
-
-  void h() {
-open("filename", O_RDWR);
-// CHECK-MESSAGES-NOT: warning:
-open64("filename", O_RDWR);
-// CHECK-MESSAGES-NOT: warning:
-openat(0, "filename", O_RDWR);
-// CHECK-MESSAGES-NOT: warning:
-  }
-};
Index: test/clang-tidy/android-cloexec-open.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-open.cpp
@@ -0,0 +1,180 @@
+// RUN: %check_clang_tidy %s android-cloexec-open %t
+
+#define O_RDWR 1
+#define O_EXCL 2
+#define __O_CLOEXEC 3
+#define O_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({

[PATCH] D34913: [clang-tidy] Add a new Android check "android-cloexec-socket"

2017-06-30 Thread Yan Wang via Phabricator via cfe-commits
yawanng created this revision.
yawanng added a project: clang-tools-extra.
Herald added subscribers: xazax.hun, JDevlieghere, mgorny, srhines.

socket() is better to include SOCK_CLOEXEC in its type argument to avoid the 
file descriptor leakage.


Repository:
  rL LLVM

https://reviews.llvm.org/D34913

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecOpenCheck.cpp
  clang-tidy/android/CloexecSocketCheck.cpp
  clang-tidy/android/CloexecSocketCheck.h
  clang-tidy/utils/CMakeLists.txt
  clang-tidy/utils/CloexecFlagChecker.cpp
  clang-tidy/utils/CloexecFlagChecker.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-socket.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-socket.cpp

Index: test/clang-tidy/android-cloexec-socket.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-socket.cpp
@@ -0,0 +1,92 @@
+// RUN: %check_clang_tidy %s android-cloexec-socket %t
+
+#define SOCK_STREAM 1
+#define SOCK_DGRAM 2
+#define __O_CLOEXEC 3
+#define SOCK_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({\
+int _rc;\
+do {\
+  _rc = (exp);  \
+} while (_rc == -1);\
+  })
+
+extern "C" int socket(int domain, int type, int protocol);
+
+void a() {
+  socket(0, SOCK_STREAM, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'socket' should use SOCK_CLOEXEC where possible [android-cloexec-socket]
+  // CHECK-FIXES: SOCK_STREAM | SOCK_CLOEXEC
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM, 0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: 'socket'
+  // CHECK-FIXES: SOCK_STREAM | SOCK_CLOEXEC
+  socket(0, SOCK_STREAM | SOCK_DGRAM, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'socket'
+  // CHECK-FIXES: SOCK_STREAM | SOCK_DGRAM | SOCK_CLOEXEC
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM, 0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:56: warning: 'socket'
+  // CHECK-FIXES: SOCK_STREAM | SOCK_DGRAM | SOCK_CLOEXEC
+}
+
+void f() {
+  socket(0, 3, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 'socket'
+  // CHECK-FIXES: 3 | SOCK_CLOEXEC
+  TEMP_FAILURE_RETRY(socket(0, 3, 0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: 'socket'
+  // CHECK-FIXES: 3 | SOCK_CLOEXEC
+
+  int flag = 3;
+  socket(0, flag, 0);
+  // CHECK-MESSAGES-NOT: warning:
+  TEMP_FAILURE_RETRY(socket(0, flag, 0));
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+namespace i {
+int socket(int domain, int type, int protocol);
+
+void d() {
+  socket(0, SOCK_STREAM, 0);
+  // CHECK-MESSAGES-NOT: warning:
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM, 0));
+  // CHECK-MESSAGES-NOT: warning:
+  socket(0, SOCK_STREAM | SOCK_DGRAM, 0);
+  // CHECK-MESSAGES-NOT: warning:
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM, 0));
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+} // namespace i
+
+void e() {
+  socket(0, SOCK_CLOEXEC, 0);
+  // CHECK-MESSAGES-NOT: warning:
+  TEMP_FAILURE_RETRY(socket(0, SOCK_CLOEXEC, 0));
+  // CHECK-MESSAGES-NOT: warning:
+  socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0);
+  // CHECK-MESSAGES-NOT: warning:
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0));
+  // CHECK-MESSAGES-NOT: warning:
+  socket(0, SOCK_STREAM | SOCK_CLOEXEC | SOCK_DGRAM, 0);
+  // CHECK-MESSAGES-NOT: warning:
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_CLOEXEC | SOCK_DGRAM, 0));
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+class G {
+public:
+  int socket(int domain, int type, int protocol);
+  void d() {
+socket(0, SOCK_STREAM, 0);
+// CHECK-MESSAGES-NOT: warning:
+TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM, 0));
+// CHECK-MESSAGES-NOT: warning:
+socket(0, SOCK_STREAM | SOCK_DGRAM, 0);
+// CHECK-MESSAGES-NOT: warning:
+TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM, 0));
+// CHECK-MESSAGES-NOT: warning:
+  }
+};
+
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -7,6 +7,7 @@
android-cloexec-creat
android-cloexec-fopen
android-cloexec-open
+   android-cloexec-socket
boost-use-to-string
cert-dcl03-c (redirects to misc-static-assert) 
cert-dcl21-cpp
Index: docs/clang-tidy/checks/android-cloexec-socket.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-socket.rst
@@ -0,0 +1,16 @@
+.. title:: clang-tidy - android-cloexec-socket
+
+android-cloexec-socket
+==
+``socket()`` should include ``SOCK_CLOEXEC`` in its type argument to avoid the
+file descriptor leakage.
+
+Examples:
+
+.. code-block:: c++
+
+  socket(domain, type, SOCK_STREAM);
+
+  // becomes
+
+  socket(domain, type, SOCK_STREAM | SOCK_CLOEXEC);
Index: docs/ReleaseNotes.rst
===

[PATCH] D34913: [clang-tidy] Add a new Android check "android-cloexec-socket"

2017-07-05 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 105293.
yawanng marked 8 inline comments as done.

https://reviews.llvm.org/D34913

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecOpenCheck.cpp
  clang-tidy/android/CloexecSocketCheck.cpp
  clang-tidy/android/CloexecSocketCheck.h
  clang-tidy/utils/ASTUtils.cpp
  clang-tidy/utils/ASTUtils.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-socket.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-socket.cpp

Index: test/clang-tidy/android-cloexec-socket.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-socket.cpp
@@ -0,0 +1,91 @@
+// RUN: %check_clang_tidy %s android-cloexec-socket %t
+
+#define SOCK_STREAM 1
+#define SOCK_DGRAM 2
+#define __O_CLOEXEC 3
+#define SOCK_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({\
+int _rc;\
+do {\
+  _rc = (exp);  \
+} while (_rc == -1);\
+  })
+
+extern "C" int socket(int domain, int type, int protocol);
+
+void a() {
+  socket(0, SOCK_STREAM, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'socket' should use SOCK_CLOEXEC where possible [android-cloexec-socket]
+  // CHECK-FIXES: socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0)
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM, 0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: 'socket'
+  // CHECK-FIXES: socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0)
+  socket(0, SOCK_STREAM | SOCK_DGRAM, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'socket'
+  // CHECK-FIXES: socket(0, SOCK_STREAM | SOCK_DGRAM | SOCK_CLOEXEC, 0)
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM, 0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:56: warning: 'socket'
+  // CHECK-FIXES: socket(0, SOCK_STREAM | SOCK_DGRAM | SOCK_CLOEXEC, 0)
+}
+
+void f() {
+  socket(0, 3, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 'socket'
+  // CHECK-FIXES: socket(0, 3 | SOCK_CLOEXEC, 0)
+  TEMP_FAILURE_RETRY(socket(0, 3, 0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: 'socket'
+  // CHECK-FIXES: socket(0, 3 | SOCK_CLOEXEC, 0)
+
+  int flag = 3;
+  socket(0, flag, 0);
+  // CHECK-MESSAGES-NOT: warning:
+  TEMP_FAILURE_RETRY(socket(0, flag, 0));
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+namespace i {
+int socket(int domain, int type, int protocol);
+
+void d() {
+  socket(0, SOCK_STREAM, 0);
+  // CHECK-MESSAGES-NOT: warning:
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM, 0));
+  // CHECK-MESSAGES-NOT: warning:
+  socket(0, SOCK_STREAM | SOCK_DGRAM, 0);
+  // CHECK-MESSAGES-NOT: warning:
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM, 0));
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+} // namespace i
+
+void e() {
+  socket(0, SOCK_CLOEXEC, 0);
+  // CHECK-MESSAGES-NOT: warning:
+  TEMP_FAILURE_RETRY(socket(0, SOCK_CLOEXEC, 0));
+  // CHECK-MESSAGES-NOT: warning:
+  socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0);
+  // CHECK-MESSAGES-NOT: warning:
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0));
+  // CHECK-MESSAGES-NOT: warning:
+  socket(0, SOCK_STREAM | SOCK_CLOEXEC | SOCK_DGRAM, 0);
+  // CHECK-MESSAGES-NOT: warning:
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_CLOEXEC | SOCK_DGRAM, 0));
+  // CHECK-MESSAGES-NOT: warning:
+}
+
+class G {
+public:
+  int socket(int domain, int type, int protocol);
+  void d() {
+socket(0, SOCK_STREAM, 0);
+// CHECK-MESSAGES-NOT: warning:
+TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM, 0));
+// CHECK-MESSAGES-NOT: warning:
+socket(0, SOCK_STREAM | SOCK_DGRAM, 0);
+// CHECK-MESSAGES-NOT: warning:
+TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM, 0));
+// CHECK-MESSAGES-NOT: warning:
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -7,6 +7,7 @@
android-cloexec-creat
android-cloexec-fopen
android-cloexec-open
+   android-cloexec-socket
boost-use-to-string
cert-dcl03-c (redirects to misc-static-assert) 
cert-dcl21-cpp
Index: docs/clang-tidy/checks/android-cloexec-socket.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-socket.rst
@@ -0,0 +1,17 @@
+.. title:: clang-tidy - android-cloexec-socket
+
+android-cloexec-socket
+==
+
+``socket()`` should include ``SOCK_CLOEXEC`` in its type argument to avoid the
+file descriptor leakage.
+
+Examples:
+
+.. code-block:: c++
+
+  socket(domain, type, SOCK_STREAM);
+
+  // becomes
+
+  socket(domain, type, SOCK_STREAM | SOCK_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -73,6 +73,12 @@
 
   Checks if the required mode ``e`` exists in the mode

[PATCH] D34114: [clang] A better format for unnecessary packed warning.

2017-07-05 Thread Yan Wang via Phabricator via cfe-commits
yawanng added a comment.

PING


Repository:
  rL LLVM

https://reviews.llvm.org/D34114



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D34913: [clang-tidy] Add a new Android check "android-cloexec-socket"

2017-07-10 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 105878.
yawanng marked 5 inline comments as done.

https://reviews.llvm.org/D34913

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecOpenCheck.cpp
  clang-tidy/android/CloexecSocketCheck.cpp
  clang-tidy/android/CloexecSocketCheck.h
  clang-tidy/utils/ASTUtils.cpp
  clang-tidy/utils/ASTUtils.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-socket.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-socket.cpp

Index: test/clang-tidy/android-cloexec-socket.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-socket.cpp
@@ -0,0 +1,75 @@
+// RUN: %check_clang_tidy %s android-cloexec-socket %t
+
+#define SOCK_STREAM 1
+#define SOCK_DGRAM 2
+#define __O_CLOEXEC 3
+#define SOCK_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({\
+int _rc;\
+do {\
+  _rc = (exp);  \
+} while (_rc == -1);\
+  })
+
+extern "C" int socket(int domain, int type, int protocol);
+
+void a() {
+  socket(0, SOCK_STREAM, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'socket' should use SOCK_CLOEXEC where possible [android-cloexec-socket]
+  // CHECK-FIXES: socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0)
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM, 0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: 'socket'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0))
+  socket(0, SOCK_STREAM | SOCK_DGRAM, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'socket'
+  // CHECK-FIXES: socket(0, SOCK_STREAM | SOCK_DGRAM | SOCK_CLOEXEC, 0)
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM, 0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:56: warning: 'socket'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM | SOCK_CLOEXEC, 0))
+}
+
+void f() {
+  socket(0, 3, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 'socket'
+  // CHECK-FIXES: socket(0, 3 | SOCK_CLOEXEC, 0)
+  TEMP_FAILURE_RETRY(socket(0, 3, 0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: 'socket'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, 3 | SOCK_CLOEXEC, 0))
+
+  int flag = 3;
+  socket(0, flag, 0);
+  TEMP_FAILURE_RETRY(socket(0, flag, 0));
+}
+
+namespace i {
+int socket(int domain, int type, int protocol);
+
+void d() {
+  socket(0, SOCK_STREAM, 0);
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM, 0));
+  socket(0, SOCK_STREAM | SOCK_DGRAM, 0);
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM, 0));
+}
+
+} // namespace i
+
+void e() {
+  socket(0, SOCK_CLOEXEC, 0);
+  TEMP_FAILURE_RETRY(socket(0, SOCK_CLOEXEC, 0));
+  socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0);
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0));
+  socket(0, SOCK_STREAM | SOCK_CLOEXEC | SOCK_DGRAM, 0);
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_CLOEXEC | SOCK_DGRAM, 0));
+}
+
+class G {
+public:
+  int socket(int domain, int type, int protocol);
+  void d() {
+socket(0, SOCK_STREAM, 0);
+TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM, 0));
+socket(0, SOCK_STREAM | SOCK_DGRAM, 0);
+TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM, 0));
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -7,6 +7,7 @@
android-cloexec-creat
android-cloexec-fopen
android-cloexec-open
+   android-cloexec-socket
boost-use-to-string
cert-dcl03-c (redirects to misc-static-assert) 
cert-dcl21-cpp
Index: docs/clang-tidy/checks/android-cloexec-socket.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-socket.rst
@@ -0,0 +1,17 @@
+.. title:: clang-tidy - android-cloexec-socket
+
+android-cloexec-socket
+==
+
+``socket()`` should include ``SOCK_CLOEXEC`` in its type argument to avoid the
+file descriptor leakage.
+
+Examples:
+
+.. code-block:: c++
+
+  socket(domain, type, SOCK_STREAM);
+
+  // becomes
+
+  socket(domain, type, SOCK_STREAM | SOCK_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -73,6 +73,12 @@
 
   Checks if the required mode ``e`` exists in the mode argument of ``fopen()``.
 
+- New `android-cloexec-socket
+  `_ check
+
+  Checks if the required file flag ``SOCK_CLOEXEC`` is present in the argument of
+  ``socket()``.
+
 - New `cert-dcl21-cpp
   `_ check
 
Index: clang-tidy/utils/ASTUtils.h
===
--- clang-tidy/utils/ASTUtils.h
+++ clang-tidy/util

[PATCH] D34913: [clang-tidy] Add a new Android check "android-cloexec-socket"

2017-07-10 Thread Yan Wang via Phabricator via cfe-commits
yawanng added inline comments.



Comment at: clang-tidy/utils/ASTUtils.h:27
+///  or  |  | ...
+bool hasFlag(const Expr *Flags, const SourceManager &SM,
+ const LangOptions &LangOpts, const char *CloseOnExecFlag);

alexfh wrote:
> `hasFlag` is too generic and may give a totally wrong impression of what the 
> function does. Even in the context of this utility library I would prefer to 
> expand the name and make it less ambiguous. Something along the lines of 
> `exprHasBitFlagWithSpelling`. I wouldn't also insist on the flag being 
> implemented as a macro, since this restriction would prevent many valid use 
> cases with enum or constexpr int flags.
Yes, the name is a little misleading and only consider the macro is not 
thorough. But for the purpose of the current Android checks, where this 
function is used, this simple solution can cover about 95% cases. Few use 
`enum` or `constexpr` for flags like `O_CLOEXEC` or other similar ones.  
Moreover, if extending the function to cover the constant integer variables, 
it's not easy to get the value of the checked flag, which may depend on the 
target. Generally, in current stage, this function works well in the Android 
cases and it's still a TODO for other more sophisticated user cases. 


https://reviews.llvm.org/D34913



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35194: [clang-tidy] clang-apply-replacements: Don't insert null entry

2017-07-10 Thread Yan Wang via Phabricator via cfe-commits
yawanng added a comment.

LGTM. Please wait for Alexander approval.




Comment at: clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp:296
+ << "' doesn't exist. Ignoring...\n";
+}
 continue;

Maybe add some error message here if it's not an existence issue. like "invalid 
file path" or something? The same below.


https://reviews.llvm.org/D35194



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D34913: [clang-tidy] Add a new Android check "android-cloexec-socket"

2017-07-11 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 106058.
yawanng marked 4 inline comments as done.

https://reviews.llvm.org/D34913

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecOpenCheck.cpp
  clang-tidy/android/CloexecSocketCheck.cpp
  clang-tidy/android/CloexecSocketCheck.h
  clang-tidy/utils/ASTUtils.cpp
  clang-tidy/utils/ASTUtils.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-socket.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-socket.cpp

Index: test/clang-tidy/android-cloexec-socket.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-socket.cpp
@@ -0,0 +1,75 @@
+// RUN: %check_clang_tidy %s android-cloexec-socket %t
+
+#define SOCK_STREAM 1
+#define SOCK_DGRAM 2
+#define __O_CLOEXEC 3
+#define SOCK_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({\
+int _rc;\
+do {\
+  _rc = (exp);  \
+} while (_rc == -1);\
+  })
+
+extern "C" int socket(int domain, int type, int protocol);
+
+void a() {
+  socket(0, SOCK_STREAM, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'socket' should use SOCK_CLOEXEC where possible [android-cloexec-socket]
+  // CHECK-FIXES: socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0)
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM, 0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: 'socket'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0))
+  socket(0, SOCK_STREAM | SOCK_DGRAM, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'socket'
+  // CHECK-FIXES: socket(0, SOCK_STREAM | SOCK_DGRAM | SOCK_CLOEXEC, 0)
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM, 0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:56: warning: 'socket'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM | SOCK_CLOEXEC, 0))
+}
+
+void f() {
+  socket(0, 3, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 'socket'
+  // CHECK-FIXES: socket(0, 3 | SOCK_CLOEXEC, 0)
+  TEMP_FAILURE_RETRY(socket(0, 3, 0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: 'socket'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, 3 | SOCK_CLOEXEC, 0))
+
+  int flag = 3;
+  socket(0, flag, 0);
+  TEMP_FAILURE_RETRY(socket(0, flag, 0));
+}
+
+namespace i {
+int socket(int domain, int type, int protocol);
+
+void d() {
+  socket(0, SOCK_STREAM, 0);
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM, 0));
+  socket(0, SOCK_STREAM | SOCK_DGRAM, 0);
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM, 0));
+}
+
+} // namespace i
+
+void e() {
+  socket(0, SOCK_CLOEXEC, 0);
+  TEMP_FAILURE_RETRY(socket(0, SOCK_CLOEXEC, 0));
+  socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0);
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0));
+  socket(0, SOCK_STREAM | SOCK_CLOEXEC | SOCK_DGRAM, 0);
+  TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_CLOEXEC | SOCK_DGRAM, 0));
+}
+
+class G {
+public:
+  int socket(int domain, int type, int protocol);
+  void d() {
+socket(0, SOCK_STREAM, 0);
+TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM, 0));
+socket(0, SOCK_STREAM | SOCK_DGRAM, 0);
+TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM, 0));
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -7,6 +7,7 @@
android-cloexec-creat
android-cloexec-fopen
android-cloexec-open
+   android-cloexec-socket
boost-use-to-string
cert-dcl03-c (redirects to misc-static-assert) 
cert-dcl21-cpp
Index: docs/clang-tidy/checks/android-cloexec-socket.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-socket.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-socket
+
+android-cloexec-socket
+==
+
+``socket()`` should include ``SOCK_CLOEXEC`` in its type argument to avoid the
+file descriptor leakage. Without this flag, an opened sensitive file would
+remain open across a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  socket(domain, type, SOCK_STREAM);
+
+  // becomes
+
+  socket(domain, type, SOCK_STREAM | SOCK_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -73,6 +73,12 @@
 
   Checks if the required mode ``e`` exists in the mode argument of ``fopen()``.
 
+- New `android-cloexec-socket
+  `_ check
+
+  Checks if the required file flag ``SOCK_CLOEXEC`` is present in the argument of
+  ``socket()``.
+
 - New `cert-dcl21-cpp
   `_ check
 
Index: clang-tidy/utils/ASTUtils.h

[PATCH] D34913: [clang-tidy] Add a new Android check "android-cloexec-socket"

2017-07-12 Thread Yan Wang via Phabricator via cfe-commits
yawanng added a comment.

In https://reviews.llvm.org/D34913#797577, @Eugene.Zelenko wrote:

> Please wait for Alexander, Aaron or Haojian approval.


Could you please check this CL? Thank you.


https://reviews.llvm.org/D34913



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D34913: [clang-tidy] Add a new Android check "android-cloexec-socket"

2017-07-12 Thread Yan Wang via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL307818: [clang-tidy] Add a new Android check 
"android-cloexec-socket" (authored by yawanng).

Changed prior to commit:
  https://reviews.llvm.org/D34913?vs=106058&id=106252#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D34913

Files:
  clang-tools-extra/trunk/clang-tidy/android/AndroidTidyModule.cpp
  clang-tools-extra/trunk/clang-tidy/android/CMakeLists.txt
  clang-tools-extra/trunk/clang-tidy/android/CloexecOpenCheck.cpp
  clang-tools-extra/trunk/clang-tidy/android/CloexecSocketCheck.cpp
  clang-tools-extra/trunk/clang-tidy/android/CloexecSocketCheck.h
  clang-tools-extra/trunk/clang-tidy/utils/ASTUtils.cpp
  clang-tools-extra/trunk/clang-tidy/utils/ASTUtils.h
  clang-tools-extra/trunk/docs/ReleaseNotes.rst
  clang-tools-extra/trunk/docs/clang-tidy/checks/android-cloexec-socket.rst
  clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
  clang-tools-extra/trunk/test/clang-tidy/android-cloexec-socket.cpp

Index: clang-tools-extra/trunk/clang-tidy/android/CloexecSocketCheck.h
===
--- clang-tools-extra/trunk/clang-tidy/android/CloexecSocketCheck.h
+++ clang-tools-extra/trunk/clang-tidy/android/CloexecSocketCheck.h
@@ -0,0 +1,35 @@
+//===--- CloexecSocketCheck.h - clang-tidy---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_SOCKET_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_SOCKET_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+/// Finds code that uses socket() without using the SOCK_CLOEXEC flag.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-socket.html
+class CloexecSocketCheck : public ClangTidyCheck {
+public:
+  CloexecSocketCheck(StringRef Name, ClangTidyContext *Context)
+  : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace android
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_SOCKET_H
Index: clang-tools-extra/trunk/clang-tidy/android/CMakeLists.txt
===
--- clang-tools-extra/trunk/clang-tidy/android/CMakeLists.txt
+++ clang-tools-extra/trunk/clang-tidy/android/CMakeLists.txt
@@ -5,6 +5,7 @@
   CloexecCreatCheck.cpp
   CloexecFopenCheck.cpp
   CloexecOpenCheck.cpp
+  CloexecSocketCheck.cpp
 
   LINK_LIBS
   clangAST
Index: clang-tools-extra/trunk/clang-tidy/android/CloexecSocketCheck.cpp
===
--- clang-tools-extra/trunk/clang-tidy/android/CloexecSocketCheck.cpp
+++ clang-tools-extra/trunk/clang-tidy/android/CloexecSocketCheck.cpp
@@ -0,0 +1,57 @@
+//===--- CloexecSocketCheck.cpp - clang-tidy---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "CloexecSocketCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+static constexpr const char *SOCK_CLOEXEC = "SOCK_CLOEXEC";
+
+void CloexecSocketCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+  callExpr(callee(functionDecl(isExternC(), returns(isInteger()),
+   hasName("socket"),
+   hasParameter(0, hasType(isInteger())),
+   hasParameter(1, hasType(isInteger())),
+   hasParameter(2, hasType(isInteger(
+  .bind("funcDecl")))
+  .bind("socketFn"),
+  this);
+}
+
+void CloexecSocketCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *MatchedCall = Result.Nodes.getNodeAs("socketFn");
+  const auto *FD = Result.Nodes.getNodeAs("funcDecl");
+  const Expr *FlagArg = MatchedCall->getArg(1);
+  SourceManager &SM = *Result.SourceManager;
+
+  if (utils::exprHasBitFlagWithSpelling(FlagArg->IgnoreParenCasts(), SM,
+ Result.Context->getLangOpts(), SOCK_CLOEXEC))
+return;
+
+  SourceLocation EndLoc =
+  Lexer::getLocForEndOfToken(SM.getFileLoc(FlagArg->getLocEnd()), 

[PATCH] D35362: [clang-tidy] Add close-on-exec checks on several functions in Android module.

2017-07-13 Thread Yan Wang via Phabricator via cfe-commits
yawanng created this revision.
yawanng added a project: clang-tools-extra.
Herald added subscribers: xazax.hun, JDevlieghere, mgorny.

accept() is better to be replaced by accept4() with SOCK_CLOEXEC flag to avoid 
file descriptor leakage.

This is one of a bunch of similar APIs as below and they have very similar 
structures:


https://reviews.llvm.org/D35362

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecAcceptCheck.cpp
  clang-tidy/android/CloexecAcceptCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-accept.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-accept.cpp

Index: test/clang-tidy/android-cloexec-accept.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-accept.cpp
@@ -0,0 +1,28 @@
+// RUN: %check_clang_tidy %s android-cloexec-accept %t
+
+struct sockaddr {};
+typedef int socklen_t;
+#define NULL 0
+
+extern "C" int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
+
+void f() {
+  accept(0, NULL, NULL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer accept4() to accept() because accept4() allows SOCK_CLOEXEC [android-cloexec-accept]
+  // CHECK-FIXES: accept4(0, NULL, NULL, SOCK_CLOEXEC)
+}
+
+namespace i {
+int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
+void g() {
+  accept(0, NULL, NULL);
+}
+} // namespace i
+
+class C {
+public:
+  int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
+  void h() {
+accept(0, NULL, NULL);
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -4,6 +4,7 @@
 =
 
 .. toctree::
+   android-cloexec-accept
android-cloexec-creat
android-cloexec-fopen
android-cloexec-open
Index: docs/clang-tidy/checks/android-cloexec-accept.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-accept.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-accept
+
+android-cloexec-accept
+==
+
+The usage of ``accept()`` is not recommended, it's better to use ``accept4()``.
+Without this flag, an opened sensitive file descriptor would remain open across
+a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  accept(sockfd, addr, addrlen);
+
+  // becomes
+
+  accept4(sockfd, addr, addrlen, SOCK_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -57,6 +57,11 @@
 Improvements to clang-tidy
 --
 
+- New `android-cloexec-accept
+  `_ check
+
+  Detects usage of ``accept()``.
+
 - New `android-cloexec-creat
   `_ check
 
Index: clang-tidy/android/CloexecAcceptCheck.h
===
--- /dev/null
+++ clang-tidy/android/CloexecAcceptCheck.h
@@ -0,0 +1,35 @@
+//===--- CloexecAcceptCheck.h - clang-tidy---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_ACCEPT_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_ACCEPT_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+/// accept() is better to be replaced by accept4().
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-accept.html
+class CloexecAcceptCheck : public ClangTidyCheck {
+public:
+  CloexecAcceptCheck(StringRef Name, ClangTidyContext *Context)
+  : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace android
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_ACCEPT_H
Index: clang-tidy/android/CloexecAcceptCheck.cpp
===
--- /dev/null
+++ clang-tidy/android/CloexecAcceptCheck.cpp
@@ -0,0 +1,64 @@
+//===--- CloexecAcceptCheck.cpp - clang-tidy---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===-

[PATCH] D35372: [clang-tidy] Add a close-on-exec check on memfd_create() in Android module.

2017-07-13 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 106515.
yawanng marked an inline comment as done.

https://reviews.llvm.org/D35372

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecMemfdCreateCheck.cpp
  clang-tidy/android/CloexecMemfdCreateCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-memfd-create.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-memfd-create.cpp

Index: test/clang-tidy/android-cloexec-memfd-create.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-memfd-create.cpp
@@ -0,0 +1,63 @@
+// RUN: %check_clang_tidy %s android-cloexec-memfd-create %t
+
+#define MFD_ALLOW_SEALING 1
+#define __O_CLOEXEC 3
+#define MFD_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({\
+int _rc;\
+do {\
+  _rc = (exp);  \
+} while (_rc == -1);\
+  })
+#define NULL 0
+
+extern "C" int memfd_create(const char *name, unsigned int flags);
+
+void a() {
+  memfd_create(NULL, MFD_ALLOW_SEALING);
+  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: 'memfd_create' should use MFD_CLOEXEC where possible [android-cloexec-memfd-create]
+  // CHECK-FIXES: memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC)
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+  // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: 'memfd_create'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC))
+}
+
+void f() {
+  memfd_create(NULL, 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'memfd_create'
+  // CHECK-FIXES: memfd_create(NULL, 3 | MFD_CLOEXEC)
+  TEMP_FAILURE_RETRY(memfd_create(NULL, 3));
+  // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: 'memfd_create'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, 3 | MFD_CLOEXEC))
+
+  int flag = 3;
+  memfd_create(NULL, flag);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, flag));
+}
+
+namespace i {
+int memfd_create(const char *name, unsigned int flags);
+
+void d() {
+  memfd_create(NULL, MFD_ALLOW_SEALING);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+}
+
+} // namespace i
+
+void e() {
+  memfd_create(NULL, MFD_CLOEXEC);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_CLOEXEC));
+  memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC));
+}
+
+class G {
+public:
+  int memfd_create(const char *name, unsigned int flags);
+  void d() {
+memfd_create(NULL, MFD_ALLOW_SEALING);
+TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -6,6 +6,7 @@
 .. toctree::
android-cloexec-creat
android-cloexec-fopen
+   android-cloexec-memfd-create
android-cloexec-open
android-cloexec-socket
boost-use-to-string
Index: docs/clang-tidy/checks/android-cloexec-memfd-create.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-memfd-create.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-memfd-create
+
+android-cloexec-memfd-create
+
+
+``memfd_create()`` should include ``MFD_CLOEXEC`` in its type argument to avoid
+the file descriptor leakage. Without this flag, an opened sensitive file would
+remain open across a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  memfd_create(name, MFD_ALLOW_SEALING);
+
+  // becomes
+
+  memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -73,6 +73,12 @@
 
   Checks if the required mode ``e`` exists in the mode argument of ``fopen()``.
 
+- New `android-cloexec-memfd_create
+  `_ check
+
+  Checks if the required file flag ``MFD_CLOEXEC`` is present in the argument of
+  ``memfd_create()``.
+
 - New `android-cloexec-socket
   `_ check
 
Index: clang-tidy/android/CloexecMemfdCreateCheck.h
===
--- /dev/null
+++ clang-tidy/android/CloexecMemfdCreateCheck.h
@@ -0,0 +1,35 @@
+//===--- CloexecMemfdCreateCheck.h - clang-tidy-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOO

[PATCH] D35370: [clang-tidy] Add a close-on-exec check on inotify_init() in Android module.

2017-07-13 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 106517.
yawanng marked an inline comment as done.

https://reviews.llvm.org/D35370

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecInotifyInitCheck.cpp
  clang-tidy/android/CloexecInotifyInitCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-inotify-init.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-inotify-init.cpp

Index: test/clang-tidy/android-cloexec-inotify-init.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-inotify-init.cpp
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s android-cloexec-inotify-init %t
+
+extern "C" int inotify_init();
+
+void f() {
+  inotify_init();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer inotify_init() to inotify_init1() because inotify_init1() allows IN_CLOEXEC [android-cloexec-inotify-init]
+  // CHECK-FIXES: inotify_init1(IN_CLOEXEC)
+}
+
+namespace i {
+int inotify_init();
+void g() {
+  inotify_init();
+}
+} // namespace i
+
+class C {
+public:
+  int inotify_init();
+  void h() {
+inotify_init();
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -6,6 +6,7 @@
 .. toctree::
android-cloexec-creat
android-cloexec-fopen
+   android-cloexec-inotify-init
android-cloexec-open
android-cloexec-socket
boost-use-to-string
Index: docs/clang-tidy/checks/android-cloexec-inotify-init.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-inotify-init.rst
@@ -0,0 +1,17 @@
+.. title:: clang-tidy - android-cloexec-inotify-init
+
+android-cloexec-inotify-init
+
+
+The usage of ``inotify_init()`` is not recommended, it's better to use
+``inotify_init1()``.
+
+Examples:
+
+.. code-block:: c++
+
+  inotify_init();
+
+  // becomes
+
+  inotify_init1(IN_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -73,6 +73,11 @@
 
   Checks if the required mode ``e`` exists in the mode argument of ``fopen()``.
 
+- New `android-cloexec-inotify-init
+  `_ check
+
+  Detects usage of ``inotify_init()``.
+
 - New `android-cloexec-socket
   `_ check
 
Index: clang-tidy/android/CloexecInotifyInitCheck.h
===
--- /dev/null
+++ clang-tidy/android/CloexecInotifyInitCheck.h
@@ -0,0 +1,35 @@
+//===--- CloexecInotifyInitCheck.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_INOTIFY_INIT_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_INOTIFY_INIT_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+/// inotify_init() is better to be replaced by inotify_init1().
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-inotify-init.html
+class CloexecInotifyInitCheck : public ClangTidyCheck {
+public:
+  CloexecInotifyInitCheck(StringRef Name, ClangTidyContext *Context)
+  : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace android
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_INOTIFY_INIT_H
Index: clang-tidy/android/CloexecInotifyInitCheck.cpp
===
--- /dev/null
+++ clang-tidy/android/CloexecInotifyInitCheck.cpp
@@ -0,0 +1,40 @@
+//===--- CloexecInotifyInitCheck.cpp - clang-tidy--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "CloexecInotifyInitCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+void CloexecInotifyInitCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+  ca

[PATCH] D35368: [clang-tidy] Add a close-on-exec check on inotify_init1() in Android module.

2017-07-13 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 106520.
yawanng marked an inline comment as done.
Herald added subscribers: xazax.hun, JDevlieghere.

https://reviews.llvm.org/D35368

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecInotifyInit1Check.cpp
  clang-tidy/android/CloexecInotifyInit1Check.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-inotify-init1.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-inotify-init1.cpp

Index: test/clang-tidy/android-cloexec-inotify-init1.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-inotify-init1.cpp
@@ -0,0 +1,64 @@
+// RUN: %check_clang_tidy %s android-cloexec-inotify-init1 %t
+
+#define IN_NONBLOCK 1
+#define __O_CLOEXEC 3
+#define IN_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({\
+int _rc;\
+do {\
+  _rc = (exp);  \
+} while (_rc == -1);\
+  })
+
+extern "C" int inotify_init1(int flags);
+
+void a() {
+  inotify_init1(IN_NONBLOCK);
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: 'inotify_init1' should use IN_CLOEXEC where possible [android-cloexec-inotify-init1]
+  // CHECK-FIXES: inotify_init1(IN_NONBLOCK | IN_CLOEXEC)
+  TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK));
+  // CHECK-MESSAGES: :[[@LINE-1]]:47: warning: 'inotify_init1'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK | IN_CLOEXEC))
+}
+
+void f() {
+  inotify_init1(0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'inotify_init1'
+  // CHECK-FIXES: inotify_init1(IN_CLOEXEC)
+  TEMP_FAILURE_RETRY(inotify_init1(0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'inotify_init1'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(inotify_init1(IN_CLOEXEC))
+
+  int flag = 1;
+  inotify_init1(flag);
+  TEMP_FAILURE_RETRY(inotify_init1(flag));
+}
+
+namespace i {
+int inotify_init1(int flags);
+
+void d() {
+  inotify_init1(IN_NONBLOCK);
+  TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK));
+}
+
+} // namespace i
+
+void e() {
+  inotify_init1(IN_CLOEXEC);
+  TEMP_FAILURE_RETRY(inotify_init1(IN_CLOEXEC));
+  inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+  TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK | IN_CLOEXEC));
+}
+
+class G {
+public:
+  int inotify_init1(int flags);
+  void d() {
+inotify_init1(IN_CLOEXEC);
+TEMP_FAILURE_RETRY(inotify_init1(IN_CLOEXEC));
+inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK | IN_CLOEXEC));
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -6,6 +6,7 @@
 .. toctree::
android-cloexec-creat
android-cloexec-fopen
+   android-cloexec-inotify-init1
android-cloexec-open
android-cloexec-socket
boost-use-to-string
Index: docs/clang-tidy/checks/android-cloexec-inotify-init1.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-inotify-init1.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-inotify-init1
+
+android-cloexec-inotify-init1
+=
+
+``inotify_init1()`` should include ``IN_CLOEXEC`` in its type argument to avoid the
+file descriptor leakage. Without this flag, an opened sensitive file would
+remain open across a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  inotify_init1(IN_NONBLOCK);
+
+  // becomes
+
+  inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -73,6 +73,12 @@
 
   Checks if the required mode ``e`` exists in the mode argument of ``fopen()``.
 
+- New `android-cloexec-inotify-init1
+  `_ check
+
+  Checks if the required file flag ``IN_CLOEXEC`` is present in the argument of
+  ``inotify_init1()``.
+
 - New `android-cloexec-socket
   `_ check
 
Index: clang-tidy/android/CloexecInotifyInit1Check.h
===
--- /dev/null
+++ clang-tidy/android/CloexecInotifyInit1Check.h
@@ -0,0 +1,35 @@
+//===--- CloexecInotifyInit1Check.h - clang-tidy-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_INOTIFY_INIT1_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOE

[PATCH] D35365: [clang-tidy] Add a close-on-exec check on epoll_create1() in Android module.

2017-07-13 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 106523.
yawanng marked 2 inline comments as done.

https://reviews.llvm.org/D35365

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecEpollCreate1Check.cpp
  clang-tidy/android/CloexecEpollCreate1Check.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-epoll-create1.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-epoll-create1.cpp

Index: test/clang-tidy/android-cloexec-epoll-create1.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-epoll-create1.cpp
@@ -0,0 +1,59 @@
+// RUN: %check_clang_tidy %s android-cloexec-epoll-create1 %t
+
+#define __O_CLOEXEC 3
+#define EPOLL_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({\
+int _rc;\
+do {\
+  _rc = (exp);  \
+} while (_rc == -1);\
+  })
+
+extern "C" int epoll_create1(int flags);
+
+void a() {
+  epoll_create1(0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'epoll_create1' should use EPOLL_CLOEXEC where possible [android-cloexec-epoll-create1]
+  // CHECK-FIXES: epoll_create1(EPOLL_CLOEXEC)
+  TEMP_FAILURE_RETRY(epoll_create1(0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'epoll_create1'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC))
+}
+
+void f() {
+  epoll_create1(3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'epoll_create1'
+  // CHECK-FIXES: epoll_create1(EPOLL_CLOEXEC)
+  TEMP_FAILURE_RETRY(epoll_create1(3));
+  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'epoll_create1'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC))
+
+  int flag = 0;
+  epoll_create1(EPOLL_CLOEXEC);
+  TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
+}
+
+namespace i {
+int epoll_create1(int flags);
+
+void d() {
+  epoll_create1(0);
+  TEMP_FAILURE_RETRY(epoll_create1(0));
+}
+
+} // namespace i
+
+void e() {
+  epoll_create1(EPOLL_CLOEXEC);
+  TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
+}
+
+class G {
+public:
+  int epoll_create1(int flags);
+  void d() {
+epoll_create1(EPOLL_CLOEXEC);
+TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -5,6 +5,7 @@
 
 .. toctree::
android-cloexec-creat
+   android-cloexec-epoll-create1
android-cloexec-fopen
android-cloexec-open
android-cloexec-socket
Index: docs/clang-tidy/checks/android-cloexec-epoll-create1.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-epoll-create1.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-epoll-create1
+
+android-cloexec-epoll-create1
+=
+
+``epoll_create1()`` should include ``EPOLL_CLOEXEC`` in its type argument to
+avoid the file descriptor leakage. Without this flag, an opened sensitive file
+would remain open across a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  epoll_create1(0);
+
+  // becomes
+
+  epoll_create1(EPOLL_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -62,6 +62,12 @@
 
   Detect usage of ``creat()``.
 
+- New `android-cloexec-epoll-create1
+  `_ check
+
+  Checks if the required file flag ``EPOLL_CLOEXEC`` is present in the argument of
+  ``epoll_create1()``.
+
 - New `android-cloexec-open
   `_ check
 
Index: clang-tidy/android/CloexecEpollCreate1Check.h
===
--- /dev/null
+++ clang-tidy/android/CloexecEpollCreate1Check.h
@@ -0,0 +1,35 @@
+//===--- CloexecEpollCreate1Check.h - clang-tidy-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_EPOLL_CREATE1_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_EPOLL_CREATE1_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+/// Finds code that uses epoll_create1() without using the EPOLL_CLOEXEC flag.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-epoll-create1.html
+class CloexecEpollCreate1Check : public ClangTidyCheck {
+public:
+  CloexecE

[PATCH] D35367: [clang-tidy] Add a close-on-exec check on epoll_create() in Android module.

2017-07-13 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 106539.
yawanng marked an inline comment as done.
Herald added subscribers: xazax.hun, JDevlieghere.

https://reviews.llvm.org/D35367

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecEpollCreateCheck.cpp
  clang-tidy/android/CloexecEpollCreateCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-epoll-create.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-epoll-create.cpp

Index: test/clang-tidy/android-cloexec-epoll-create.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-epoll-create.cpp
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s android-cloexec-epoll-create %t
+
+extern "C" int epoll_create(int size);
+
+void f() {
+  epoll_create(0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer epoll_create() to epoll_create1() because epoll_create1() allows EPOLL_CLOEXEC [android-cloexec-epoll-create]
+  // CHECK-FIXES: epoll_create1(EPOLL_CLOEXEC)
+}
+
+namespace i {
+int epoll_create(int size);
+void g() {
+  epoll_create(0);
+}
+} // namespace i
+
+class C {
+public:
+  int epoll_create(int size);
+  void h() {
+epoll_create(0);
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -5,6 +5,7 @@
 
 .. toctree::
android-cloexec-creat
+   android-cloexec-epoll-create
android-cloexec-fopen
android-cloexec-open
android-cloexec-socket
Index: docs/clang-tidy/checks/android-cloexec-epoll-create.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-epoll-create.rst
@@ -0,0 +1,17 @@
+.. title:: clang-tidy - android-cloexec-epoll-create
+
+android-cloexec-epoll-create
+
+
+The usage of ``epoll_create()`` is not recommended, it's better to use
+``epoll_create1()``, which allows close-on-exec.
+
+Examples:
+
+.. code-block:: c++
+
+  epoll_create(size);
+
+  // becomes
+
+  epoll_create1(EPOLL_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -62,6 +62,11 @@
 
   Detect usage of ``creat()``.
 
+- New `android-cloexec-epoll-create
+  `_ check
+
+  Detects usage of ``epoll_create()``.
+
 - New `android-cloexec-open
   `_ check
 
Index: clang-tidy/android/CloexecEpollCreateCheck.h
===
--- /dev/null
+++ clang-tidy/android/CloexecEpollCreateCheck.h
@@ -0,0 +1,35 @@
+//===--- CloexecEpollCreateCheck.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_EPOLL_CREATE_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_EPOLL_CREATE_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+/// epoll_create() is better to be replaced by epoll_create1().
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-epoll-create.html
+class CloexecEpollCreateCheck : public ClangTidyCheck {
+public:
+  CloexecEpollCreateCheck(StringRef Name, ClangTidyContext *Context)
+  : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace android
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_EPOLL_CREATE_H
Index: clang-tidy/android/CloexecEpollCreateCheck.cpp
===
--- /dev/null
+++ clang-tidy/android/CloexecEpollCreateCheck.cpp
@@ -0,0 +1,42 @@
+//===--- CloexecEpollCreateCheck.cpp - clang-tidy--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "CloexecEpollCreateCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+void CloexecEpollCreateCheck::registerMatchers(MatchFinder

[PATCH] D35372: [clang-tidy] Add a close-on-exec check on memfd_create() in Android module.

2017-07-17 Thread Yan Wang via Phabricator via cfe-commits
yawanng added a comment.

In https://reviews.llvm.org/D35372#810525, @alexfh wrote:

> In https://reviews.llvm.org/D35372#810457, @alexfh wrote:
>
> > I have deja vu ;)
> >
> > Should we make a single check for all CLOEXEC and friends with a single 
> > configurable list of (function name, flag name) pairs?
>
>
> Okay, it may be a bit more complicated than just a list of function name -> 
> flag name mappings, since we have to take in account the argument position as 
> well. We also might want to check the signature to a certain degree to avoid 
> matching wrong function. There are multiple approaches possible to rule out 
> incorrect functions with the same name:
>
> 1. just look at the number of arguments - this might well be enough, since 
> for a certain codebase I wouldn't expect multiple `memfd_create`'s etc. It 
> would allow user configurability of the function -> flag mappings.
> 2. encode the types of arguments as strings and have a small dictionary of 
> matchers in the check (e.g. `"const char*" -> 
> pointerType(pointee(isAnyCharacter()))`) - that will be more precise and 
> still quite flexible and also allow user-configurable function -> flag 
> mappings. But this mechanism may be an overkill, if we don't anticipate 
> user-configurable functions. I don't know how complex the resulting code 
> turns out to be.
> 3. Add a matcher for each function statically. This would obviously allow for 
> arbitrarily complex matchers, but won't be extensible via configuration 
> options.


Great idea. But we may prefer separate checks, because each API can be 
controlled independently. Moreover, there are not that many such system 
functions and hopefully we have listed most of them already :-)  To reduce the 
code duplication, what about a base class for all of them and try to share as 
much code as possible?


https://reviews.llvm.org/D35372



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35372: [clang-tidy] Add a close-on-exec check on memfd_create() in Android module.

2017-07-20 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 107557.
yawanng added a comment.

Refactor the check, add a base class for it, which can facilitate all other 
similar checks. Basically, all checks in the same category will have only one 
or two lines code by inheriting the base class. If this looks good, I will 
modify all other similar ones. Thank you :-)


https://reviews.llvm.org/D35372

Files:
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/CloexecCheck.cpp
  clang-tidy/android/CloexecCheck.h
  clang-tidy/android/CloexecMemfdCreateCheck.cpp
  clang-tidy/android/CloexecMemfdCreateCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/android-cloexec-memfd-create.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/android-cloexec-memfd-create.cpp

Index: test/clang-tidy/android-cloexec-memfd-create.cpp
===
--- /dev/null
+++ test/clang-tidy/android-cloexec-memfd-create.cpp
@@ -0,0 +1,63 @@
+// RUN: %check_clang_tidy %s android-cloexec-memfd-create %t
+
+#define MFD_ALLOW_SEALING 1
+#define __O_CLOEXEC 3
+#define MFD_CLOEXEC __O_CLOEXEC
+#define TEMP_FAILURE_RETRY(exp) \
+  ({\
+int _rc;\
+do {\
+  _rc = (exp);  \
+} while (_rc == -1);\
+  })
+#define NULL 0
+
+extern "C" int memfd_create(const char *name, unsigned int flags);
+
+void a() {
+  memfd_create(NULL, MFD_ALLOW_SEALING);
+  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: 'memfd_create' should use MFD_CLOEXEC where possible [android-cloexec-memfd-create]
+  // CHECK-FIXES: memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC)
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+  // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: 'memfd_create'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC))
+}
+
+void f() {
+  memfd_create(NULL, 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'memfd_create'
+  // CHECK-FIXES: memfd_create(NULL, 3 | MFD_CLOEXEC)
+  TEMP_FAILURE_RETRY(memfd_create(NULL, 3));
+  // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: 'memfd_create'
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, 3 | MFD_CLOEXEC))
+
+  int flag = 3;
+  memfd_create(NULL, flag);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, flag));
+}
+
+namespace i {
+int memfd_create(const char *name, unsigned int flags);
+
+void d() {
+  memfd_create(NULL, MFD_ALLOW_SEALING);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+}
+
+} // namespace i
+
+void e() {
+  memfd_create(NULL, MFD_CLOEXEC);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_CLOEXEC));
+  memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC);
+  TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC));
+}
+
+class G {
+public:
+  int memfd_create(const char *name, unsigned int flags);
+  void d() {
+memfd_create(NULL, MFD_ALLOW_SEALING);
+TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
+  }
+};
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -6,6 +6,7 @@
 .. toctree::
android-cloexec-creat
android-cloexec-fopen
+   android-cloexec-memfd-create
android-cloexec-open
android-cloexec-socket
boost-use-to-string
Index: docs/clang-tidy/checks/android-cloexec-memfd-create.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/android-cloexec-memfd-create.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - android-cloexec-memfd-create
+
+android-cloexec-memfd-create
+
+
+``memfd_create()`` should include ``MFD_CLOEXEC`` in its type argument to avoid
+the file descriptor leakage. Without this flag, an opened sensitive file would
+remain open across a fork+exec to a lower-privileged SELinux domain.
+
+Examples:
+
+.. code-block:: c++
+
+  memfd_create(name, MFD_ALLOW_SEALING);
+
+  // becomes
+
+  memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC);
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -73,6 +73,12 @@
 
   Checks if the required mode ``e`` exists in the mode argument of ``fopen()``.
 
+- New `android-cloexec-memfd_create
+  `_ check
+
+  Checks if the required file flag ``MFD_CLOEXEC`` is present in the argument of
+  ``memfd_create()``.
+
 - New `android-cloexec-socket
   `_ check
 
Index: clang-tidy/android/CloexecMemfdCreateCheck.h
===
--- /dev/null
+++ clang-tidy/android/CloexecMemfdCreateCheck.h
@@ -0,0 +1,35 @@
+//===--- CloexecMemfdCreateCheck.h -

[PATCH] D35743: [clang-format] Handle Structured binding declaration in C++17

2017-07-21 Thread Yan Wang via Phabricator via cfe-commits
yawanng created this revision.
yawanng added a project: clang-tools-extra.
Herald added a subscriber: klimek.

Add handling for Structured binding declaration in C++17 in clang-format. For 
example:
auto [x,y] = a; 
auto &[xr, yr] = a; 
auto &&[xrr, yrr] = a;


https://reviews.llvm.org/D35743

Files:
  lib/Format/TokenAnnotator.cpp
  lib/Format/UnwrappedLineParser.cpp
  test/Format/structured-binding-declaration.cpp

Index: test/Format/structured-binding-declaration.cpp
===
--- /dev/null
+++ test/Format/structured-binding-declaration.cpp
@@ -0,0 +1,54 @@
+// RUN: grep -Ev "// *[A-Z-]+:" %s | clang-format -style=LLVM \
+// RUN:   | FileCheck -strict-whitespace %s
+
+// CHECK: {{^auto\ \[x,\ y\]\ =\ a;}}
+auto[x, y] = a;
+// CHECK: {{^auto\ \&\[x,\ y\]\ =\ a;}}
+auto   &   [x, y] = a;
+// CHECK: {{^auto\ \&\&\[x,\ y\]\ =\ a;}}
+auto &&   [x, y] = a;
+
+// CHECK: {{^auto\ \[x\]\ =\ a;}}
+auto[x] = a;
+// CHECK: {{^auto\ \&\[x\]\ =\ a;}}
+auto   &   [x] = a;
+// CHECK: {{^auto\ \&\&\[x\]\ =\ a;}}
+auto &&   [x] = a;
+
+// CHECK: {{^const\ auto\ \[x,\ y\]\ =\ f\(\);}}
+const auto[x, y] = f();
+// CHECK: {{^const\ auto\ \&\[x,\ y\]\ =\ f\(\);}}
+const auto &   [x, y] = f();
+// CHECK: {{^const\ auto\ \&\&\[x,\ y\]\ =\ f\(\);}}
+const auto &&[x, y] = f();
+
+// CHECK: {{^auto\ \[x,\ y\]\ =\ A\{\};}}
+auto[x,y] = A{};
+// CHECK: {{^auto\ \&\[x,\ y\]\ =\ A\{\};}}
+auto   &   [x,y] = A{};
+// CHECK: {{^auto\ \&\&\[x,\ y\]\ =\ A\{\};}}
+auto   &&   [x,y] = A{};
+
+// CHECK: {{^for\ \(const\ auto\ \&\&\[a,\ b\]\ :\ some_range\)\ \{}}
+for (const auto   &&   [a, b] : some_range) {
+}
+// CHECK: {{^for\ \(const\ auto\ \&\[a,\ b\]\ :\ some_range\)\ \{}}
+for (const auto   &[a, b] : some_range) {
+}
+// CHECK: {{^for\ \(const\ auto\ \[a,\ b\]\ :\ some_range\)\ \{}}
+for (const auto[a, b] : some_range) {
+}
+
+// CHECK: {{^auto\ \[x,\ y\]\(expr\);}}
+auto[x,y]  (expr);
+// CHECK: {{^auto\ \&\[x,\ y\]\(expr\);}}
+auto   &   [x,y](expr);
+// CHECK: {{^auto\ \&\&\[x,\ y\]\(expr\);}}
+auto   &&   [x,y](expr);
+
+// CHECK: {{^auto\ \[x,\ y\]\{expr\};}}
+auto[x,y] {expr};
+// CHECK: {{^auto\ \&\[x,\ y\]\{expr\};}}
+auto   &   [x,y]  {expr};
+// CHECK: {{^auto\ \&\&\[x,\ y\]\{expr\};}}
+auto   &&   [x,y] {expr};
Index: lib/Format/UnwrappedLineParser.cpp
===
--- lib/Format/UnwrappedLineParser.cpp
+++ lib/Format/UnwrappedLineParser.cpp
@@ -1213,7 +1213,7 @@
   const FormatToken* Previous = getPreviousToken();
   if (Previous &&
   (Previous->isOneOf(tok::identifier, tok::kw_operator, tok::kw_new,
- tok::kw_delete) ||
+ tok::kw_delete, tok::kw_auto, tok::ampamp, tok::amp) ||
Previous->closesScope() || Previous->isSimpleTypeSpecifier())) {
 nextToken();
 return false;
Index: lib/Format/TokenAnnotator.cpp
===
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -330,8 +330,12 @@
 (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
  Contexts.back().InTemplateArgument);
 
+bool CppStructuredBindingDecl =
+!CppArrayTemplates && Style.isCpp() && Parent &&
+Parent->isOneOf(tok::kw_auto, tok::amp, tok::ampamp);
+
 bool StartsObjCMethodExpr =
-!CppArrayTemplates && Style.isCpp() &&
+!CppStructuredBindingDecl && !CppArrayTemplates && Style.isCpp() &&
 Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) &&
 CurrentToken->isNot(tok::l_brace) &&
 (!Parent ||
@@ -344,7 +348,10 @@
 
 unsigned BindingIncrease = 1;
 if (Left->is(TT_Unknown)) {
-  if (StartsObjCMethodExpr) {
+  if (CppStructuredBindingDecl) {
+Left->Type = Parent->is(tok::kw_auto) ? TT_DesignatedInitializerLSquare
+  : TT_ArraySubscriptLSquare;
+  } else if (StartsObjCMethodExpr) {
 Left->Type = TT_ObjCMethodExpr;
   } else if (Style.Language == FormatStyle::LK_JavaScript && Parent &&
  Contexts.back().ContextKind == tok::l_brace &&
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35372: [clang-tidy] Add a close-on-exec check on memfd_create() in Android module.

2017-07-24 Thread Yan Wang via Phabricator via cfe-commits
yawanng added a comment.

Ping


https://reviews.llvm.org/D35372



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D34114: [clang] A better format for unnecessary packed warning.

2017-07-26 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 108380.
yawanng edited the summary of this revision.
yawanng added a comment.

Change the condition of this unnecessary packed warning to when the alignment 
of the class is one byte. Remove all field-level warning.


https://reviews.llvm.org/D34114

Files:
  lib/AST/RecordLayoutBuilder.cpp
  test/CodeGenCXX/warn-padded-packed.cpp


Index: test/CodeGenCXX/warn-padded-packed.cpp
===
--- test/CodeGenCXX/warn-padded-packed.cpp
+++ test/CodeGenCXX/warn-padded-packed.cpp
@@ -17,7 +17,7 @@
 } __attribute__((packed));
 
 struct S4 {
-  int i; // expected-warning {{packed attribute is unnecessary for 'i'}}
+  int i;
   char c;
 } __attribute__((packed));
 
@@ -46,18 +46,18 @@
   int i; // expected-warning {{padding struct 'S8' with 3 bytes to align 'i'}}
 };
 
-struct S9 { // expected-warning {{packed attribute is unnecessary for 'S9'}}
-  int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
-  int y; // expected-warning {{packed attribute is unnecessary for 'y'}}
+struct S9 {
+  int x;
+  int y;
 } __attribute__((packed));
 
-struct S10 { // expected-warning {{packed attribute is unnecessary for 'S10'}}
-  int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
+struct S10 {
+  int x;
   char a,b,c,d;
 } __attribute__((packed));
 
 
-struct S11 {
+struct S11 { // expected-warning {{packed attribute is unnecessary for 'S11'}}
   bool x;
   char a,b,c,d;
 } __attribute__((packed));
@@ -72,5 +72,14 @@
   bool b : 10;
 };
 
+struct S14 { // expected-warning {{packed attribute is unnecessary for 'S14'}}
+  char a,b,c,d;
+} __attribute__((packed));
+
+struct S15 { // expected-warning {{packed attribute is unnecessary for 'S15'}}
+  struct S14 s;
+  char a;
+} __attribute__((packed));
+
 // The warnings are emitted when the layout of the structs is computed, so we 
have to use them.
-void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*) { }
+void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*, 
S14*, S15*) { }
Index: lib/AST/RecordLayoutBuilder.cpp
===
--- lib/AST/RecordLayoutBuilder.cpp
+++ lib/AST/RecordLayoutBuilder.cpp
@@ -1882,10 +1882,8 @@
   << (InBits ? 1 : 0); // (byte|bit)
 }
 
-// Warn if we packed it unnecessarily. If the alignment is 1 byte don't
-// bother since there won't be alignment issues.
-if (Packed && UnpackedAlignment > CharUnits::One() && 
-getSize() == UnpackedSize)
+// Warn if we packed it unnecessarily, when the alignment is 1 byte 
already.
+if (Packed && UnpackedAlignment == CharUnits::One())
   Diag(D->getLocation(), diag::warn_unnecessary_packed)
   << Context.getTypeDeclType(RD);
   }
@@ -1978,12 +1976,6 @@
   << PadSize
   << (InBits ? 1 : 0); // (byte|bit)
   }
-
-  // Warn if we packed it unnecessarily. If the alignment is 1 byte don't
-  // bother since there won't be alignment issues.
-  if (isPacked && UnpackedAlign > CharBitNum && Offset == UnpackedOffset)
-Diag(D->getLocation(), diag::warn_unnecessary_packed)
-<< D->getIdentifier();
 }
 
 static const CXXMethodDecl *computeKeyFunction(ASTContext &Context,


Index: test/CodeGenCXX/warn-padded-packed.cpp
===
--- test/CodeGenCXX/warn-padded-packed.cpp
+++ test/CodeGenCXX/warn-padded-packed.cpp
@@ -17,7 +17,7 @@
 } __attribute__((packed));
 
 struct S4 {
-  int i; // expected-warning {{packed attribute is unnecessary for 'i'}}
+  int i;
   char c;
 } __attribute__((packed));
 
@@ -46,18 +46,18 @@
   int i; // expected-warning {{padding struct 'S8' with 3 bytes to align 'i'}}
 };
 
-struct S9 { // expected-warning {{packed attribute is unnecessary for 'S9'}}
-  int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
-  int y; // expected-warning {{packed attribute is unnecessary for 'y'}}
+struct S9 {
+  int x;
+  int y;
 } __attribute__((packed));
 
-struct S10 { // expected-warning {{packed attribute is unnecessary for 'S10'}}
-  int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
+struct S10 {
+  int x;
   char a,b,c,d;
 } __attribute__((packed));
 
 
-struct S11 {
+struct S11 { // expected-warning {{packed attribute is unnecessary for 'S11'}}
   bool x;
   char a,b,c,d;
 } __attribute__((packed));
@@ -72,5 +72,14 @@
   bool b : 10;
 };
 
+struct S14 { // expected-warning {{packed attribute is unnecessary for 'S14'}}
+  char a,b,c,d;
+} __attribute__((packed));
+
+struct S15 { // expected-warning {{packed attribute is unnecessary for 'S15'}}
+  struct S14 s;
+  char a;
+} __attribute__((packed));
+
 // The warnings are emitted when the layout of the structs is computed, so we have to use them.
-void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*) { }
+void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*

[PATCH] D34114: [clang] A better format for unnecessary packed warning.

2017-07-26 Thread Yan Wang via Phabricator via cfe-commits
yawanng added a comment.

In https://reviews.llvm.org/D34114#800253, @rsmith wrote:

> Some concrete suggestions throughout the patch, but I think we should take a 
> step back and reconsider this warning approach: it seems bizarre for us to 
> warn on any packed struct that happens to contain a `char`. It would make 
> sense to warn if an `__attribute__((packed))` written in the source has *no* 
> effect (because it's applied to a struct where all fields already have 
> alignment 1, or because it's applied to a field that has alignment 1) -- even 
> then I'm not entirely convinced this is a valuable warning, but I assume 
> there's some reason you want to warn on it :)


Yes. I think the only case for this warning to be useful is when the alignment 
of the class or struct is 1 byte :-)


https://reviews.llvm.org/D34114



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D34114: [clang] Change the condition of unnecessary packed warning

2017-07-26 Thread Yan Wang via Phabricator via cfe-commits
yawanng added inline comments.



Comment at: lib/AST/RecordLayoutBuilder.cpp:1888
-if (Packed && UnpackedAlignment > CharUnits::One() && 
-getSize() == UnpackedSize)
   Diag(D->getLocation(), diag::warn_unnecessary_packed)

chh wrote:
> Why not keeping the (getSize() == UnpackedSize) condition?
> 
It seems to me that when the alignment is 1 byte, the size won't change.


https://reviews.llvm.org/D34114



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D34114: [clang] Change the condition of unnecessary packed warning

2017-07-26 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 108395.
yawanng edited the summary of this revision.
yawanng added a comment.

Including cases '__attribute__((packed, aligned(X)));'. When the alignment 
before packing is less or equal to the packed one, he 'packed' attribute not 
including 'aligned(X)' seems unnecessary.  Because the alignment won't change 
as well as the size after removing 'packed'.


https://reviews.llvm.org/D34114

Files:
  lib/AST/RecordLayoutBuilder.cpp
  test/CodeGenCXX/warn-padded-packed.cpp


Index: test/CodeGenCXX/warn-padded-packed.cpp
===
--- test/CodeGenCXX/warn-padded-packed.cpp
+++ test/CodeGenCXX/warn-padded-packed.cpp
@@ -17,7 +17,7 @@
 } __attribute__((packed));
 
 struct S4 {
-  int i; // expected-warning {{packed attribute is unnecessary for 'i'}}
+  int i;
   char c;
 } __attribute__((packed));
 
@@ -46,18 +46,18 @@
   int i; // expected-warning {{padding struct 'S8' with 3 bytes to align 'i'}}
 };
 
-struct S9 { // expected-warning {{packed attribute is unnecessary for 'S9'}}
-  int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
-  int y; // expected-warning {{packed attribute is unnecessary for 'y'}}
+struct S9 {
+  int x;
+  int y;
 } __attribute__((packed));
 
-struct S10 { // expected-warning {{packed attribute is unnecessary for 'S10'}}
-  int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
+struct S10 {
+  int x;
   char a,b,c,d;
 } __attribute__((packed));
 
 
-struct S11 {
+struct S11 { // expected-warning {{packed attribute is unnecessary for 'S11'}}
   bool x;
   char a,b,c,d;
 } __attribute__((packed));
@@ -72,5 +72,28 @@
   bool b : 10;
 };
 
+struct S14 { // expected-warning {{packed attribute is unnecessary for 'S14'}}
+  char a,b,c,d;
+} __attribute__((packed));
+
+struct S15 { // expected-warning {{packed attribute is unnecessary for 'S15'}}
+  struct S14 s;
+  char a;
+} __attribute__((packed));
+
+struct S16 { // expected-warning {{padding size of 'S16' with 2 bytes to 
alignment boundar}} expected-warning {{packed attribute is unnecessary for 
'S16'}}
+  char a,b;
+} __attribute__((packed, aligned(4)));
+
+struct S17 {
+  struct S16 s;
+  char a,b;
+} __attribute__((packed, aligned(2)));
+
+struct S18 { // expected-warning {{padding size of 'S18' with 2 bytes to 
alignment boundar}} expected-warning {{packed attribute is unnecessary for 
'S18'}}
+  struct S16 s;
+  char a,b;
+} __attribute__((packed, aligned(4)));
+
 // The warnings are emitted when the layout of the structs is computed, so we 
have to use them.
-void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*) { }
+void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*, 
S14*, S15*, S16*, S17*, S18*) { }
Index: lib/AST/RecordLayoutBuilder.cpp
===
--- lib/AST/RecordLayoutBuilder.cpp
+++ lib/AST/RecordLayoutBuilder.cpp
@@ -1882,10 +1882,9 @@
   << (InBits ? 1 : 0); // (byte|bit)
 }
 
-// Warn if we packed it unnecessarily. If the alignment is 1 byte don't
-// bother since there won't be alignment issues.
-if (Packed && UnpackedAlignment > CharUnits::One() && 
-getSize() == UnpackedSize)
+// Warn if we packed it unnecessarily, when the unpacked alignment is not
+// greater than the one after packing.
+if (Packed && UnpackedAlignment <= Alignment || )
   Diag(D->getLocation(), diag::warn_unnecessary_packed)
   << Context.getTypeDeclType(RD);
   }
@@ -1978,12 +1977,6 @@
   << PadSize
   << (InBits ? 1 : 0); // (byte|bit)
   }
-
-  // Warn if we packed it unnecessarily. If the alignment is 1 byte don't
-  // bother since there won't be alignment issues.
-  if (isPacked && UnpackedAlign > CharBitNum && Offset == UnpackedOffset)
-Diag(D->getLocation(), diag::warn_unnecessary_packed)
-<< D->getIdentifier();
 }
 
 static const CXXMethodDecl *computeKeyFunction(ASTContext &Context,


Index: test/CodeGenCXX/warn-padded-packed.cpp
===
--- test/CodeGenCXX/warn-padded-packed.cpp
+++ test/CodeGenCXX/warn-padded-packed.cpp
@@ -17,7 +17,7 @@
 } __attribute__((packed));
 
 struct S4 {
-  int i; // expected-warning {{packed attribute is unnecessary for 'i'}}
+  int i;
   char c;
 } __attribute__((packed));
 
@@ -46,18 +46,18 @@
   int i; // expected-warning {{padding struct 'S8' with 3 bytes to align 'i'}}
 };
 
-struct S9 { // expected-warning {{packed attribute is unnecessary for 'S9'}}
-  int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
-  int y; // expected-warning {{packed attribute is unnecessary for 'y'}}
+struct S9 {
+  int x;
+  int y;
 } __attribute__((packed));
 
-struct S10 { // expected-warning {{packed attribute is unnecessary for 'S10'}}
-  int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
+struct S10 {
+  int x;
  

[PATCH] D34114: [clang] Change the condition of unnecessary packed warning

2017-07-26 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 108397.

https://reviews.llvm.org/D34114

Files:
  lib/AST/RecordLayoutBuilder.cpp
  test/CodeGenCXX/warn-padded-packed.cpp


Index: test/CodeGenCXX/warn-padded-packed.cpp
===
--- test/CodeGenCXX/warn-padded-packed.cpp
+++ test/CodeGenCXX/warn-padded-packed.cpp
@@ -17,7 +17,7 @@
 } __attribute__((packed));
 
 struct S4 {
-  int i; // expected-warning {{packed attribute is unnecessary for 'i'}}
+  int i;
   char c;
 } __attribute__((packed));
 
@@ -46,18 +46,18 @@
   int i; // expected-warning {{padding struct 'S8' with 3 bytes to align 'i'}}
 };
 
-struct S9 { // expected-warning {{packed attribute is unnecessary for 'S9'}}
-  int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
-  int y; // expected-warning {{packed attribute is unnecessary for 'y'}}
+struct S9 {
+  int x;
+  int y;
 } __attribute__((packed));
 
-struct S10 { // expected-warning {{packed attribute is unnecessary for 'S10'}}
-  int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
+struct S10 {
+  int x;
   char a,b,c,d;
 } __attribute__((packed));
 
 
-struct S11 {
+struct S11 { // expected-warning {{packed attribute is unnecessary for 'S11'}}
   bool x;
   char a,b,c,d;
 } __attribute__((packed));
@@ -72,5 +72,28 @@
   bool b : 10;
 };
 
+struct S14 { // expected-warning {{packed attribute is unnecessary for 'S14'}}
+  char a,b,c,d;
+} __attribute__((packed));
+
+struct S15 { // expected-warning {{packed attribute is unnecessary for 'S15'}}
+  struct S14 s;
+  char a;
+} __attribute__((packed));
+
+struct S16 { // expected-warning {{padding size of 'S16' with 2 bytes to 
alignment boundar}} expected-warning {{packed attribute is unnecessary for 
'S16'}}
+  char a,b;
+} __attribute__((packed, aligned(4)));
+
+struct S17 {
+  struct S16 s;
+  char a,b;
+} __attribute__((packed, aligned(2)));
+
+struct S18 { // expected-warning {{padding size of 'S18' with 2 bytes to 
alignment boundar}} expected-warning {{packed attribute is unnecessary for 
'S18'}}
+  struct S16 s;
+  char a,b;
+} __attribute__((packed, aligned(4)));
+
 // The warnings are emitted when the layout of the structs is computed, so we 
have to use them.
-void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*) { }
+void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*, 
S14*, S15*, S16*, S17*, S18*) { }
Index: lib/AST/RecordLayoutBuilder.cpp
===
--- lib/AST/RecordLayoutBuilder.cpp
+++ lib/AST/RecordLayoutBuilder.cpp
@@ -1882,10 +1882,9 @@
   << (InBits ? 1 : 0); // (byte|bit)
 }
 
-// Warn if we packed it unnecessarily. If the alignment is 1 byte don't
-// bother since there won't be alignment issues.
-if (Packed && UnpackedAlignment > CharUnits::One() && 
-getSize() == UnpackedSize)
+// Warn if we packed it unnecessarily, when the unpacked alignment is not
+// greater than the one after packing.
+if (Packed && UnpackedAlignment <= Alignment)
   Diag(D->getLocation(), diag::warn_unnecessary_packed)
   << Context.getTypeDeclType(RD);
   }
@@ -1978,12 +1977,6 @@
   << PadSize
   << (InBits ? 1 : 0); // (byte|bit)
   }
-
-  // Warn if we packed it unnecessarily. If the alignment is 1 byte don't
-  // bother since there won't be alignment issues.
-  if (isPacked && UnpackedAlign > CharBitNum && Offset == UnpackedOffset)
-Diag(D->getLocation(), diag::warn_unnecessary_packed)
-<< D->getIdentifier();
 }
 
 static const CXXMethodDecl *computeKeyFunction(ASTContext &Context,


Index: test/CodeGenCXX/warn-padded-packed.cpp
===
--- test/CodeGenCXX/warn-padded-packed.cpp
+++ test/CodeGenCXX/warn-padded-packed.cpp
@@ -17,7 +17,7 @@
 } __attribute__((packed));
 
 struct S4 {
-  int i; // expected-warning {{packed attribute is unnecessary for 'i'}}
+  int i;
   char c;
 } __attribute__((packed));
 
@@ -46,18 +46,18 @@
   int i; // expected-warning {{padding struct 'S8' with 3 bytes to align 'i'}}
 };
 
-struct S9 { // expected-warning {{packed attribute is unnecessary for 'S9'}}
-  int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
-  int y; // expected-warning {{packed attribute is unnecessary for 'y'}}
+struct S9 {
+  int x;
+  int y;
 } __attribute__((packed));
 
-struct S10 { // expected-warning {{packed attribute is unnecessary for 'S10'}}
-  int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
+struct S10 {
+  int x;
   char a,b,c,d;
 } __attribute__((packed));
 
 
-struct S11 {
+struct S11 { // expected-warning {{packed attribute is unnecessary for 'S11'}}
   bool x;
   char a,b,c,d;
 } __attribute__((packed));
@@ -72,5 +72,28 @@
   bool b : 10;
 };
 
+struct S14 { // expected-warning {{packed attribute is unnecessary for 'S14'}}
+  char a,b,c,d;
+} __attribute__((p

[PATCH] D34114: [clang] Change the condition of unnecessary packed warning

2017-07-26 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 108401.
yawanng added a comment.

Add more tests.


https://reviews.llvm.org/D34114

Files:
  lib/AST/RecordLayoutBuilder.cpp
  test/CodeGenCXX/warn-padded-packed.cpp

Index: test/CodeGenCXX/warn-padded-packed.cpp
===
--- test/CodeGenCXX/warn-padded-packed.cpp
+++ test/CodeGenCXX/warn-padded-packed.cpp
@@ -17,7 +17,7 @@
 } __attribute__((packed));
 
 struct S4 {
-  int i; // expected-warning {{packed attribute is unnecessary for 'i'}}
+  int i;
   char c;
 } __attribute__((packed));
 
@@ -46,18 +46,18 @@
   int i; // expected-warning {{padding struct 'S8' with 3 bytes to align 'i'}}
 };
 
-struct S9 { // expected-warning {{packed attribute is unnecessary for 'S9'}}
-  int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
-  int y; // expected-warning {{packed attribute is unnecessary for 'y'}}
+struct S9 {
+  int x;
+  int y;
 } __attribute__((packed));
 
-struct S10 { // expected-warning {{packed attribute is unnecessary for 'S10'}}
-  int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
+struct S10 {
+  int x;
   char a,b,c,d;
 } __attribute__((packed));
 
 
-struct S11 {
+struct S11 { // expected-warning {{packed attribute is unnecessary for 'S11'}}
   bool x;
   char a,b,c,d;
 } __attribute__((packed));
@@ -72,5 +72,38 @@
   bool b : 10;
 };
 
+struct S14 { // expected-warning {{packed attribute is unnecessary for 'S14'}}
+  char a,b,c,d;
+} __attribute__((packed));
+
+struct S15 { // expected-warning {{packed attribute is unnecessary for 'S15'}}
+  struct S14 s;
+  char a;
+} __attribute__((packed));
+
+struct S16 { // expected-warning {{padding size of 'S16' with 2 bytes to alignment boundar}} expected-warning {{packed attribute is unnecessary for 'S16'}}
+  char a,b;
+} __attribute__((packed, aligned(4)));
+
+struct S17 {
+  struct S16 s;
+  char a,b;
+} __attribute__((packed, aligned(2)));
+
+struct S18 { // expected-warning {{padding size of 'S18' with 2 bytes to alignment boundar}} expected-warning {{packed attribute is unnecessary for 'S18'}}
+  struct S16 s;
+  char a,b;
+} __attribute__((packed, aligned(4)));
+
+struct S19 { // expected-warning {{packed attribute is unnecessary for 'S19'}}
+  bool b;
+  char a;
+} __attribute__((packed, aligned(1)));
+
+struct S20 {
+  int i;
+  char a;
+} __attribute__((packed, aligned(1)));
+
 // The warnings are emitted when the layout of the structs is computed, so we have to use them.
-void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*) { }
+void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*, S14*, S15*, S16*, S17*, S18*, S19*, S20*){}
Index: lib/AST/RecordLayoutBuilder.cpp
===
--- lib/AST/RecordLayoutBuilder.cpp
+++ lib/AST/RecordLayoutBuilder.cpp
@@ -1882,10 +1882,9 @@
   << (InBits ? 1 : 0); // (byte|bit)
 }
 
-// Warn if we packed it unnecessarily. If the alignment is 1 byte don't
-// bother since there won't be alignment issues.
-if (Packed && UnpackedAlignment > CharUnits::One() && 
-getSize() == UnpackedSize)
+// Warn if we packed it unnecessarily, when the unpacked alignment is not
+// greater than the one after packing.
+if (Packed && UnpackedAlignment <= Alignment)
   Diag(D->getLocation(), diag::warn_unnecessary_packed)
   << Context.getTypeDeclType(RD);
   }
@@ -1978,12 +1977,6 @@
   << PadSize
   << (InBits ? 1 : 0); // (byte|bit)
   }
-
-  // Warn if we packed it unnecessarily. If the alignment is 1 byte don't
-  // bother since there won't be alignment issues.
-  if (isPacked && UnpackedAlign > CharBitNum && Offset == UnpackedOffset)
-Diag(D->getLocation(), diag::warn_unnecessary_packed)
-<< D->getIdentifier();
 }
 
 static const CXXMethodDecl *computeKeyFunction(ASTContext &Context,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D34114: [clang] Change the condition of unnecessary packed warning

2017-07-27 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 108513.
yawanng marked 2 inline comments as done.
yawanng edited the summary of this revision.

https://reviews.llvm.org/D34114

Files:
  lib/AST/RecordLayoutBuilder.cpp
  test/CodeGenCXX/warn-padded-packed.cpp

Index: test/CodeGenCXX/warn-padded-packed.cpp
===
--- test/CodeGenCXX/warn-padded-packed.cpp
+++ test/CodeGenCXX/warn-padded-packed.cpp
@@ -17,7 +17,7 @@
 } __attribute__((packed));
 
 struct S4 {
-  int i; // expected-warning {{packed attribute is unnecessary for 'i'}}
+  int i;
   char c;
 } __attribute__((packed));
 
@@ -46,18 +46,18 @@
   int i; // expected-warning {{padding struct 'S8' with 3 bytes to align 'i'}}
 };
 
-struct S9 { // expected-warning {{packed attribute is unnecessary for 'S9'}}
-  int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
-  int y; // expected-warning {{packed attribute is unnecessary for 'y'}}
+struct S9 {
+  int x;
+  int y;
 } __attribute__((packed));
 
-struct S10 { // expected-warning {{packed attribute is unnecessary for 'S10'}}
-  int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
+struct S10 {
+  int x;
   char a,b,c,d;
 } __attribute__((packed));
 
 
-struct S11 {
+struct S11 { // expected-warning {{packed attribute is unnecessary for 'S11'}}
   bool x;
   char a,b,c,d;
 } __attribute__((packed));
@@ -72,5 +72,38 @@
   bool b : 10;
 };
 
+struct S14 { // expected-warning {{packed attribute is unnecessary for 'S14'}}
+  char a,b,c,d;
+} __attribute__((packed));
+
+struct S15 { // expected-warning {{packed attribute is unnecessary for 'S15'}}
+  struct S14 s;
+  char a;
+} __attribute__((packed));
+
+struct S16 { // expected-warning {{padding size of 'S16' with 2 bytes to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S16'}}
+  char a,b;
+} __attribute__((packed, aligned(4)));
+
+struct S17 {
+  struct S16 s;
+  char a,b;
+} __attribute__((packed, aligned(2)));
+
+struct S18 { // expected-warning {{padding size of 'S18' with 2 bytes to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S18'}}
+  struct S16 s;
+  char a,b;
+} __attribute__((packed, aligned(4)));
+
+struct S19 { // expected-warning {{packed attribute is unnecessary for 'S19'}}
+  bool b;
+  char a;
+} __attribute__((packed, aligned(1)));
+
+struct S20 {
+  int i;
+  char a;
+} __attribute__((packed, aligned(1)));
+
 // The warnings are emitted when the layout of the structs is computed, so we have to use them.
-void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*) { }
+void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*, S14*, S15*, S16*, S17*, S18*, S19*, S20*){}
Index: lib/AST/RecordLayoutBuilder.cpp
===
--- lib/AST/RecordLayoutBuilder.cpp
+++ lib/AST/RecordLayoutBuilder.cpp
@@ -1882,10 +1882,9 @@
   << (InBits ? 1 : 0); // (byte|bit)
 }
 
-// Warn if we packed it unnecessarily. If the alignment is 1 byte don't
-// bother since there won't be alignment issues.
-if (Packed && UnpackedAlignment > CharUnits::One() && 
-getSize() == UnpackedSize)
+// Warn if we packed it unnecessarily, when the unpacked alignment is not
+// greater than the one after packing.
+if (Packed && UnpackedAlignment <= Alignment)
   Diag(D->getLocation(), diag::warn_unnecessary_packed)
   << Context.getTypeDeclType(RD);
   }
@@ -1978,12 +1977,6 @@
   << PadSize
   << (InBits ? 1 : 0); // (byte|bit)
   }
-
-  // Warn if we packed it unnecessarily. If the alignment is 1 byte don't
-  // bother since there won't be alignment issues.
-  if (isPacked && UnpackedAlign > CharBitNum && Offset == UnpackedOffset)
-Diag(D->getLocation(), diag::warn_unnecessary_packed)
-<< D->getIdentifier();
 }
 
 static const CXXMethodDecl *computeKeyFunction(ASTContext &Context,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D34114: [clang] Change the condition of unnecessary packed warning

2017-07-27 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 108555.
yawanng marked an inline comment as done.
yawanng edited the summary of this revision.
yawanng added a comment.

Add more tests and restrict the conditions.


https://reviews.llvm.org/D34114

Files:
  lib/AST/RecordLayoutBuilder.cpp
  test/CodeGenCXX/warn-padded-packed.cpp

Index: test/CodeGenCXX/warn-padded-packed.cpp
===
--- test/CodeGenCXX/warn-padded-packed.cpp
+++ test/CodeGenCXX/warn-padded-packed.cpp
@@ -17,7 +17,7 @@
 } __attribute__((packed));
 
 struct S4 {
-  int i; // expected-warning {{packed attribute is unnecessary for 'i'}}
+  int i;
   char c;
 } __attribute__((packed));
 
@@ -46,18 +46,18 @@
   int i; // expected-warning {{padding struct 'S8' with 3 bytes to align 'i'}}
 };
 
-struct S9 { // expected-warning {{packed attribute is unnecessary for 'S9'}}
-  int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
-  int y; // expected-warning {{packed attribute is unnecessary for 'y'}}
+struct S9 {
+  int x;
+  int y;
 } __attribute__((packed));
 
-struct S10 { // expected-warning {{packed attribute is unnecessary for 'S10'}}
-  int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
+struct S10 {
+  int x;
   char a,b,c,d;
 } __attribute__((packed));
 
 
-struct S11 {
+struct S11 { // expected-warning {{packed attribute is unnecessary for 'S11'}}
   bool x;
   char a,b,c,d;
 } __attribute__((packed));
@@ -72,5 +72,81 @@
   bool b : 10;
 };
 
+struct S14 { // expected-warning {{packed attribute is unnecessary for 'S14'}}
+  char a,b,c,d;
+} __attribute__((packed));
+
+struct S15 { // expected-warning {{packed attribute is unnecessary for 'S15'}}
+  struct S14 s;
+  char a;
+} __attribute__((packed));
+
+struct S16 { // expected-warning {{padding size of 'S16' with 2 bytes to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S16'}}
+  char a,b;
+} __attribute__((packed, aligned(4)));
+
+struct S17 {
+  struct S16 s;
+  char a,b;
+} __attribute__((packed, aligned(2)));
+
+struct S18 { // expected-warning {{padding size of 'S18' with 2 bytes to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S18'}}
+  struct S16 s;
+  char a,b;
+} __attribute__((packed, aligned(4)));
+
+struct S19 { // expected-warning {{packed attribute is unnecessary for 'S19'}}
+  bool b;
+  char a;
+} __attribute__((packed, aligned(1)));
+
+struct S20 {
+  int i;
+  char a;
+} __attribute__((packed, aligned(1)));
+
+struct S21 { // expected-warning {{padding size of 'S21' with 4 bits to alignment boundary}}
+  unsigned char a : 6;
+  unsigned char b : 6;
+} __attribute__((packed, aligned(1)));
+
+struct S22 { // expected-warning {{packed attribute is unnecessary for 'S22'}}
+  unsigned char a : 4;
+  unsigned char b : 4;
+} __attribute__((packed));
+
+struct S23 { // expected-warning {{padding size of 'S23' with 4 bits to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S23'}}
+  unsigned char a : 2;
+  unsigned char b : 2;
+} __attribute__((packed));
+
+struct S24 {
+  unsigned char a : 6;
+  unsigned char b : 6;
+  unsigned char c : 6;
+  unsigned char d : 6;
+  unsigned char e : 6;
+  unsigned char f : 6;
+  unsigned char g : 6;
+  unsigned char h : 6;
+} __attribute__((packed));
+
+struct S25 { // expected-warning {{padding size of 'S25' with 7 bits to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S25'}}
+  unsigned char a;
+  unsigned char b : 1;
+} __attribute__((packed));
+
+struct S26 { // expected-warning {{packed attribute is unnecessary for 'S26'}}
+  unsigned char a : 1;
+  unsigned char b; //expected-warning {{padding struct 'S26' with 7 bits to align 'b'}}
+} __attribute__((packed));
+
+struct S27 { // expected-warning {{padding size of 'S27' with 7 bits to alignment boundary}}
+  unsigned char a : 1;
+  unsigned char b : 8;
+} __attribute__((packed));
+
+
 // The warnings are emitted when the layout of the structs is computed, so we have to use them.
-void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*) { }
+void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*, S14*, S15*,
+   S16*, S17*, S18*, S19*, S20*, S21*, S22*, S23*, S24*, S25*, S26*, S27*){}
Index: lib/AST/RecordLayoutBuilder.cpp
===
--- lib/AST/RecordLayoutBuilder.cpp
+++ lib/AST/RecordLayoutBuilder.cpp
@@ -632,6 +632,9 @@
   /// pointer, as opposed to inheriting one from a primary base class.
   bool HasOwnVFPtr;
 
+  /// \brief the flag of field offset changing due to packed attribute.
+  bool IsFieldOffsetChangedWithPacked;
+
   typedef llvm::DenseMap BaseOffsetsMapTy;
 
   /// Bases - base classes and their offsets in the record.
@@ -666,7 +669,7 @@
 NonVirtualSize(CharUnits::Zero()),
 NonVirtualAlignment(CharUnits::One()), PrimaryBase(nullptr),
 PrimaryBaseIsVi

[PATCH] D33103: [clang-tidy] TwineLocalCheck: add param # checking

2017-05-11 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 98684.

https://reviews.llvm.org/D33103

Files:
  clang-tidy/llvm/TwineLocalCheck.cpp
  test/clang-tidy/llvm-twine-local.cpp


Index: test/clang-tidy/llvm-twine-local.cpp
===
--- test/clang-tidy/llvm-twine-local.cpp
+++ test/clang-tidy/llvm-twine-local.cpp
@@ -5,6 +5,7 @@
 public:
   Twine(const char *);
   Twine(int);
+  Twine();
   Twine &operator+(const Twine &);
 };
 }
@@ -29,4 +30,10 @@
 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: twine variables are prone to 
use-after-free bugs
 // CHECK-MESSAGES: note: FIX-IT applied suggested code changes
 // CHECK-FIXES: const char * Prefix = false ? "__INT_FAST" : "__UINT_FAST";
+
+  const Twine t2 = Twine();
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to 
use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t2 = (Twine()).str();
+  foo(Twine() + "b");
 }
Index: clang-tidy/llvm/TwineLocalCheck.cpp
===
--- clang-tidy/llvm/TwineLocalCheck.cpp
+++ clang-tidy/llvm/TwineLocalCheck.cpp
@@ -35,8 +35,11 @@
 // of the initializer.
 const Expr *C = VD->getInit()->IgnoreImplicit();
 
-while (isa(C))
+while (isa(C)) {
+  if (cast(C)->getNumArgs() == 0)
+break;
   C = cast(C)->getArg(0)->IgnoreParenImpCasts();
+}
 
 SourceRange TypeRange =
 VD->getTypeSourceInfo()->getTypeLoc().getSourceRange();


Index: test/clang-tidy/llvm-twine-local.cpp
===
--- test/clang-tidy/llvm-twine-local.cpp
+++ test/clang-tidy/llvm-twine-local.cpp
@@ -5,6 +5,7 @@
 public:
   Twine(const char *);
   Twine(int);
+  Twine();
   Twine &operator+(const Twine &);
 };
 }
@@ -29,4 +30,10 @@
 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: twine variables are prone to use-after-free bugs
 // CHECK-MESSAGES: note: FIX-IT applied suggested code changes
 // CHECK-FIXES: const char * Prefix = false ? "__INT_FAST" : "__UINT_FAST";
+
+  const Twine t2 = Twine();
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t2 = (Twine()).str();
+  foo(Twine() + "b");
 }
Index: clang-tidy/llvm/TwineLocalCheck.cpp
===
--- clang-tidy/llvm/TwineLocalCheck.cpp
+++ clang-tidy/llvm/TwineLocalCheck.cpp
@@ -35,8 +35,11 @@
 // of the initializer.
 const Expr *C = VD->getInit()->IgnoreImplicit();
 
-while (isa(C))
+while (isa(C)) {
+  if (cast(C)->getNumArgs() == 0)
+break;
   C = cast(C)->getArg(0)->IgnoreParenImpCasts();
+}
 
 SourceRange TypeRange =
 VD->getTypeSourceInfo()->getTypeLoc().getSourceRange();
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33103: [clang-tidy] TwineLocalCheck: add param # checking

2017-05-11 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 98705.
yawanng added a comment.

Add more tests.


https://reviews.llvm.org/D33103

Files:
  clang-tidy/llvm/TwineLocalCheck.cpp
  test/clang-tidy/llvm-twine-local.cpp


Index: test/clang-tidy/llvm-twine-local.cpp
===
--- test/clang-tidy/llvm-twine-local.cpp
+++ test/clang-tidy/llvm-twine-local.cpp
@@ -5,6 +5,7 @@
 public:
   Twine(const char *);
   Twine(int);
+  Twine();
   Twine &operator+(const Twine &);
 };
 }
@@ -29,4 +30,35 @@
 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: twine variables are prone to 
use-after-free bugs
 // CHECK-MESSAGES: note: FIX-IT applied suggested code changes
 // CHECK-FIXES: const char * Prefix = false ? "__INT_FAST" : "__UINT_FAST";
+
+  const Twine t2 = Twine();
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to 
use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t2 = (Twine()).str();
+  foo(Twine() + "b");
+
+  const Twine t3 = Twine(42);
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to 
use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t3 = (Twine(42)).str();
+
+  const Twine t4 = Twine(42) + "b";
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to 
use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t4 = (Twine(42) + "b").str();
+
+  const Twine t5 = Twine() + "b";
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to 
use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t5 = (Twine() + "b").str();
+
+  const Twine t6 = true ? Twine() : Twine(42);
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to 
use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t6 = (true ? Twine() : Twine(42)).str();
+
+  const Twine t7 = false ? Twine() : Twine("b");
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to 
use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t7 = (false ? Twine() : Twine("b")).str();
 }
Index: clang-tidy/llvm/TwineLocalCheck.cpp
===
--- clang-tidy/llvm/TwineLocalCheck.cpp
+++ clang-tidy/llvm/TwineLocalCheck.cpp
@@ -35,8 +35,11 @@
 // of the initializer.
 const Expr *C = VD->getInit()->IgnoreImplicit();
 
-while (isa(C))
+while (isa(C)) {
+  if (cast(C)->getNumArgs() == 0)
+break;
   C = cast(C)->getArg(0)->IgnoreParenImpCasts();
+}
 
 SourceRange TypeRange =
 VD->getTypeSourceInfo()->getTypeLoc().getSourceRange();


Index: test/clang-tidy/llvm-twine-local.cpp
===
--- test/clang-tidy/llvm-twine-local.cpp
+++ test/clang-tidy/llvm-twine-local.cpp
@@ -5,6 +5,7 @@
 public:
   Twine(const char *);
   Twine(int);
+  Twine();
   Twine &operator+(const Twine &);
 };
 }
@@ -29,4 +30,35 @@
 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: twine variables are prone to use-after-free bugs
 // CHECK-MESSAGES: note: FIX-IT applied suggested code changes
 // CHECK-FIXES: const char * Prefix = false ? "__INT_FAST" : "__UINT_FAST";
+
+  const Twine t2 = Twine();
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t2 = (Twine()).str();
+  foo(Twine() + "b");
+
+  const Twine t3 = Twine(42);
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t3 = (Twine(42)).str();
+
+  const Twine t4 = Twine(42) + "b";
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t4 = (Twine(42) + "b").str();
+
+  const Twine t5 = Twine() + "b";
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t5 = (Twine() + "b").str();
+
+  const Twine t6 = true ? Twine() : Twine(42);
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t6 = (true ? Twine() : Twine(42)).str();
+
+  const Twine t7 = false ? Twine() : Twine("b");
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHE

[PATCH] D33304: [clang-tidy] Add a new module Android and a new check for file descriptors.

2017-05-17 Thread Yan Wang via Phabricator via cfe-commits
yawanng created this revision.
yawanng added a project: clang-tools-extra.
Herald added subscribers: krytarowski, xazax.hun, mgorny, srhines.

A common source of security bugs has been code that opens file descriptors 
without using the O_CLOEXEC flag.  (Without that flag, an opened sensitive file 
would remain open across a fork+exec to a lower-privileged SELinux domain, 
leaking that sensitive data.).

open(), openat(), and open64() must include O_CLOEXEC in their flags argument.


https://reviews.llvm.org/D33304

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/FileDescriptorCheck.cpp
  clang-tidy/android/FileDescriptorCheck.h
  clang-tidy/plugin/CMakeLists.txt
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  unittests/clang-tidy/CMakeLists.txt

Index: unittests/clang-tidy/CMakeLists.txt
===
--- unittests/clang-tidy/CMakeLists.txt
+++ unittests/clang-tidy/CMakeLists.txt
@@ -26,6 +26,7 @@
   clangLex
   clangTidy
   clangTidyGoogleModule
+  clangTidyAndroidModule
   clangTidyLLVMModule
   clangTidyMiscModule
   clangTidyReadabilityModule
Index: clang-tidy/tool/ClangTidyMain.cpp
===
--- clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tidy/tool/ClangTidyMain.cpp
@@ -477,6 +477,11 @@
 static int LLVM_ATTRIBUTE_UNUSED GoogleModuleAnchorDestination =
 GoogleModuleAnchorSource;
 
+// This anchor is used to force the linker to link the AndroidModule.
+extern volatile int AndroidModuleAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED AndroidModuleAnchorDestination =
+AndroidModuleAnchorSource;
+
 // This anchor is used to force the linker to link the MiscModule.
 extern volatile int MiscModuleAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED MiscModuleAnchorDestination =
Index: clang-tidy/tool/CMakeLists.txt
===
--- clang-tidy/tool/CMakeLists.txt
+++ clang-tidy/tool/CMakeLists.txt
@@ -17,6 +17,7 @@
   clangTidyCERTModule
   clangTidyCppCoreGuidelinesModule
   clangTidyGoogleModule
+  clangTidyAndroidModule
   clangTidyHICPPModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: clang-tidy/plugin/CMakeLists.txt
===
--- clang-tidy/plugin/CMakeLists.txt
+++ clang-tidy/plugin/CMakeLists.txt
@@ -12,6 +12,7 @@
   clangTidyCERTModule
   clangTidyCppCoreGuidelinesModule
   clangTidyGoogleModule
+  clangTidyAndroidModule
   clangTidyLLVMModule
   clangTidyMiscModule
   clangTidyModernizeModule
Index: clang-tidy/android/FileDescriptorCheck.h
===
--- clang-tidy/android/FileDescriptorCheck.h
+++ clang-tidy/android/FileDescriptorCheck.h
@@ -0,0 +1,46 @@
+//===--- FileDescriptorCheck.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_FILE_DESCRIPTOR_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_FILE_DESCRIPTOR_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace android {
+
+/// Finds code that opens file descriptors without using the O_CLOEXEC flag.
+///
+/// open(), openat(), and open64() must include O_CLOEXEC in their flags
+/// argument.
+/// Only consider simple cases that the corresponding argument is constant or binary
+/// operation OR among constants like 'O_CLOEXEC' or 'O_CLOEXEC | O_RDONLY'. No constant
+/// propagation is performed.
+///
+/// https://b.corp.google.com/issues/36664104
+
+class FileDescriptorCheck : public ClangTidyCheck {
+public:
+  FileDescriptorCheck(StringRef Name, ClangTidyContext *Context)
+  : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  bool checkFlags(const Expr *Flags);
+  bool checkFlag(const IntegerLiteral *Flag);
+private:
+  static constexpr const char *FLAG = "O_CLOEXEC";
+  static constexpr const char *HEADER_FILE = "fcntl.h";
+};
+
+} // namespace android
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_FILE_DESCRIPTOR_H
Index: clang-tidy/android/FileDescriptorCheck.cpp
===
--- clang-tidy/android/FileDescriptorCheck.cpp
+++ clang-tidy/android/FileDescriptorCheck.cpp
@@ -0,0 +1,101 @@
+//===--- FileDescriptorCheck.cpp - clang-tidy--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed und

[PATCH] D33304: [clang-tidy] Add a new module Android and a new check for file descriptors.

2017-05-17 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 99374.
yawanng added a comment.

Add unit test file.


https://reviews.llvm.org/D33304

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/FileDescriptorCheck.cpp
  clang-tidy/android/FileDescriptorCheck.h
  clang-tidy/plugin/CMakeLists.txt
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  test/clang-tidy/android-file-descriptor.cpp
  unittests/clang-tidy/CMakeLists.txt

Index: unittests/clang-tidy/CMakeLists.txt
===
--- unittests/clang-tidy/CMakeLists.txt
+++ unittests/clang-tidy/CMakeLists.txt
@@ -26,6 +26,7 @@
   clangLex
   clangTidy
   clangTidyGoogleModule
+  clangTidyAndroidModule
   clangTidyLLVMModule
   clangTidyMiscModule
   clangTidyReadabilityModule
Index: test/clang-tidy/android-file-descriptor.cpp
===
--- test/clang-tidy/android-file-descriptor.cpp
+++ test/clang-tidy/android-file-descriptor.cpp
@@ -0,0 +1,54 @@
+// RUN: %check_clang_tidy %s android-file-descriptor %t 
+
+#include 
+
+void a() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open(), openat(), and open64() must include O_CLOEXEC in their flags argument. [android-file-descriptor]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open(), openat(), and open64() must include O_CLOEXEC in their flags argument. [android-file-descriptor]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void b() {
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open(), openat(), and open64() must include O_CLOEXEC in their flags argument. [android-file-descriptor]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open64("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open(), openat(), and open64() must include O_CLOEXEC in their flags argument. [android-file-descriptor]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void c() {
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: open(), openat(), and open64() must include O_CLOEXEC in their flags argument. [android-file-descriptor]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  openat(0, "filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: open(), openat(), and open64() must include O_CLOEXEC in their flags argument. [android-file-descriptor]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+namespace i {
+  int open(const char *pathname, int flags){ return 0; }
+  int open(const char *pathname, int flags, mode_t mode) { return 0; }
+  int open64(const char *pathname, int flags){ return 0; }
+  int open64(const char *pathname, int flags, mode_t mode) { return 0; }
+  int openat(int dirfd, const char *pathname, int flags) { return 0; }
+  int openat(int dirfd, const char *pathname, int flags, mode_t mode) { return 0; }
+}
+
+void d() {
+  i::open("filename", O_RDWR);
+  i::open64("filename", O_RDWR);
+  i::openat(0, "filename", O_RDWR);
+}
+
+void e() {
+  open("filename", O_CLOEXEC);
+  open("filename", O_RDWR | O_CLOEXEC);
+  open64("filename", O_CLOEXEC);
+  open64("filename", O_RDWR | O_CLOEXEC);
+  openat(0, "filename", O_CLOEXEC);
+  openat(0, "filename", O_RDWR | O_CLOEXEC);
+}
Index: clang-tidy/tool/ClangTidyMain.cpp
===
--- clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tidy/tool/ClangTidyMain.cpp
@@ -477,6 +477,11 @@
 static int LLVM_ATTRIBUTE_UNUSED GoogleModuleAnchorDestination =
 GoogleModuleAnchorSource;
 
+// This anchor is used to force the linker to link the AndroidModule.
+extern volatile int AndroidModuleAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED AndroidModuleAnchorDestination =
+AndroidModuleAnchorSource;
+
 // This anchor is used to force the linker to link the MiscModule.
 extern volatile int MiscModuleAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED MiscModuleAnchorDestination =
Index: clang-tidy/tool/CMakeLists.txt
===
--- clang-tidy/tool/CMakeLists.txt
+++ clang-tidy/tool/CMakeLists.txt
@@ -17,6 +17,7 @@
   clangTidyCERTModule
   clangTidyCppCoreGuidelinesModule
   clangTidyGoogleModule
+  clangTidyAndroidModule
   clangTidyHICPPModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: clang-tidy/plugin/CMakeLists.txt
===
--- clang-tidy/plugin/CMakeLists.txt
+++ clang-tidy/plugin/CMakeLists.txt
@@ -12,6 +12,7 @@
   clangTidyCERTModule
   clangTidyCppCoreGuidelinesModule
   clangTidyGoogleModule
+  clangTidyAndroidModule
   clangTidyLLVMModule
   clangTidyMiscModule
   clangTidyModernizeModule
Index: clang-tidy/android/FileDescriptorCheck.h

[PATCH] D33304: [clang-tidy] Add a new module Android and a new check for file descriptors.

2017-05-18 Thread Yan Wang via Phabricator via cfe-commits
yawanng updated this revision to Diff 99447.

https://reviews.llvm.org/D33304

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/android/AndroidTidyModule.cpp
  clang-tidy/android/CMakeLists.txt
  clang-tidy/android/FileDescriptorCheck.cpp
  clang-tidy/android/FileDescriptorCheck.h
  clang-tidy/plugin/CMakeLists.txt
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  test/clang-tidy/android-file-descriptor.cpp
  unittests/clang-tidy/CMakeLists.txt

Index: unittests/clang-tidy/CMakeLists.txt
===
--- unittests/clang-tidy/CMakeLists.txt
+++ unittests/clang-tidy/CMakeLists.txt
@@ -26,6 +26,7 @@
   clangLex
   clangTidy
   clangTidyGoogleModule
+  clangTidyAndroidModule
   clangTidyLLVMModule
   clangTidyMiscModule
   clangTidyReadabilityModule
Index: test/clang-tidy/android-file-descriptor.cpp
===
--- test/clang-tidy/android-file-descriptor.cpp
+++ test/clang-tidy/android-file-descriptor.cpp
@@ -0,0 +1,54 @@
+// RUN: %check_clang_tidy %s android-file-descriptor %t
+
+#include 
+
+void a() {
+  open("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open must include O_CLOEXEC in their flags argument. [android-file-descriptor]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: open must include O_CLOEXEC in their flags argument. [android-file-descriptor]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void b() {
+  open64("filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 must include O_CLOEXEC in their flags argument. [android-file-descriptor]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  open64("filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: open64 must include O_CLOEXEC in their flags argument. [android-file-descriptor]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+void c() {
+  openat(0, "filename", O_RDWR);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat must include O_CLOEXEC in their flags argument. [android-file-descriptor]
+  // CHECK-FIXES: O_RDWR | O_CLOEXEC
+  openat(0, "filename", O_RDWR | O_EXCL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: openat must include O_CLOEXEC in their flags argument. [android-file-descriptor]
+  // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+}
+
+namespace i {
+int open(const char *pathname, int flags) { return 0; }
+int open(const char *pathname, int flags, mode_t mode) { return 0; }
+int open64(const char *pathname, int flags) { return 0; }
+int open64(const char *pathname, int flags, mode_t mode) { return 0; }
+int openat(int dirfd, const char *pathname, int flags) { return 0; }
+int openat(int dirfd, const char *pathname, int flags, mode_t mode) { return 0; }
+} // namespace i
+
+void d() {
+  i::open("filename", O_RDWR);
+  i::open64("filename", O_RDWR);
+  i::openat(0, "filename", O_RDWR);
+}
+
+void e() {
+  open("filename", O_CLOEXEC);
+  open("filename", O_RDWR | O_CLOEXEC);
+  open64("filename", O_CLOEXEC);
+  open64("filename", O_RDWR | O_CLOEXEC);
+  openat(0, "filename", O_CLOEXEC);
+  openat(0, "filename", O_RDWR | O_CLOEXEC);
+}
Index: clang-tidy/tool/ClangTidyMain.cpp
===
--- clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tidy/tool/ClangTidyMain.cpp
@@ -477,6 +477,11 @@
 static int LLVM_ATTRIBUTE_UNUSED GoogleModuleAnchorDestination =
 GoogleModuleAnchorSource;
 
+// This anchor is used to force the linker to link the AndroidModule.
+extern volatile int AndroidModuleAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED AndroidModuleAnchorDestination =
+AndroidModuleAnchorSource;
+
 // This anchor is used to force the linker to link the MiscModule.
 extern volatile int MiscModuleAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED MiscModuleAnchorDestination =
Index: clang-tidy/tool/CMakeLists.txt
===
--- clang-tidy/tool/CMakeLists.txt
+++ clang-tidy/tool/CMakeLists.txt
@@ -13,6 +13,7 @@
   clangASTMatchers
   clangBasic
   clangTidy
+  clangTidyAndroidModule
   clangTidyBoostModule
   clangTidyCERTModule
   clangTidyCppCoreGuidelinesModule
Index: clang-tidy/plugin/CMakeLists.txt
===
--- clang-tidy/plugin/CMakeLists.txt
+++ clang-tidy/plugin/CMakeLists.txt
@@ -8,6 +8,7 @@
   clangFrontend
   clangSema
   clangTidy
+  clangTidyAndroidModule
   clangTidyBoostModule
   clangTidyCERTModule
   clangTidyCppCoreGuidelinesModule
Index: clang-tidy/android/FileDescriptorCheck.h
===
--- clang-tidy/android/FileDescriptorCheck.h
+++ clang-tidy/android/FileDescriptorCheck.h
@@ -0,0 +1,45 @@
+//===--- FileDescriptorCheck.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infras

[PATCH] D33304: [clang-tidy] Add a new module Android and a new check for file descriptors.

2017-05-18 Thread Yan Wang via Phabricator via cfe-commits
yawanng marked an inline comment as done.
yawanng added inline comments.



Comment at: clang-tidy/android/FileDescriptorCheck.cpp:76
+int64_t val = aPInt.getSExtValue();
+if((val & O_CLOEXEC) == 0)
+  return false;

srhines wrote:
> Using O_CLOEXEC here is potentially a problem, since most of our compiles are 
> cross-compiles. If O_CLOEXEC is different on the target platform than the 
> host platform (where this code is being compiled), this check would fail. 
> Perhaps we can get the value of O_CLOEXEC as defined for the translation unit 
> (and if it isn't defined, that's already a pretty big indicator that any use 
> of these functions will be wrong). Alternately, maybe just re-parsing for 
> "O_CLOEXEC" is better.
I also think re-parsing is better. I will think about this and update soon. 


https://reviews.llvm.org/D33304



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33304: [WIP][clang-tidy] Add a new module Android and a new check for file descriptors.

2017-05-18 Thread Yan Wang via Phabricator via cfe-commits
yawanng added a comment.

In https://reviews.llvm.org/D33304#758871, @aaron.ballman wrote:

> In https://reviews.llvm.org/D33304#758808, @alexfh wrote:
>
> > In https://reviews.llvm.org/D33304#758713, @aaron.ballman wrote:
> >
> > > In https://reviews.llvm.org/D33304#758624, @srhines wrote:
> > >
> > > > In https://reviews.llvm.org/D33304#758621, @joerg wrote:
> > > >
> > > > > I find the use of "must" at the very least inappropriate. If there 
> > > > > was no use case for not including it, it wouldn't be an option. There 
> > > > > is also nothing really Android-specific here beside maybe the open64 
> > > > > mess.
> > > >
> > > >
> > > > On Android, we are requiring this flag. That is why this is part of a 
> > > > new category of Android-specific tidy rules. If you think this belongs 
> > > > more generally in a different category for tidy, can you suggest 
> > > > somewhere else to put it? We didn't want to impose these restrictions 
> > > > for platforms that might not want to be so strict. Also, as with any 
> > > > static analysis, there is the possibility that the original code author 
> > > > intended to "break" the rules, but that is what NOLINT is for.
> > >
> > >
> > > I'm not keen on putting this in an Android module either, as it's not 
> > > really Android-specific behavior. For instance, this is also part of a 
> > > recommended compliant solution for CERT FIO22-C.
> >
> >
> > I think AOSP has enough specific guidelines and requirements to warrant a 
> > separate module (especially, if Android folks have plans to contribute more 
> > than one check into it ;). As for this check, if the relevant requirements 
> > of CERT and Android are really identical, we could make an alias for the 
> > check in the CERT module (or vice versa). Another possibility that comes to 
> > mind is to create a new "posix" module specifically for things related to 
> > POSIX APIs (or "unix", if we want it to be slightly broader). WDYT?
>
>
> If there are plans to add more checks, then yes. However, I think I'd prefer 
> to see at least 2-3 checks in the work (or have some commitment for doing at 
> least that many checks) before we add a module for it. I mostly worry about 
> adding a single check and then nothing else. (No matter what module name 
> we're talking about, btw.) I'd be fine with android, posix, or unix, 
> depending on the nature of the checks.
>
> >> I think this should probably be in misc, or the bugprone module that 
> >> @alexfh has mentioned previously.
> > 
> > I'm strongly against bloating "misc" module. It's more or less the last 
> > resort, a place for checks we have found no better place for. The proposed 
> > "bugprone" module is an attempt to address this by pulling out a large part 
> > of "misc" to a place with more definite name and purpose. However, in the 
> > case of this check we seem to have enough good (and more specific) 
> > alternatives to default to "misc" or even "bugprone".
>
> I was hesitant to suggest misc, but I was hoping to avoid adding a module 
> with a single check under it and no commitment for further ones.


There are also two other requirements(not yet implemented). There will be more 
checks following up.


Repository:
  rL LLVM

https://reviews.llvm.org/D33304



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33304: [WIP][clang-tidy] Add a new module Android and a new check for file descriptors.

2017-05-22 Thread Yan Wang via Phabricator via cfe-commits
yawanng added a comment.

I will make some major changes to this CL based on the current suggestions from 
reviewers and update it for further review later. Thank you for the valuable 
advice.


Repository:
  rL LLVM

https://reviews.llvm.org/D33304



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits