This revision was automatically updated to reflect the committed changes.
Closed by commit rG25bbe234e4e7: [analyzer] StdLibraryFunctionsChecker: Add 
support for new functions (authored by zukatsinadze).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85093/new/

https://reviews.llvm.org/D85093

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

Index: clang/test/Analysis/std-c-library-functions-arg-constraints.c
===================================================================
--- clang/test/Analysis/std-c-library-functions-arg-constraints.c
+++ clang/test/Analysis/std-c-library-functions-arg-constraints.c
@@ -45,7 +45,6 @@
   // bugpath-note{{TRUE}} \
   // bugpath-note{{Left side of '&&' is true}} \
   // bugpath-note{{'x' is <= 255}}
-
 }
 
 void test_alnum_symbolic2(int x) {
@@ -62,6 +61,114 @@
   }
 }
 
+int toupper(int);
+
+void test_toupper_concrete(int v) {
+  int ret = toupper(256); // \
+  // report-warning{{Function argument constraint is not satisfied}} \
+  // bugpath-warning{{Function argument constraint is not satisfied}} \
+  // bugpath-note{{Function argument constraint is not satisfied}}
+  (void)ret;
+}
+
+void test_toupper_symbolic(int x) {
+  int ret = toupper(x);
+  (void)ret;
+
+  clang_analyzer_eval(EOF <= x && x <= 255); // \
+  // report-warning{{TRUE}} \
+  // bugpath-warning{{TRUE}} \
+  // bugpath-note{{TRUE}} \
+  // bugpath-note{{Left side of '&&' is true}} \
+  // bugpath-note{{'x' is <= 255}}
+}
+
+void test_toupper_symbolic2(int x) {
+  if (x > 255) { // \
+    // bugpath-note{{Assuming 'x' is > 255}} \
+    // bugpath-note{{Taking true branch}}
+
+    int ret = toupper(x); // \
+    // report-warning{{Function argument constraint is not satisfied}} \
+    // bugpath-warning{{Function argument constraint is not satisfied}} \
+    // bugpath-note{{Function argument constraint is not satisfied}}
+
+    (void)ret;
+  }
+}
+
+int tolower(int);
+
+void test_tolower_concrete(int v) {
+  int ret = tolower(256); // \
+  // report-warning{{Function argument constraint is not satisfied}} \
+  // bugpath-warning{{Function argument constraint is not satisfied}} \
+  // bugpath-note{{Function argument constraint is not satisfied}}
+  (void)ret;
+}
+
+void test_tolower_symbolic(int x) {
+  int ret = tolower(x);
+  (void)ret;
+
+  clang_analyzer_eval(EOF <= x && x <= 255); // \
+  // report-warning{{TRUE}} \
+  // bugpath-warning{{TRUE}} \
+  // bugpath-note{{TRUE}} \
+  // bugpath-note{{Left side of '&&' is true}} \
+  // bugpath-note{{'x' is <= 255}}
+}
+
+void test_tolower_symbolic2(int x) {
+  if (x > 255) { // \
+    // bugpath-note{{Assuming 'x' is > 255}} \
+    // bugpath-note{{Taking true branch}}
+
+    int ret = tolower(x); // \
+    // report-warning{{Function argument constraint is not satisfied}} \
+    // bugpath-warning{{Function argument constraint is not satisfied}} \
+    // bugpath-note{{Function argument constraint is not satisfied}}
+
+    (void)ret;
+  }
+}
+
+int toascii(int);
+
+void test_toascii_concrete(int v) {
+  int ret = toascii(256); // \
+  // report-warning{{Function argument constraint is not satisfied}} \
+  // bugpath-warning{{Function argument constraint is not satisfied}} \
+  // bugpath-note{{Function argument constraint is not satisfied}}
+  (void)ret;
+}
+
+void test_toascii_symbolic(int x) {
+  int ret = toascii(x);
+  (void)ret;
+
+  clang_analyzer_eval(EOF <= x && x <= 255); // \
+  // report-warning{{TRUE}} \
+  // bugpath-warning{{TRUE}} \
+  // bugpath-note{{TRUE}} \
+  // bugpath-note{{Left side of '&&' is true}} \
+  // bugpath-note{{'x' is <= 255}}
+}
+
+void test_toascii_symbolic2(int x) {
+  if (x > 255) { // \
+    // bugpath-note{{Assuming 'x' is > 255}} \
+    // bugpath-note{{Taking true branch}}
+
+    int ret = toascii(x); // \
+    // report-warning{{Function argument constraint is not satisfied}} \
+    // bugpath-warning{{Function argument constraint is not satisfied}} \
+    // bugpath-note{{Function argument constraint is not satisfied}}
+
+    (void)ret;
+  }
+}
+
 typedef struct FILE FILE;
 typedef typeof(sizeof(int)) size_t;
 size_t fread(void *restrict, size_t, size_t, FILE *restrict);
