From b7f53df0c2b5f33e562de876f51a18eace0b4997 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Tue, 27 Feb 2018 20:06:20 +0000 Subject: [PATCH] [analyzer] Self-debug: Dump dynamic type info and taint with the program state. Useful for debugging problems with dynamic type info and taint. Differential Revision: https://reviews.llvm.org/D43657 llvm-svn: 326239 --- .../Core/PathSensitive/DynamicTypeMap.h | 3 +++ .../StaticAnalyzer/Core/DynamicTypeMap.cpp | 23 +++++++++++++++++++ .../lib/StaticAnalyzer/Core/ProgramState.cpp | 9 +++++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h index 555191d997099..97e8aba8365a5 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h @@ -51,6 +51,9 @@ inline ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, DynamicTypeInfo(NewTy, CanBeSubClassed)); } +void printDynamicTypeInfo(ProgramStateRef State, raw_ostream &Out, + const char *NL, const char *Sep); + } // ento } // clang diff --git a/clang/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp b/clang/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp index a01ff36a8aae0..0561c2a8bcf93 100644 --- a/clang/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp +++ b/clang/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp @@ -47,5 +47,28 @@ ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, const MemRegion *Reg, return NewState; } +void printDynamicTypeInfo(ProgramStateRef State, raw_ostream &Out, + const char *NL, const char *Sep) { + bool First = true; + for (const auto &I : State->get()) { + if (First) { + Out << NL << "Dynamic types of regions:" << NL; + First = false; + } + const MemRegion *MR = I.first; + const DynamicTypeInfo &DTI = I.second; + Out << MR << " : "; + if (DTI.isValid()) { + Out << DTI.getType()->getPointeeType().getAsString(); + if (DTI.canBeASubClass()) { + Out << " (or its subclass)"; + } + } else { + Out << "Invalid type info"; + } + Out << NL; + } +} + } // namespace ento } // namespace clang diff --git a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp index eccbc30bbe538..2546bf074a667 100644 --- a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp +++ b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -17,6 +17,7 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h" #include "clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h" #include "llvm/Support/raw_ostream.h" using namespace clang; @@ -449,6 +450,12 @@ void ProgramState::print(raw_ostream &Out, const char *NL, const char *Sep, // Print out the constraints. Mgr.getConstraintManager().print(this, Out, NL, Sep); + // Print out the tracked dynamic types. + printDynamicTypeInfo(this, Out, NL, Sep); + + // Print out tainted symbols. + printTaint(Out, NL, Sep); + // Print checker-specific data. Mgr.getOwningEngine()->printState(Out, this, NL, Sep, LC); } @@ -466,7 +473,7 @@ void ProgramState::printTaint(raw_ostream &Out, TaintMapImpl TM = get(); if (!TM.isEmpty()) - Out <<"Tainted Symbols:" << NL; + Out <<"Tainted symbols:" << NL; for (TaintMapImpl::iterator I = TM.begin(), E = TM.end(); I != E; ++I) { Out << I->first << " : " << I->second << NL;