r290023 - [analyzer] UnixAPIChecker: Don't diagnose for functions in C++ namespaces

Devin Coughlin via cfe-commits cfe-commits at lists.llvm.org
Fri Dec 16 17:08:18 PST 2016


Author: dcoughlin
Date: Fri Dec 16 19:08:17 2016
New Revision: 290023

URL: http://llvm.org/viewvc/llvm-project?rev=290023&view=rev
Log:
[analyzer] UnixAPIChecker: Don't diagnose for functions in C++ namespaces

Update the UnixAPIChecker to not diagnose for calls to functions that
are declared in C++ namespaces. This avoids false positives when a
namespaced function has the same name as a Unix API.

This address PR28331.

Added:
    cfe/trunk/test/Analysis/unix-api.cpp
Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp?rev=290023&r1=290022&r2=290023&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp Fri Dec 16 19:08:17 2016
@@ -427,6 +427,12 @@ void UnixAPIChecker::checkPreStmt(const
   if (!FD || FD->getKind() != Decl::Function)
     return;
 
+  // Don't treat functions in namespaces with the same name a Unix function
+  // as a call to the Unix function.
+  const DeclContext *NamespaceCtx = FD->getEnclosingNamespaceContext();
+  if (NamespaceCtx && isa<NamespaceDecl>(NamespaceCtx))
+    return;
+
   StringRef FName = C.getCalleeName(FD);
   if (FName.empty())
     return;

Added: cfe/trunk/test/Analysis/unix-api.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/unix-api.cpp?rev=290023&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/unix-api.cpp (added)
+++ cfe/trunk/test/Analysis/unix-api.cpp Fri Dec 16 19:08:17 2016
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.API -verify %s
+extern "C" {
+#ifndef O_RDONLY
+#define O_RDONLY 0
+#endif
+
+#ifndef NULL
+#define NULL ((void*) 0)
+#endif
+
+int open(const char *, int, ...);
+int close(int fildes);
+
+} // extern "C"
+
+namespace MyNameSpace {
+int open(const char *a, int b, int c, int d);
+}
+
+void unix_open(const char *path) {
+  int fd;
+  fd = open(path, O_RDONLY); // no-warning
+  if (fd > -1)
+    close(fd);
+}
+
+void unix_open_misuse(const char *path) {
+  int fd;
+  int mode = 0x0;
+  fd = open(path, O_RDONLY, mode, NULL); // expected-warning{{Call to 'open' with more than 3 arguments}}
+  if (fd > -1)
+    close(fd);
+}
+
+// Don't treat open() in namespaces as the POSIX open()
+void namespaced_open(const char *path) {
+  MyNameSpace::open("Hi", 2, 3, 4); // no-warning
+
+  using namespace MyNameSpace;
+
+  open("Hi", 2, 3, 4); // no-warning
+
+  int fd;
+  int mode = 0x0;
+  fd = ::open(path, O_RDONLY, mode, NULL); // expected-warning{{Call to 'open' with more than 3 arguments}}
+  if (fd > -1)
+    close(fd);
+}
+
+class MyClass {
+public:
+  static int open(const char *a, int b, int c, int d);
+
+  int open(int a, int, int c, int d);
+};
+
+void class_qualified_open() {
+  MyClass::open("Hi", 2, 3, 4); // no-warning
+
+  MyClass mc;
+  mc.open(1, 2, 3, 4); // no-warning
+}




More information about the cfe-commits mailing list