[clang] 7dd2063 - Improve modeling of 'getcwd' in the StdLibraryFunctionsChecker (#77040)

via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 8 17:28:01 PST 2024


Author: Ben Shi
Date: 2024-01-09T09:27:57+08:00
New Revision: 7dd20637c801b429f2dd1040941d00141459d64e

URL: https://github.com/llvm/llvm-project/commit/7dd20637c801b429f2dd1040941d00141459d64e
DIFF: https://github.com/llvm/llvm-project/commit/7dd20637c801b429f2dd1040941d00141459d64e.diff

LOG: Improve modeling of 'getcwd' in the StdLibraryFunctionsChecker (#77040)

1. Improve the 'errno' modeling.
2. Improve constraints of the arguments.

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
    clang/test/Analysis/errno-stdlibraryfunctions.c

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c9b577bd549b1e..803eb2f7c74cf6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1150,9 +1150,10 @@ Improvements
 ^^^^^^^^^^^^
 
 - Improved the ``unix.StdCLibraryFunctions`` checker by modeling more
-  functions like ``send``, ``recv``, ``readlink``, ``fflush``, ``mkdtemp`` and
-  ``errno`` behavior.
+  functions like ``send``, ``recv``, ``readlink``, ``fflush``, ``mkdtemp``,
+  ``getcwd`` and ``errno`` behavior.
   (`52ac71f92d38 <https://github.com/llvm/llvm-project/commit/52ac71f92d38f75df5cb88e9c090ac5fd5a71548>`_,
+  `#77040 <https://github.com/llvm/llvm-project/pull/77040>`_,
   `#76671 <https://github.com/llvm/llvm-project/pull/76671>`_,
   `#71373 <https://github.com/llvm/llvm-project/pull/71373>`_,
   `#76557 <https://github.com/llvm/llvm-project/pull/76557>`_,

diff  --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index 20068653d530a3..034825d88a44de 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -2516,10 +2516,21 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
             .ArgConstraint(NotNull(ArgNo(0))));
 
     // char *getcwd(char *buf, size_t size);
-    // FIXME: Improve for errno modeling.
     addToFunctionSummaryMap(
         "getcwd", Signature(ArgTypes{CharPtrTy, SizeTy}, RetType{CharPtrTy}),
         Summary(NoEvalCall)
+            .Case({ArgumentCondition(1, WithinRange, Range(1, SizeMax)),
+                   ReturnValueCondition(BO_EQ, ArgNo(0))},
+                  ErrnoMustNotBeChecked, GenericSuccessMsg)
+            .Case({ArgumentCondition(1, WithinRange, SingleValue(0)),
+                   IsNull(Ret)},
+                  ErrnoNEZeroIrrelevant, "Assuming that argument 'size' is 0")
+            .Case({ArgumentCondition(1, WithinRange, Range(1, SizeMax)),
+                   IsNull(Ret)},
+                  ErrnoNEZeroIrrelevant, GenericFailureMsg)
+            .ArgConstraint(NotNull(ArgNo(0)))
+            .ArgConstraint(
+                BufferSize(/*Buffer*/ ArgNo(0), /*BufSize*/ ArgNo(1)))
             .ArgConstraint(
                 ArgumentCondition(1, WithinRange, Range(0, SizeMax))));
 

diff  --git a/clang/test/Analysis/errno-stdlibraryfunctions.c b/clang/test/Analysis/errno-stdlibraryfunctions.c
index 80e14c4e2923ca..9e3d07e7aa88a0 100644
--- a/clang/test/Analysis/errno-stdlibraryfunctions.c
+++ b/clang/test/Analysis/errno-stdlibraryfunctions.c
@@ -74,3 +74,18 @@ void errno_mkdtemp(char *template) {
     if (errno) {}                         // expected-warning{{An undefined value may be read from 'errno'}}
   }
 }
+
+void errno_getcwd(char *Buf, size_t Sz) {
+  char *Path = getcwd(Buf, Sz);
+  if (Sz == 0) {
+    clang_analyzer_eval(errno != 0);   // expected-warning{{TRUE}}
+    clang_analyzer_eval(Path == NULL); // expected-warning{{TRUE}}
+    if (errno) {}                      // no warning
+  } else if (Path == NULL) {
+    clang_analyzer_eval(errno != 0);   // expected-warning{{TRUE}}
+    if (errno) {}                      // no warning
+  } else {
+    clang_analyzer_eval(Path == Buf);  // expected-warning{{TRUE}}
+    if (errno) {}                      // expected-warning{{An undefined value may be read from 'errno'}}
+  }
+}


        


More information about the cfe-commits mailing list