Index: include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h @@ -51,6 +51,9 @@ DynamicTypeInfo(NewTy, CanBeSubClassed)); } +void printDynamicTypeInfo(ProgramStateRef State, raw_ostream &Out, + const char *NL, const char *Sep); + } // ento } // clang Index: lib/StaticAnalyzer/Core/DynamicTypeMap.cpp =================================================================== --- lib/StaticAnalyzer/Core/DynamicTypeMap.cpp +++ lib/StaticAnalyzer/Core/DynamicTypeMap.cpp @@ -47,5 +47,28 @@ 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 Index: lib/StaticAnalyzer/Core/ProgramState.cpp =================================================================== --- lib/StaticAnalyzer/Core/ProgramState.cpp +++ 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 @@ // 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 @@ 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;