[clang] 0eba5dc - [analyzer] Fix modeling some library functions when UCHAR_MAX > INT_MAX.

Artem Dergachev via cfe-commits cfe-commits at lists.llvm.org
Sun Mar 15 21:16:55 PDT 2020


Author: Artem Dergachev
Date: 2020-03-16T07:16:44+03:00
New Revision: 0eba5dc80fb0a65b8bad00998c390ce3ec0c430f

URL: https://github.com/llvm/llvm-project/commit/0eba5dc80fb0a65b8bad00998c390ce3ec0c430f
DIFF: https://github.com/llvm/llvm-project/commit/0eba5dc80fb0a65b8bad00998c390ce3ec0c430f.diff

LOG: [analyzer] Fix modeling some library functions when UCHAR_MAX > INT_MAX.

This makes life easier for downstream users who maintain exotic
target platforms.

Patch by Vince Bridgers!

Differential Revision: https://reviews.llvm.org/D75529

Added: 
    

Modified: 
    clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index d52b3f371af9..6af63fc28e23 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -510,8 +510,14 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
   const RangeInt LongMax = BVF.getMaxValue(LongTy).getLimitedValue();
   const RangeInt LongLongMax = BVF.getMaxValue(LongLongTy).getLimitedValue();
 
-  const RangeInt UCharMax =
-      BVF.getMaxValue(ACtx.UnsignedCharTy).getLimitedValue();
+  // Set UCharRangeMax to min of int or uchar maximum value.
+  // The C standard states that the arguments of functions like isalpha must
+  // be representable as an unsigned char. Their type is 'int', so the max
+  // value of the argument should be min(UCharMax, IntMax). This just happen
+  // to be true for commonly used and well tested instruction set
+  // architectures, but not for others.
+  const RangeInt UCharRangeMax =
+      std::min(BVF.getMaxValue(ACtx.UnsignedCharTy).getLimitedValue(), IntMax);
 
   // The platform dependent value of EOF.
   // Try our best to parse this from the Preprocessor, otherwise fallback to -1.
@@ -573,8 +579,8 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
   // Templates for summaries that are reused by many functions.
   auto Getc = [&]() {
     return Summary(ArgTypes{Irrelevant}, RetType{IntTy}, NoEvalCall)
-        .Case(
-            {ReturnValueCondition(WithinRange, {{EOFv, EOFv}, {0, UCharMax}})});
+        .Case({ReturnValueCondition(WithinRange,
+                                    {{EOFv, EOFv}, {0, UCharRangeMax}})});
   };
   auto Read = [&](RetType R, RangeInt Max) {
     return Summary(ArgTypes{Irrelevant, Irrelevant, SizeTy}, RetType{R},
@@ -609,12 +615,13 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
                   // The locale-specific range.
                   // No post-condition. We are completely unaware of
                   // locale-specific return values.
-                  .Case({ArgumentCondition(0U, WithinRange, {{128, UCharMax}})})
+                  .Case({ArgumentCondition(0U, WithinRange,
+                                           {{128, UCharRangeMax}})})
                   .Case({ArgumentCondition(0U, OutOfRange,
                                            {{'0', '9'},
                                             {'A', 'Z'},
                                             {'a', 'z'},
-                                            {128, UCharMax}}),
+                                            {128, UCharRangeMax}}),
                          ReturnValueCondition(WithinRange, SingleValue(0))})},
       },
       {
@@ -625,10 +632,11 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
                                            {{'A', 'Z'}, {'a', 'z'}}),
                          ReturnValueCondition(OutOfRange, SingleValue(0))})
                   // The locale-specific range.
-                  .Case({ArgumentCondition(0U, WithinRange, {{128, UCharMax}})})
+                  .Case({ArgumentCondition(0U, WithinRange,
+                                           {{128, UCharRangeMax}})})
                   .Case({ArgumentCondition(
                              0U, OutOfRange,
-                             {{'A', 'Z'}, {'a', 'z'}, {128, UCharMax}}),
+                             {{'A', 'Z'}, {'a', 'z'}, {128, UCharRangeMax}}),
                          ReturnValueCondition(WithinRange, SingleValue(0))})},
       },
       {
@@ -692,9 +700,11 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
                          ArgumentCondition(0U, OutOfRange, Range('a', 'z')),
                          ReturnValueCondition(WithinRange, SingleValue(0))})
                   // The locale-specific range.
-                  .Case({ArgumentCondition(0U, WithinRange, {{128, UCharMax}})})
+                  .Case({ArgumentCondition(0U, WithinRange,
+                                           {{128, UCharRangeMax}})})
                   // Is not an unsigned char.
-                  .Case({ArgumentCondition(0U, OutOfRange, Range(0, UCharMax)),
+                  .Case({ArgumentCondition(0U, OutOfRange,
+                                           Range(0, UCharRangeMax)),
                          ReturnValueCondition(WithinRange, SingleValue(0))})},
       },
       {
@@ -728,10 +738,11 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
                                            {{9, 13}, {' ', ' '}}),
                          ReturnValueCondition(OutOfRange, SingleValue(0))})
                   // The locale-specific range.
-                  .Case({ArgumentCondition(0U, WithinRange, {{128, UCharMax}})})
+                  .Case({ArgumentCondition(0U, WithinRange,
+                                           {{128, UCharRangeMax}})})
                   .Case({ArgumentCondition(
                              0U, OutOfRange,
-                             {{9, 13}, {' ', ' '}, {128, UCharMax}}),
+                             {{9, 13}, {' ', ' '}, {128, UCharRangeMax}}),
                          ReturnValueCondition(WithinRange, SingleValue(0))})},
       },
       {
@@ -742,10 +753,11 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
                   .Case({ArgumentCondition(0U, WithinRange, Range('A', 'Z')),
                          ReturnValueCondition(OutOfRange, SingleValue(0))})
                   // The locale-specific range.
-                  .Case({ArgumentCondition(0U, WithinRange, {{128, UCharMax}})})
+                  .Case({ArgumentCondition(0U, WithinRange,
+                                           {{128, UCharRangeMax}})})
                   // Other.
                   .Case({ArgumentCondition(0U, OutOfRange,
-                                           {{'A', 'Z'}, {128, UCharMax}}),
+                                           {{'A', 'Z'}, {128, UCharRangeMax}}),
                          ReturnValueCondition(WithinRange, SingleValue(0))})},
       },
       {
@@ -768,7 +780,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
       {"getchar",
        Summaries{Summary(ArgTypes{}, RetType{IntTy}, NoEvalCall)
                      .Case({ReturnValueCondition(
-                         WithinRange, {{EOFv, EOFv}, {0, UCharMax}})})}},
+                         WithinRange, {{EOFv, EOFv}, {0, UCharRangeMax}})})}},
 
       // read()-like functions that never return more than buffer size.
       // We are not sure how ssize_t is defined on every platform, so we


        


More information about the cfe-commits mailing list