[clang] 3b1165b - [analyzer] Retrieve incomplete array extent from its redeclaration.

Denys Petrov via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 25 05:14:21 PDT 2021


Author: Denys Petrov
Date: 2021-10-25T15:14:10+03:00
New Revision: 3b1165ba3d15de83699be3ff4be3b6adf4d6e977

URL: https://github.com/llvm/llvm-project/commit/3b1165ba3d15de83699be3ff4be3b6adf4d6e977
DIFF: https://github.com/llvm/llvm-project/commit/3b1165ba3d15de83699be3ff4be3b6adf4d6e977.diff

LOG: [analyzer] Retrieve incomplete array extent from its redeclaration.

Summary: Fix a case when the extent can not be retrieved correctly from incomplete array declaration. Use redeclaration to get the array extent.

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

Added: 
    

Modified: 
    clang/lib/StaticAnalyzer/Core/RegionStore.cpp
    clang/test/Analysis/initialization.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
index e0e6bca1e7cc..5565e9cfd08c 100644
--- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -1641,8 +1641,18 @@ Optional<SVal> RegionStoreManager::getConstantValFromConstArrayInitializer(
       (!B.isMainAnalysis() || !VD->hasGlobalStorage()))
     return None;
 
-  // Array's declaration should have an initializer.
-  const Expr *Init = VD->getAnyInitializer();
+  // Array's declaration should have `ConstantArrayType` type, because only this
+  // type contains an array extent. It may happen that array type can be of
+  // `IncompleteArrayType` type. To get the declaration of `ConstantArrayType`
+  // type, we should find the declaration in the redeclarations chain that has
+  // the initialization expression.
+  // NOTE: `getAnyInitializer` has an out-parameter, which returns a new `VD`
+  // from which an initializer is obtained. We replace current `VD` with the new
+  // `VD`. If the return value of the function is null than `VD` won't be
+  // replaced.
+  const Expr *Init = VD->getAnyInitializer(VD);
+  // NOTE: If `Init` is non-null, then a new `VD` is non-null for sure. So check
+  // `Init` for null only and don't worry about the replaced `VD`.
   if (!Init)
     return None;
 

diff  --git a/clang/test/Analysis/initialization.c b/clang/test/Analysis/initialization.c
index 7981465394ea..9015113f8640 100644
--- a/clang/test/Analysis/initialization.c
+++ b/clang/test/Analysis/initialization.c
@@ -103,3 +103,42 @@ void glob_arr_index4() {
   // FIXME: Should warn {{FALSE}}, since the array has a static storage.
   clang_analyzer_eval(glob_arr_no_init[2]); // expected-warning{{UNKNOWN}}
 }
+
+const int glob_arr3[];              // IncompleteArrayType
+const int glob_arr3[4] = {1, 2, 3}; // ConstantArrayType
+void glob_arr_index5() {
+  clang_analyzer_eval(glob_arr3[0] == 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(glob_arr3[1] == 2); // expected-warning{{TRUE}}
+  clang_analyzer_eval(glob_arr3[2] == 3); // expected-warning{{TRUE}}
+  clang_analyzer_eval(glob_arr3[3] == 0); // expected-warning{{TRUE}}
+}
+
+void glob_invalid_index5() {
+  int x = 42;
+  int res = glob_arr3[x]; // expected-warning{{garbage or undefined}}
+}
+
+void glob_invalid_index6() {
+  int x = -42;
+  int res = glob_arr3[x]; // expected-warning{{garbage or undefined}}
+}
+
+const int glob_arr4[];              // IncompleteArrayType
+const int glob_arr4[4] = {1, 2, 3}; // ConstantArrayType
+const int glob_arr4[];              // ConstantArrayType (according to AST)
+void glob_arr_index6() {
+  clang_analyzer_eval(glob_arr4[0] == 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(glob_arr4[1] == 2); // expected-warning{{TRUE}}
+  clang_analyzer_eval(glob_arr4[2] == 3); // expected-warning{{TRUE}}
+  clang_analyzer_eval(glob_arr4[3] == 0); // expected-warning{{TRUE}}
+}
+
+void glob_invalid_index7() {
+  int x = 42;
+  int res = glob_arr4[x]; // expected-warning{{garbage or undefined}}
+}
+
+void glob_invalid_index8() {
+  int x = -42;
+  int res = glob_arr4[x]; // expected-warning{{garbage or undefined}}
+}


        


More information about the cfe-commits mailing list