Index: include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h =================================================================== --- /dev/null +++ include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h @@ -0,0 +1,41 @@ +//== DynamicTypeMap.h - Dynamic type map ----------------------- -*- C++ -*--=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides APIs for tracking dynamic type information. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEMAP_H +#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEMAP_H +#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" +#include "llvm/ADT/ImmutableMap.h" + +namespace clang { +namespace ento { + +/// The GDM component containing the dynamic type info. This is a map from a +/// symbol to its most likely type. +struct DynamicTypeMap {}; +typedef llvm::ImmutableMap + DynamicTypeMapImpl; +template <> +struct ProgramStateTrait + : public ProgramStatePartialTrait { + static void *GDMIndex() { + static int index = 0; + return &index; + } +}; + +} // ento +} // clang + +#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEMAP_H Index: lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp +++ lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp @@ -17,6 +17,7 @@ #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" @@ -27,6 +28,7 @@ class DynamicTypePropagation: public Checker< check::PreCall, check::PostCall, + check::DeadSymbols, check::PostStmt, check::PostStmt > { const ObjCObjectType *getObjectTypeForAllocAndNew(const ObjCMessageExpr *MsgE, @@ -40,9 +42,23 @@ void checkPostCall(const CallEvent &Call, CheckerContext &C) const; void checkPostStmt(const ImplicitCastExpr *CastE, CheckerContext &C) const; void checkPostStmt(const CXXNewExpr *NewE, CheckerContext &C) const; + void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const; }; } +void DynamicTypePropagation::checkDeadSymbols(SymbolReaper &SR, + CheckerContext &C) const { + ProgramStateRef State = C.getState(); + DynamicTypeMapImpl TypeMap = State->get(); + for (DynamicTypeMapImpl::iterator I = TypeMap.begin(), E = TypeMap.end(); + I != E; ++I) { + if (!SR.isLiveRegion(I->first)) { + State = State->remove(I->first); + } + } + C.addTransition(State); +} + static void recordFixedType(const MemRegion *Region, const CXXMethodDecl *MD, CheckerContext &C) { assert(Region); Index: lib/StaticAnalyzer/Core/ProgramState.cpp =================================================================== --- lib/StaticAnalyzer/Core/ProgramState.cpp +++ lib/StaticAnalyzer/Core/ProgramState.cpp @@ -14,6 +14,7 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/Analysis/CFG.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h" #include "clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h" @@ -752,12 +753,6 @@ return Tainted; } -/// The GDM component containing the dynamic type info. This is a map from a -/// symbol to its most likely type. -REGISTER_TRAIT_WITH_PROGRAMSTATE(DynamicTypeMap, - CLANG_ENTO_PROGRAMSTATE_MAP(const MemRegion *, - DynamicTypeInfo)) - DynamicTypeInfo ProgramState::getDynamicTypeInfo(const MemRegion *Reg) const { Reg = Reg->StripCasts();