martong created this revision.
martong added reviewers: Szelethus, gamesh411, balazske.
Herald added subscribers: cfe-commits, ASDenysPetrov, steakhal, Charusso, 
dkrupp, donat.nagy, mikhail.ramalho, a.sidorin, rnkovacs, szepet, 
baloghadamsoftware, xazax.hun, whisperity.
Herald added a project: clang.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84415

Files:
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/std-c-library-functions-POSIX.c

Index: clang/test/Analysis/std-c-library-functions-POSIX.c
===================================================================
--- clang/test/Analysis/std-c-library-functions-POSIX.c
+++ clang/test/Analysis/std-c-library-functions-POSIX.c
@@ -95,6 +95,20 @@
 // CHECK: Loaded summary for: ssize_t send(int sockfd, const void *buf, size_t len, int flags)
 // CHECK: Loaded summary for: int socketpair(int domain, int type, int protocol, int sv[2])
 // CHECK: Loaded summary for: int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen, char *restrict node, socklen_t nodelen, char *restrict service, socklen_t servicelen, int flags)
+// CHECK: Loaded summary for: int pthread_cond_signal(pthread_cond_t *cond)
+// CHECK: Loaded summary for: int pthread_cond_broadcast(pthread_cond_t *cond)
+// CHECK: Loaded summary for: int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void *), void *restrict arg)
+// CHECK: Loaded summary for: int pthread_attr_destroy(pthread_attr_t *attr)
+// CHECK: Loaded summary for: int pthread_attr_init(pthread_attr_t *attr)
+// CHECK: Loaded summary for: int pthread_attr_getstacksize(const pthread_attr_t *restrict attr, size_t *restrict stacksize)
+// CHECK: Loaded summary for: int pthread_attr_getguardsize(const pthread_attr_t *restrict attr, size_t *restrict guardsize)
+// CHECK: Loaded summary for: int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
+// CHECK: Loaded summary for: int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
+// CHECK: Loaded summary for: int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr)
+// CHECK: Loaded summary for: int pthread_mutex_destroy(pthread_mutex_t *mutex)
+// CHECK: Loaded summary for: int pthread_mutex_lock(pthread_mutex_t *mutex)
+// CHECK: Loaded summary for: int pthread_mutex_trylock(pthread_mutex_t *mutex)
+// CHECK: Loaded summary for: int pthread_mutex_unlock(pthread_mutex_t *mutex)
 
 long a64l(const char *str64);
 char *l64a(long value);
@@ -227,6 +241,26 @@
 int socketpair(int domain, int type, int protocol, int sv[2]);
 int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen, char *restrict node, socklen_t nodelen, char *restrict service, socklen_t servicelen, int flags);
 
+typedef union { int x; } pthread_cond_t;
+int pthread_cond_signal(pthread_cond_t *cond);
+int pthread_cond_broadcast(pthread_cond_t *cond);
+typedef union { int x; } pthread_attr_t;
+typedef unsigned long int pthread_t;
+int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void *), void *restrict arg);
+int pthread_attr_destroy(pthread_attr_t *attr);
+int pthread_attr_init(pthread_attr_t *attr);
+int pthread_attr_getstacksize(const pthread_attr_t *restrict attr, size_t *restrict stacksize);
+int pthread_attr_getguardsize(const pthread_attr_t *restrict attr, size_t *restrict guardsize);
+int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
+int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
+typedef union { int x; } pthread_mutex_t;
+typedef union { int x; } pthread_mutexattr_t;
+int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
+int pthread_mutex_destroy(pthread_mutex_t *mutex);
+int pthread_mutex_lock(pthread_mutex_t *mutex);
+int pthread_mutex_trylock(pthread_mutex_t *mutex);
+int pthread_mutex_unlock(pthread_mutex_t *mutex);
+
 // Must have at least one call expression to initialize the summary map.
 int bar(void);
 void foo() {
Index: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -812,6 +812,8 @@
   const QualType ConstWchar_tPtrTy =
       ACtx.getPointerType(ACtx.WCharTy.withConst()); // const wchar_t *
   const QualType ConstVoidPtrRestrictTy = getRestrictTy(ConstVoidPtrTy);
+  const QualType SizePtrTy = ACtx.getPointerType(SizeTy);
+  const QualType SizePtrRestrictTy = getRestrictTy(SizePtrTy);
 
   const RangeInt IntMax = BVF.getMaxValue(IntTy).getLimitedValue();
   const RangeInt UnsignedIntMax =
@@ -883,6 +885,11 @@
       for (const Summary &S : Summaries)
         operator()(Name, S);
     }