@@ -80,7 +187,7 @@
   // bugpath-note{{'buf' is not equal to null}}
 }
 void test_notnull_symbolic2(FILE *fp, int *buf) {
-  if (!buf) // bugpath-note{{Assuming 'buf' is null}} \
+  if (!buf)                          // bugpath-note{{Assuming 'buf' is null}} \
             // bugpath-note{{Taking true branch}}
     fread(buf, sizeof(int), 10, fp); // \
     // report-warning{{Function argument constraint is not satisfied}} \
@@ -151,7 +258,7 @@
 }
 int __buf_size_arg_constraint_mul(const void *, size_t, size_t);
 void test_buf_size_concrete_with_multiplication() {
-  short buf[3];         // bugpath-note{{'buf' initialized here}}
+  short buf[3];                                         // bugpath-note{{'buf' initialized here}}
   __buf_size_arg_constraint_mul(buf, 4, sizeof(short)); // \
   // report-warning{{Function argument constraint is not satisfied}} \
   // bugpath-warning{{Function argument constraint is not satisfied}} \
Index: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -40,12 +40,12 @@
 //
 // The following standard C functions are currently supported:
 //
-//   fgetc      getline   isdigit   isupper
+//   fgetc      getline   isdigit   isupper     toascii
 //   fread      isalnum   isgraph   isxdigit
 //   fwrite     isalpha   islower   read
 //   getc       isascii   isprint   write
-//   getchar    isblank   ispunct
-//   getdelim   iscntrl   isspace
+//   getchar    isblank   ispunct   toupper
+//   getdelim   iscntrl   isspace   tolower
 //
 //===----------------------------------------------------------------------===//
 
@@ -147,9 +147,7 @@
     RangeConstraint(ArgNo ArgN, RangeKind Kind, const IntRangeVector &Args)
         : ValueConstraint(ArgN), Kind(Kind), Args(Args) {}
 
-    const IntRangeVector &getRanges() const {
-      return Args;
-    }
+    const IntRangeVector &getRanges() const { return Args; }
 
   private:
     ProgramStateRef applyAsOutOfRange(ProgramStateRef State,
@@ -158,6 +156,7 @@
     ProgramStateRef applyAsWithinRange(ProgramStateRef State,
                                        const CallEvent &Call,
                                        const Summary &Summary) const;
+
   public:
     ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call,
                           const Summary &Summary,
@@ -408,7 +407,7 @@
       return *this;
     }
 
-    Summary &Case(ConstraintSet&& CS) {
+    Summary &Case(ConstraintSet &&CS) {
       CaseConstraints.push_back(std::move(CS));
       return *this;
     }
@@ -796,13 +795,13 @@
   const QualType LongLongTy = ACtx.LongLongTy;
   const QualType SizeTy = ACtx.getSizeType();
 
-  const QualType VoidPtrTy = ACtx.VoidPtrTy; // void *
+  const QualType VoidPtrTy = ACtx.VoidPtrTy;            // void *
   const QualType IntPtrTy = ACtx.getPointerType(IntTy); // int *
   const QualType UnsignedIntPtrTy =
       ACtx.getPointerType(UnsignedIntTy); // unsigned int *
   const QualType VoidPtrRestrictTy = getRestrictTy(VoidPtrTy);
   const QualType ConstVoidPtrTy =
-      ACtx.getPointerType(ACtx.VoidTy.withConst()); // const void *
+      ACtx.getPointerType(ACtx.VoidTy.withConst());            // const void *
   const QualType CharPtrTy = ACtx.getPointerType(ACtx.CharTy); // char *
   const QualType CharPtrRestrictTy = getRestrictTy(CharPtrTy);
   const QualType ConstCharPtrTy =
@@ -1117,6 +1116,18 @@
           .Case({ArgumentCondition(0U, OutOfRange,
                                    {{'0', '9'}, {'A', 'F'}, {'a', 'f'}}),
                  ReturnValueCondition(WithinRange, SingleValue(0))}));
+  addToFunctionSummaryMap(
+      "toupper", Summary(ArgTypes{IntTy}, RetType{IntTy}, EvalCallAsPure)
+                     .ArgConstraint(ArgumentCondition(
+                         0U, WithinRange, {{EOFv, EOFv}, {0, UCharRangeMax}})));
+  addToFunctionSummaryMap(
+      "tolower", Summary(ArgTypes{IntTy}, RetType{IntTy}, EvalCallAsPure)
+                     .ArgConstraint(ArgumentCondition(
+                         0U, WithinRange, {{EOFv, EOFv}, {0, UCharRangeMax}})));
+  addToFunctionSummaryMap(
+      "toascii", Summary(ArgTypes{IntTy}, RetType{IntTy}, EvalCallAsPure)
+                     .ArgConstraint(ArgumentCondition(
+                         0U, WithinRange, {{EOFv, EOFv}, {0, UCharRangeMax}})));
 
   // The getc() family of functions that returns either a char or an EOF.
   if (FilePtrTy) {
@@ -2033,7 +2044,8 @@
       mgr.getAnalyzerOptions().getCheckerBooleanOption(Checker, "ModelPOSIX");
 }
 
-bool ento::shouldRegisterStdCLibraryFunctionsChecker(const CheckerManager &mgr) {
+bool ento::shouldRegisterStdCLibraryFunctionsChecker(
+    const CheckerManager &mgr) {
   return true;
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to