ayartsev created this revision. ayartsev added a reviewer: zaks.anna. ayartsev added a subscriber: cfe-commits.
The patch is a fix for [[ https://llvm.org/bugs/show_bug.cgi?id=23790 | PR23790 ]]. Call to StringRef::Compare() returning [1,0,-1] is replaced with the real call to strcmp to be more precise in modelling. This also may theoretically help to find defects if a tested code relays on a value returned from strcmp like if (strcmp(x, y) == 1) { ... } Please review! http://reviews.llvm.org/D16317 Files: lib/StaticAnalyzer/Checkers/CStringChecker.cpp test/Analysis/string.c
Index: test/Analysis/string.c =================================================================== --- test/Analysis/string.c +++ test/Analysis/string.c @@ -703,13 +703,13 @@ void strcmp_1() { char *x = "234"; char *y = "123"; - clang_analyzer_eval(strcmp(x, y) == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}} } void strcmp_2() { char *x = "123"; char *y = "234"; - clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}} + clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} } void strcmp_null_0() { @@ -727,25 +727,25 @@ void strcmp_diff_length_0() { char *x = "12345"; char *y = "234"; - clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}} + clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} } void strcmp_diff_length_1() { char *x = "123"; char *y = "23456"; - clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}} + clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} } void strcmp_diff_length_2() { char *x = "12345"; char *y = "123"; - clang_analyzer_eval(strcmp(x, y) == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}} } void strcmp_diff_length_3() { char *x = "123"; char *y = "12345"; - clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}} + clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} } void strcmp_embedded_null () { @@ -786,13 +786,13 @@ void strncmp_1() { char *x = "234"; char *y = "123"; - clang_analyzer_eval(strncmp(x, y, 3) == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(strncmp(x, y, 3) > 0); // expected-warning{{TRUE}} } void strncmp_2() { char *x = "123"; char *y = "234"; - clang_analyzer_eval(strncmp(x, y, 3) == -1); // expected-warning{{TRUE}} + clang_analyzer_eval(strncmp(x, y, 3) < 0); // expected-warning{{TRUE}} } void strncmp_null_0() { @@ -810,25 +810,25 @@ void strncmp_diff_length_0() { char *x = "12345"; char *y = "234"; - clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}} + clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}} } void strncmp_diff_length_1() { char *x = "123"; char *y = "23456"; - clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}} + clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}} } void strncmp_diff_length_2() { char *x = "12345"; char *y = "123"; - clang_analyzer_eval(strncmp(x, y, 5) == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(strncmp(x, y, 5) > 0); // expected-warning{{TRUE}} } void strncmp_diff_length_3() { char *x = "123"; char *y = "12345"; - clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}} + clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}} } void strncmp_diff_length_4() { @@ -840,13 +840,13 @@ void strncmp_diff_length_5() { char *x = "012"; char *y = "12345"; - clang_analyzer_eval(strncmp(x, y, 3) == -1); // expected-warning{{TRUE}} + clang_analyzer_eval(strncmp(x, y, 3) < 0); // expected-warning{{TRUE}} } void strncmp_diff_length_6() { char *x = "234"; char *y = "12345"; - clang_analyzer_eval(strncmp(x, y, 3) == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(strncmp(x, y, 3) > 0); // expected-warning{{TRUE}} } void strncmp_embedded_null () { Index: lib/StaticAnalyzer/Checkers/CStringChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -1872,8 +1872,15 @@ // 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. - result = s1StrRef.compare(s2StrRef); + // Compare string 1 to string 2. + char s1[s1StrRef.size() + 1]; + memcpy(s1, s1StrRef.data(), s1StrRef.size()); + s1[s1StrRef.size()] = '\0'; + char s2[s2StrRef.size() + 1]; + memcpy(s2, s2StrRef.data(), s2StrRef.size()); + s2[s2StrRef.size()] = '\0'; + + result = strcmp(s1, s2); } // Build the SVal of the comparison and bind the return value.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits