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

Lenny Maiorani lenny at colorado.edu
Mon May 2 12:05:50 PDT 2011


Author: lenny
Date: Mon May  2 14:05:49 2011
New Revision: 130708

URL: http://llvm.org/viewvc/llvm-project?rev=130708&view=rev
Log:
Implements strncasecmp() checker and simplifies some of the logic around creating substrings if necessary and calling the appropriate StringRef::compare/compare_lower().


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=130708&r1=130707&r2=130708&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp Mon May  2 14:05:49 2011
@@ -77,6 +77,7 @@
   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 evalStrncasecmp(CheckerContext &C, const CallExpr *CE) const;
   void evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
                         bool isBounded = false, bool ignoreCase = false) const;
 
@@ -1128,6 +1129,12 @@
   evalStrcmpCommon(C, CE, /* isBounded = */ false, /* ignoreCase = */ true);
 }
 
+void CStringChecker::evalStrncasecmp(CheckerContext &C, 
+                                     const CallExpr *CE) const {
+  //int strncasecmp(const char *restrict s1, const char *restrict s2, size_t n);
+  evalStrcmpCommon(C, CE, /* isBounded = */ true, /* ignoreCase = */ true);
+}
+
 void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
                                       bool isBounded, bool ignoreCase) const {
   const GRState *state = C.getState();
@@ -1181,31 +1188,17 @@
       return;
     llvm::APSInt lenInt(CI->getValue());
 
-    // Compare using the bounds provided like strncmp() does.
-    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 {
-      // Create substrings of each to compare the prefix.
-      llvm::StringRef s1SubStr = 
-        s1StrRef.substr(0, (size_t)lenInt.getLimitedValue());
-      llvm::StringRef s2SubStr = 
-        s2StrRef.substr(0, (size_t)lenInt.getLimitedValue());
+    // Create substrings of each to compare the prefix.
+    s1StrRef = s1StrRef.substr(0, (size_t)lenInt.getLimitedValue());
+    s2StrRef = s2StrRef.substr(0, (size_t)lenInt.getLimitedValue());
+  }
 
-      // Compare the substrings.
-      result = s1SubStr.compare(s2SubStr);
-    }
+  if (ignoreCase) {
+    // Compare string 1 to string 2 the same way strcasecmp() does.
+    result = s1StrRef.compare_lower(s2StrRef);
   } else {
     // Compare string 1 to string 2 the same way strcmp() does.
-    if (ignoreCase) {
-      result = s1StrRef.compare_lower(s2StrRef);
-    } else {
-      result = s1StrRef.compare(s2StrRef);
-    }
+    result = s1StrRef.compare(s2StrRef);
   }
   
   // Build the SVal of the comparison to bind the return value.
@@ -1256,6 +1249,7 @@
     .Case("strcmp", &CStringChecker::evalStrcmp)
     .Case("strncmp", &CStringChecker::evalStrncmp)
     .Case("strcasecmp", &CStringChecker::evalStrcasecmp)
+    .Case("strncasecmp", &CStringChecker::evalStrncasecmp)
     .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=130708&r1=130707&r2=130708&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/string.c (original)
+++ cfe/trunk/test/Analysis/string.c Mon May  2 14:05:49 2011
@@ -872,3 +872,109 @@
   if (strcasecmp(x, y) != -1)
     (void)*(char*)0; // no-warning
 }
+
+//===----------------------------------------------------------------------===
+// strncasecmp()
+//===----------------------------------------------------------------------===
+
+#define strncasecmp BUILTIN(strncasecmp)
+int strncasecmp(const char *restrict s1, const char *restrict s2, size_t n);
+
+void strncasecmp_constant0() {
+  if (strncasecmp("abc", "Abc", 3) != 0)
+    (void)*(char*)0; // no-warning
+}
+
+void strncasecmp_constant_and_var_0() {
+  char *x = "abc";
+  if (strncasecmp(x, "Abc", 3) != 0)
+    (void)*(char*)0; // no-warning
+}
+
+void strncasecmp_constant_and_var_1() {
+  char *x = "abc";
+  if (strncasecmp("Abc", x, 3) != 0)
+    (void)*(char*)0; // no-warning
+}
+
+void strncasecmp_0() {
+  char *x = "abc";
+  char *y = "Abc";
+  if (strncasecmp(x, y, 3) != 0)
+    (void)*(char*)0; // no-warning
+}
+
+void strncasecmp_1() {
+  char *x = "Bcd";
+  char *y = "abc";
+  if (strncasecmp(x, y, 3) != 1)
+    (void)*(char*)0; // no-warning
+}
+
+void strncasecmp_2() {
+  char *x = "abc";
+  char *y = "Bcd";
+  if (strncasecmp(x, y, 3) != -1)
+    (void)*(char*)0; // no-warning
+}
+
+void strncasecmp_null_0() {
+  char *x = NULL;
+  char *y = "123";
+  strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to byte string function}}
+}
+
+void strncasecmp_null_1() {
+  char *x = "123";
+  char *y = NULL;
+  strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to byte string function}}
+}
+
+void strncasecmp_diff_length_0() {
+  char *x = "abcde";
+  char *y = "aBd";
+  if (strncasecmp(x, y, 5) != -1)
+    (void)*(char*)0; // no-warning
+}
+
+void strncasecmp_diff_length_1() {
+  char *x = "abc";
+  char *y = "aBdef";
+  if (strncasecmp(x, y, 5) != -1)
+    (void)*(char*)0; // no-warning
+}
+
+void strncasecmp_diff_length_2() {
+  char *x = "aBcDe";
+  char *y = "abc";
+  if (strncasecmp(x, y, 5) != 1)
+    (void)*(char*)0; // no-warning
+}
+
+void strncasecmp_diff_length_3() {
+  char *x = "aBc";
+  char *y = "abcde";
+  if (strncasecmp(x, y, 5) != -1)
+    (void)*(char*)0; // no-warning
+}
+
+void strncasecmp_diff_length_4() {
+  char *x = "abcde";
+  char *y = "aBc";
+  if (strncasecmp(x, y, 3) != 0)
+    (void)*(char*)0; // no-warning
+}
+
+void strncasecmp_diff_length_5() {
+  char *x = "abcde";
+  char *y = "aBd";
+  if (strncasecmp(x, y, 3) != -1)
+    (void)*(char*)0; // no-warning
+}
+
+void strncasecmp_diff_length_6() {
+  char *x = "aBDe";
+  char *y = "abc";
+  if (strncasecmp(x, y, 3) != 1)
+    (void)*(char*)0; // no-warning
+}





More information about the cfe-commits mailing list