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 | 02955afbb4676625dba724f693e55e0c8826f249 (patch) | |
tree | 405171cbde38e0c5ff41741bd4fec096ce58a285 /clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp | |
parent | 1f02ac34519be8e49b7eb3491569810be2dfc21c (diff) | |
download | bcm5719-llvm-02955afbb4676625dba724f693e55e0c8826f249.tar.gz bcm5719-llvm-02955afbb4676625dba724f693e55e0c8826f249.zip |
[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
llvm-svn: 349984
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp index 742266bfe60..2553f54bbca 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp @@ -321,11 +321,6 @@ void ExprInspectionChecker::analyzerDenote(const CallExpr *CE, return; } - if (!isa<SymbolData>(Sym)) { - reportBug("Not an atomic symbol", C); - return; - } - const auto *E = dyn_cast<StringLiteral>(CE->getArg(1)->IgnoreParenCasts()); if (!E) { reportBug("Not a string literal", C); @@ -345,7 +340,7 @@ class SymbolExpressor public: SymbolExpressor(ProgramStateRef State) : State(State) {} - Optional<std::string> VisitSymExpr(const SymExpr *S) { + Optional<std::string> lookup(const SymExpr *S) { if (const StringLiteral *const *SLPtr = State->get<DenotedSymbols>(S)) { const StringLiteral *SL = *SLPtr; return std::string(SL->getBytes()); @@ -353,8 +348,14 @@ public: return None; } + Optional<std::string> VisitSymExpr(const SymExpr *S) { + return lookup(S); + } + Optional<std::string> VisitSymIntExpr(const SymIntExpr *S) { - if (auto Str = Visit(S->getLHS())) + if (Optional<std::string> Str = lookup(S)) + return Str; + if (Optional<std::string> Str = Visit(S->getLHS())) return (*Str + " " + BinaryOperator::getOpcodeStr(S->getOpcode()) + " " + std::to_string(S->getRHS().getLimitedValue()) + (S->getRHS().isUnsigned() ? "U" : "")) @@ -363,12 +364,22 @@ public: } Optional<std::string> VisitSymSymExpr(const SymSymExpr *S) { - if (auto Str1 = Visit(S->getLHS())) - if (auto Str2 = Visit(S->getRHS())) + if (Optional<std::string> Str = lookup(S)) + return Str; + if (Optional<std::string> Str1 = Visit(S->getLHS())) + if (Optional<std::string> Str2 = Visit(S->getRHS())) return (*Str1 + " " + BinaryOperator::getOpcodeStr(S->getOpcode()) + " " + *Str2).str(); return None; } + + Optional<std::string> VisitSymbolCast(const SymbolCast *S) { + if (Optional<std::string> Str = lookup(S)) + return Str; + if (Optional<std::string> Str = Visit(S->getOperand())) + return (Twine("(") + S->getType().getAsString() + ")" + *Str).str(); + return None; + } }; } // namespace |