diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp | 29 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/Store.cpp | 11 |
2 files changed, 31 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 diff --git a/clang/lib/StaticAnalyzer/Core/Store.cpp b/clang/lib/StaticAnalyzer/Core/Store.cpp index 794fd843647..4fa937d9658 100644 --- a/clang/lib/StaticAnalyzer/Core/Store.cpp +++ b/clang/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 |