mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-03 11:23:58 +00:00
[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
This commit is contained in:
parent
44e803ef6d
commit
3b1165ba3d
@ -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;
|
||||
|
||||
|
@ -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}}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user