[cfe-commits] r130398 - in /cfe/trunk: lib/StaticAnalyzer/Checkers/CStringChecker.cpp test/Analysis/string.c

Lenny Maiorani lenny at colorado.edu
Thu Apr 28 08:09:11 PDT 2011


Author: lenny
Date: Thu Apr 28 10:09:11 2011
New Revision: 130398

URL: http://llvm.org/viewvc/llvm-project?rev=130398&view=rev
Log:
Implements strcasecmp() checker in Static Analyzer.


Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
    cfe/trunk/test/Analysis/string.c

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp?rev=130398&r1=130397&r2=130398&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp Thu Apr 28 10:09:11 2011
@@ -76,8 +76,9 @@
 
   void evalStrcmp(CheckerContext &C, const CallExpr *CE) const;
   void evalStrncmp(CheckerContext &C, const CallExpr *CE) const;
+  void evalStrcasecmp(CheckerContext &C, const CallExpr *CE) const;
   void evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
-                        bool isBounded = false) const;
+                        bool isBounded = false, bool ignoreCase = false) const;
 
   // Utility methods
   std::pair<const GRState*, const GRState*>
@@ -1106,16 +1107,22 @@
 
 void CStringChecker::evalStrcmp(CheckerContext &C, const CallExpr *CE) const {
   //int strcmp(const char *restrict s1, const char *restrict s2);
-  evalStrcmpCommon(C, CE, /* isBounded = */ false);
+  evalStrcmpCommon(C, CE, /* isBounded = */ false, /* ignoreCase = */ false);
 }
 
 void CStringChecker::evalStrncmp(CheckerContext &C, const CallExpr *CE) const {
   //int strncmp(const char *restrict s1, const char *restrict s2, size_t n);
-  evalStrcmpCommon(C, CE, /* isBounded = */ true);
+  evalStrcmpCommon(C, CE, /* isBounded = */ true, /* ignoreCase = */ false);
+}
+
+void CStringChecker::evalStrcasecmp(CheckerContext &C, 
+                                    const CallExpr *CE) const {
+  //int strcasecmp(const char *restrict s1, const char *restrict s2);
+  evalStrcmpCommon(C, CE, /* isBounded = */ false, /* ignoreCase = */ true);
 }
 
 void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
-                                      bool isBounded) const {
+                                      bool isBounded, bool ignoreCase) const {
   const GRState *state = C.getState();
 
   // Check that the first string is non-null
@@ -1168,10 +1175,23 @@
     llvm::APSInt lenInt(CI->getValue());
 
     // Compare using the bounds provided like strncmp() does.
-    result = s1StrRef.compare(s2StrRef, (size_t)lenInt.getLimitedValue());
+    if (ignoreCase) {
+      // TODO Implement compare_lower(RHS, n) in LLVM StringRef.
+      // result = s1StrRef.compare_lower(s2StrRef, 
+      //                                 (size_t)lenInt.getLimitedValue());
+
+      // For now, give up.
+      return;
+    } else {
+      result = s1StrRef.compare(s2StrRef, (size_t)lenInt.getLimitedValue());
+    }
   } else {
     // Compare string 1 to string 2 the same way strcmp() does.
-    result = s1StrRef.compare(s2StrRef);
+    if (ignoreCase) {
+      result = s1StrRef.compare_lower(s2StrRef);
+    } else {
+      result = s1StrRef.compare(s2StrRef);
+    }
   }
   
   // Build the SVal of the comparison to bind the return value.
@@ -1221,6 +1241,7 @@
     .Case("strnlen", &CStringChecker::evalstrnLength)
     .Case("strcmp", &CStringChecker::evalStrcmp)
     .Case("strncmp", &CStringChecker::evalStrncmp)
+    .Case("strcasecmp", &CStringChecker::evalStrcasecmp)
     .Case("bcopy", &CStringChecker::evalBcopy)
     .Default(NULL);
 

Modified: cfe/trunk/test/Analysis/string.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/string.c?rev=130398&r1=130397&r2=130398&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/string.c (original)
+++ cfe/trunk/test/Analysis/string.c Thu Apr 28 10:09:11 2011
@@ -788,3 +788,87 @@
     (void)*(char*)0; // no-warning
 }
 
+//===----------------------------------------------------------------------===
+// strcasecmp()
+//===----------------------------------------------------------------------===
+
+#define strcasecmp BUILTIN(strcasecmp)
+int strcasecmp(const char *restrict s1, const char *restrict s2);
+
+void strcasecmp_constant0() {
+  if (strcasecmp("abc", "Abc") != 0)
+    (void)*(char*)0; // no-warning
+}
+
+void strcasecmp_constant_and_var_0() {
+  char *x = "abc";
+  if (strcasecmp(x, "Abc") != 0)
+    (void)*(char*)0; // no-warning
+}
+
+void strcasecmp_constant_and_var_1() {
+  char *x = "abc";
+    if (strcasecmp("Abc", x) != 0)
+    (void)*(char*)0; // no-warning
+}
+
+void strcasecmp_0() {
+  char *x = "abc";
+  char *y = "Abc";
+  if (strcasecmp(x, y) != 0)
+    (void)*(char*)0; // no-warning
+}
+
+void strcasecmp_1() {
+  char *x = "Bcd";
+  char *y = "abc";
+  if (strcasecmp(x, y) != 1)
+    (void)*(char*)0; // no-warning
+}
+
+void strcasecmp_2() {
+  char *x = "abc";
+  char *y = "Bcd";
+  if (strcasecmp(x, y) != -1)
+    (void)*(char*)0; // no-warning
+}
+
+void strcasecmp_null_0() {
+  char *x = NULL;
+  char *y = "123";
+  strcasecmp(x, y); // expected-warning{{Null pointer argument in call to byte string function}}
+}
+
+void strcasecmp_null_1() {
+  char *x = "123";
+  char *y = NULL;
+  strcasecmp(x, y); // expected-warning{{Null pointer argument in call to byte string function}}
+}
+
+void strcasecmp_diff_length_0() {
+  char *x = "abcde";
+  char *y = "aBd";
+  if (strcasecmp(x, y) != -1)
+    (void)*(char*)0; // no-warning
+}
+
+void strcasecmp_diff_length_1() {
+  char *x = "abc";
+  char *y = "aBdef";
+  if (strcasecmp(x, y) != -1)
+    (void)*(char*)0; // no-warning
+}
+
+void strcasecmp_diff_length_2() {
+  char *x = "aBcDe";
+  char *y = "abc";
+  if (strcasecmp(x, y) != 1)
+    (void)*(char*)0; // no-warning
+}
+
+void strcasecmp_diff_length_3() {
+  char *x = "aBc";
+  char *y = "abcde";
+  if (strcasecmp(x, y) != -1)
+    (void)*(char*)0; // no-warning
+}





More information about the cfe-commits mailing list