diff options
author | Artem Dergachev <artem.dergachev@gmail.com> | 2018-12-22 02:06:51 +0000 |
---|---|---|
committer | Artem Dergachev <artem.dergachev@gmail.com> | 2018-12-22 02:06:51 +0000 |
commit | 71ba9f34f8103934f0aa68e04ba3f9b6bbca0a5f (patch) | |
tree | 3ae817b77c32fdd9af0e884660e603e529e1007f /lib/StaticAnalyzer/Core/Store.cpp | |
parent | 5ce73e9a7953d8b153974c3c5a1ed1330558a73f (diff) | |
download | clang-71ba9f34f8103934f0aa68e04ba3f9b6bbca0a5f.tar.gz |
[analyzer] pr38668: Do not attempt to cast loaded integers to floats.
This patch is a different approach to landing the reverted r349701.
It is expected to have the same object (memory region) treated as if it has
different types in different program points. The correct behavior for
RegionStore when an object is stored as an object of type T1 but loaded as
an object of type T2 is to store the object as if it has type T1 but cast it
to T2 during load.
Note that the cast here is some sort of a "reinterpret_cast" (even in C). For
instance, if you store an integer and load a float, you won't get your integer
represented as a float; instead, you will get garbage.
Admit that we cannot perform the cast and return an unknown value.
Differential Revision: https://reviews.llvm.org/D55875
rdar://problem/45062567
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349984 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/Store.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/Store.cpp | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/lib/StaticAnalyzer/Core/Store.cpp b/lib/StaticAnalyzer/Core/Store.cpp index 794fd84364..4fa937d965 100644 --- a/lib/StaticAnalyzer/Core/Store.cpp +++ b/lib/StaticAnalyzer/Core/Store.cpp @@ -402,6 +402,17 @@ SVal StoreManager::CastRetrievedVal(SVal V, const TypedValueRegion *R, if (castTy.isNull() || V.isUnknownOrUndef()) return V; + // The dispatchCast() call below would convert the int into a float. + // What we want, however, is a bit-by-bit reinterpretation of the int + // as a float, which usually yields nothing garbage. For now skip casts + // from ints to floats. + // TODO: What other combinations of types are affected? + if (castTy->isFloatingType()) { + SymbolRef Sym = V.getAsSymbol(); + if (Sym && !Sym->getType()->isFloatingType()) + return UnknownVal(); + } + // When retrieving symbolic pointer and expecting a non-void pointer, // wrap them into element regions of the expected type if necessary. // SValBuilder::dispatchCast() doesn't do that, but it is necessary to |