+    // Add the same summary for different names.
+    void operator()(std::vector<StringRef> Names, Summary S) {
+      for (StringRef Name : Names)
+        operator()(Name, S);
+    }
   } addToFunctionSummaryMap(ACtx, FunctionSummaryMap, DisplayLoadedSummaries);
 
   // We are finally ready to define specifications for all supported functions.
@@ -1986,6 +1993,126 @@
                   BufferSize(/*Buffer=*/ArgNo(4), /*BufSize=*/ArgNo(5)))
               .ArgConstraint(
                   ArgumentCondition(5, WithinRange, Range(0, *Socklen_tMax))));
+
+    Optional<QualType> Pthread_cond_tTy = lookupType("pthread_cond_t", ACtx);
+    Optional<QualType> Pthread_cond_tPtrTy;
+    if (Pthread_cond_tTy)
+      Pthread_cond_tPtrTy = ACtx.getPointerType(*Pthread_cond_tTy);
+
+    if (Pthread_cond_tPtrTy)
+      // int pthread_cond_signal(pthread_cond_t *cond);
+      // int pthread_cond_broadcast(pthread_cond_t *cond);
+      addToFunctionSummaryMap(
+          {"pthread_cond_signal", "pthread_cond_broadcast"},
+          Summary(ArgTypes{*Pthread_cond_tPtrTy}, RetType{IntTy}, NoEvalCall)
+              .ArgConstraint(NotNull(ArgNo(0))));
+
+    Optional<QualType> Pthread_tTy = lookupType("pthread_t", ACtx);
+    Optional<QualType> Pthread_tPtrTy, Pthread_tPtrRestrictTy;
+    if (Pthread_tTy) {
+      Pthread_tPtrTy = ACtx.getPointerType(*Pthread_tTy);
+      Pthread_tPtrRestrictTy = getRestrictTy(*Pthread_tPtrTy);
+    }
+
+    Optional<QualType> Pthread_mutex_tTy = lookupType("pthread_mutex_t", ACtx);
+    Optional<QualType> Pthread_mutex_tPtrTy, Pthread_mutex_tPtrRestrictTy;
+    if (Pthread_mutex_tTy) {
+      Pthread_mutex_tPtrTy = ACtx.getPointerType(*Pthread_mutex_tTy);
+      Pthread_mutex_tPtrRestrictTy = getRestrictTy(*Pthread_mutex_tPtrTy);
+    }
+
+    Optional<QualType> Pthread_attr_tTy = lookupType("pthread_attr_t", ACtx);
+    Optional<QualType> Pthread_attr_tPtrTy, ConstPthread_attr_tPtrTy,
+        ConstPthread_attr_tPtrRestrictTy;
+    if (Pthread_attr_tTy) {
+      Pthread_attr_tPtrTy = ACtx.getPointerType(*Pthread_attr_tTy);
+      ConstPthread_attr_tPtrTy =
+          ACtx.getPointerType(Pthread_attr_tTy->withConst());
+      ConstPthread_attr_tPtrRestrictTy =
+          getRestrictTy(*ConstPthread_attr_tPtrTy);
+    }
+
+    Optional<QualType> Pthread_mutexattr_tTy =
+        lookupType("pthread_mutexattr_t", ACtx);
+    Optional<QualType> Pthread_mutexattr_tPtrTy, ConstPthread_mutexattr_tPtrTy,
+        ConstPthread_mutexattr_tPtrRestrictTy;
+    if (Pthread_mutexattr_tTy) {
+      Pthread_mutexattr_tPtrTy = ACtx.getPointerType(*Pthread_mutexattr_tTy);
+      ConstPthread_mutexattr_tPtrTy =
+          ACtx.getPointerType(Pthread_mutexattr_tTy->withConst());
+      ConstPthread_mutexattr_tPtrRestrictTy =
+          getRestrictTy(*ConstPthread_mutexattr_tPtrTy);
+    }
+
+    QualType PthreadStartRoutineTy = ACtx.getPointerType(
+        ACtx.getFunctionType(/*ResultTy=*/VoidPtrTy, /*Args=*/VoidPtrTy,
+                             FunctionProtoType::ExtProtoInfo()));
+
+    if (Pthread_tPtrRestrictTy && ConstPthread_attr_tPtrRestrictTy)
+      // int pthread_create(pthread_t *restrict thread,
+      //                    const pthread_attr_t *restrict attr,
+      //                    void *(*start_routine)(void*), void *restrict arg);
+      addToFunctionSummaryMap(
+          "pthread_create",
+          Summary(ArgTypes{*Pthread_tPtrRestrictTy,
+                           *ConstPthread_attr_tPtrRestrictTy,
+                           PthreadStartRoutineTy, VoidPtrRestrictTy},
+                  RetType{IntTy}, NoEvalCall)
+              .ArgConstraint(NotNull(ArgNo(0)))
+              .ArgConstraint(NotNull(ArgNo(2))));
+
+    if (Pthread_attr_tPtrTy)
+      // int pthread_attr_destroy(pthread_attr_t *attr);
+      // int pthread_attr_init(pthread_attr_t *attr);
+      addToFunctionSummaryMap(
+          {"pthread_attr_destroy", "pthread_attr_init"},
+          Summary(ArgTypes{*Pthread_attr_tPtrTy}, RetType{IntTy}, NoEvalCall)
+              .ArgConstraint(NotNull(ArgNo(0))));
+
+    if (ConstPthread_attr_tPtrRestrictTy)
+      // int pthread_attr_getstacksize(const pthread_attr_t *restrict attr,
+      //                               size_t *restrict stacksize);
+      // int pthread_attr_getguardsize(const pthread_attr_t *restrict attr,
+      //                               size_t *restrict guardsize);
+      addToFunctionSummaryMap(
+          {"pthread_attr_getstacksize", "pthread_attr_getguardsize"},
+          Summary(
+              ArgTypes{*ConstPthread_attr_tPtrRestrictTy, SizePtrRestrictTy},
+              RetType{IntTy}, NoEvalCall)
+              .ArgConstraint(NotNull(ArgNo(0)))
+              .ArgConstraint(NotNull(ArgNo(1))));
+
+    if (Pthread_attr_tPtrTy)
+      // int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
+      // int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
+      addToFunctionSummaryMap(
+          {"pthread_attr_setstacksize", "pthread_attr_setguardsize"},
+          Summary(ArgTypes{*Pthread_attr_tPtrTy, SizeTy}, RetType{IntTy},
+                  NoEvalCall)
+              .ArgConstraint(NotNull(ArgNo(0)))
+              .ArgConstraint(
+                  ArgumentCondition(1, WithinRange, Range(0, SizeMax))));
+
+    if (Pthread_mutex_tPtrRestrictTy && ConstPthread_mutexattr_tPtrRestrictTy)
+      // int pthread_mutex_init(pthread_mutex_t *restrict mutex, const
+      //                        pthread_mutexattr_t *restrict attr);
+      addToFunctionSummaryMap(
+          "pthread_mutex_init",
+          Summary(ArgTypes{*Pthread_mutex_tPtrRestrictTy,
+                           *ConstPthread_mutexattr_tPtrRestrictTy},
+                  RetType{IntTy}, NoEvalCall)
+              .ArgConstraint(NotNull(ArgNo(0))));
+
+    if (Pthread_mutex_tPtrTy)
+      // int pthread_mutex_destroy(pthread_mutex_t *mutex);
+      // int pthread_mutex_lock(pthread_mutex_t *mutex);
+      // int pthread_mutex_trylock(pthread_mutex_t *mutex);
+      // int pthread_mutex_unlock(pthread_mutex_t *mutex);
+      addToFunctionSummaryMap(
+          {"pthread_mutex_destroy", "pthread_mutex_lock",
+           "pthread_mutex_trylock", "pthread_mutex_unlock"},
+          Summary(ArgTypes{*Pthread_mutex_tPtrTy}, RetType{IntTy}, NoEvalCall)
+              .ArgConstraint(NotNull(ArgNo(0))));
   }
 
   // Functions for testing.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to