I was hanging around the abstract state for deep understanding of the store ,
let’s take an example
struct AA {
int a;
char b;
float c;
double d;
AA(int a, char b, float c, double d) : a(a), b(b), c(c), d(d) {};
};
//AA get();
void clang_analyzer_eval(bool);
void foo(){
AA obj(0, '0',0.1,0.11);
auto &[a, b, c, d] = obj;
float h = c;
clang_analyzer_eval(a==obj.a);
}
The abstract for this look like this
ProgramState:BindingDecl 0xd8dde50 <clang/test/Analysis/structured_bindings.cpp:15:10> col:10 referenced a 'int'
`-MemberExpr 0xd8de2a0 <col:10> 'int' lvalue .a 0xd8c0380
`-DeclRefExpr 0xd8de280 <col:10> 'AA':'AA' lvalue Decomposition 0xd8ddf70 '' 'AA &'
"program_state": {
"store": { "pointer": "0xd8f9a10", "items": [
{ "cluster": "obj", "pointer": "0xd8ebda8", "items": [
{ "kind": "Direct", "offset": 0, "value": "0 S32b" },
{ "kind": "Direct", "offset": 32, "value": "48 S8b" },
{ "kind": "Direct", "offset": 64, "value": "Unknown" },
{ "kind": "Direct", "offset": 128, "value": "Unknown" }
]},
{ "cluster": "NonParamVarRegion{D1176}", "pointer": "0xd8f9988", "items": [
{ "kind": "Direct", "offset": 0, "value": "&obj" }
]},
{ "cluster": "h", "pointer": "0xd8f9cc0", "items": [
{ "kind": "Direct", "offset": 0, "value": "Unknown" }
]}
]},
"environment": { "pointer": "0xd8eb400", "items": [
{ "lctx_id": 1, "location_context": "#0 Call", "calling": "foo", "location": null, "items": [
{ "stmt_id": 1376, "pretty": "clang_analyzer_eval", "value": "&code{clang_analyzer_eval}" },
{ "stmt_id": 1385, "pretty": "clang_analyzer_eval", "value": "&code{clang_analyzer_eval}" }
]}
]},
"constraints": null,
"equivalence_classes": null,
"disequality_info": null,
"dynamic_types": null,
"dynamic_casts": null,
"constructing_objects": null,
"checker_messages": null
Okay , so what I noticed here the value after the offset 32 is UnknownVal and that’s the reason when I bind h to the value c the value is Unkown here too .
In the other case if i bind int h = a then the cluster looks fine and the value it binds to is **{ “cluster”: “h”, “pointer”: “0xdad7eb8”, “items”: [
{ “kind”: “Direct”, “offset”: 0, “value”: “conj_$0{int, LC1, S1337, #1}” }
]}
**
. I’m really curious why it is happening that up to 32 offset we actually know about the value but after that we really don;t know about it?
Edit: Ahh I see, It actually depending on the data type we are using for the variable, I think it allocates some memory blocks for BindingDecl to models it , and if we try to access the memory location that is not in our control then it binds to Unknown.
Although, by analyzing the abstract state, I guess we really know a lot more about the BindingDecls symbolic name in several cases. And it seems like we can able to compute the Binding decl symbolic name at any point immediately .