aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff options
context:
space:
mode:
authorBalazs Benics <benicsbalazs@gmail.com>2022-07-26 12:31:21 +0200
committerBalazs Benics <benicsbalazs@gmail.com>2022-07-26 12:31:21 +0200
commita80418eec001d91f9573456b31704a350e421560 (patch)
treef6dc42dd23b892aa3dba1c13621b67f9014f8285 /llvm/lib/Bitcode/Reader/BitcodeReader.cpp
parent15ddc09ef9b05ffd5398165049b5202264fa203a (diff)
downloadllvm-a80418eec001d91f9573456b31704a350e421560.zip
llvm-a80418eec001d91f9573456b31704a350e421560.tar.gz
llvm-a80418eec001d91f9573456b31704a350e421560.tar.bz2
[analyzer] Improve loads from reinterpret-cast fields
Consider this example: ```lang=C++ struct header { unsigned a : 1; unsigned b : 1; }; struct parse_t { unsigned bits0 : 1; unsigned bits2 : 2; // <-- header unsigned bits4 : 4; }; int parse(parse_t *p) { unsigned copy = p->bits2; clang_analyzer_dump(copy); // expected-warning@-1 {{reg_$1<unsigned int SymRegion{reg_$0<struct Bug_55934::parse_t * p>}.bits2>}} header *bits = (header *)&copy; clang_analyzer_dump(bits->b); // <--- Was UndefinedVal previously. // expected-warning@-1 {{derived_$2{reg_$1<unsigned int SymRegion{reg_$0<struct Bug_55934::parse_t * p>}.bits2>,Element{copy,0 S64b,struct Bug_55934::header}.b}}} return bits->b; // no-warning: it's not UndefinedVal } ``` `bits->b` should have the same content as the second bit of `p->bits2` (assuming that the bitfields are in spelling order). --- The `Store` has the correct bindings. The problem is with the load of `bits->b`. It will eventually reach `RegionStoreManager::getBindingForField()` with `Element{copy,0 S64b,struct header}.b`, which is a `FieldRegion`. It did not find any direct bindings, so the `getBindingForFieldOrElementCommon()` gets called. That won't find any bindings, but it sees that the variable is on the //stack//, thus it must be an uninitialized local variable; thus it returns `UndefinedVal`. Instead of doing this, it should have created a //derived symbol// representing the slice of the region corresponding to the member. So, if the value of `copy` is `reg1`, then the value of `bits->b` should be `derived{reg1, elem{copy,0, header}.b}`. Actually, the `getBindingForElement()` already does exactly this for reinterpret-casts, so I decided to hoist that and reuse the logic. Fixes #55934 Reviewed By: martong Differential Revision: https://reviews.llvm.org/D128535
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
0 files changed, 0 insertions, 0 deletions