diff options
author | Gabor Horvath <xazax.hun@gmail.com> | 2015-09-18 16:43:27 +0000 |
---|---|---|
committer | Gabor Horvath <xazax.hun@gmail.com> | 2015-09-18 16:43:27 +0000 |
commit | 6165d31a8395efd19d049e24b06ca70c37f71228 (patch) | |
tree | 9a593c50cdd8f86e05a366e57385db38cf362850 /clang/lib/StaticAnalyzer/Checkers | |
parent | cab67cc3ff2896d03a46da8a5eb0823290267252 (diff) | |
download | bcm5719-llvm-6165d31a8395efd19d049e24b06ca70c37f71228.tar.gz bcm5719-llvm-6165d31a8395efd19d049e24b06ca70c37f71228.zip |
[Static Analyzer] Use generics related information to infer dynamic types.
Differential Revision: http://reviews.llvm.org/D12916
llvm-svn: 248002
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp index 99b5353bd7d..a2ef65a045b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp @@ -665,38 +665,36 @@ findMethodDecl(const ObjCMessageExpr *MessageExpr, /// Get the returned ObjCObjectPointerType by a method based on the tracked type /// information, or null pointer when the returned type is not an /// ObjCObjectPointerType. -static const ObjCObjectPointerType *getReturnTypeForMethod( +static QualType getReturnTypeForMethod( const ObjCMethodDecl *Method, ArrayRef<QualType> TypeArgs, const ObjCObjectPointerType *SelfType, ASTContext &C) { QualType StaticResultType = Method->getReturnType(); // Is the return type declared as instance type? if (StaticResultType == C.getObjCInstanceType()) - return SelfType; + return QualType(SelfType, 0); // Check whether the result type depends on a type parameter. if (!isObjCTypeParamDependent(StaticResultType)) - return nullptr; + return QualType(); QualType ResultType = StaticResultType.substObjCTypeArgs( C, TypeArgs, ObjCSubstitutionContext::Result); - return ResultType->getAs<ObjCObjectPointerType>(); + return ResultType; } /// Validate that the return type of a message expression is used correctly. /// Returns true in case an error is detected. bool DynamicTypePropagation::isReturnValueMisused( const ObjCMessageExpr *MessageExpr, - const ObjCObjectPointerType *SeflType, SymbolRef Sym, + const ObjCObjectPointerType *ResultPtrType, SymbolRef Sym, const ObjCMethodDecl *Method, ArrayRef<QualType> TypeArgs, bool SubscriptOrProperty, CheckerContext &C) const { - ASTContext &ASTCtxt = C.getASTContext(); - const auto *ResultPtrType = - getReturnTypeForMethod(Method, TypeArgs, SeflType, ASTCtxt); if (!ResultPtrType) return false; + ASTContext &ASTCtxt = C.getASTContext(); const Stmt *Parent = C.getCurrentAnalysisDeclContext()->getParentMap().getParent(MessageExpr); if (SubscriptOrProperty) { @@ -861,12 +859,32 @@ void DynamicTypePropagation::checkPostObjCMessage(const ObjCMethodCall &M, if (!TypeArgs) return; - if (isReturnValueMisused(MessageExpr, *TrackedType, RecSym, Method, *TypeArgs, - M.getMessageKind() != OCM_Message, C)) + QualType ResultType = + getReturnTypeForMethod(Method, *TypeArgs, *TrackedType, ASTCtxt); + // The static type is the same as the deduced type. + if (ResultType.isNull()) + return; + + const MemRegion *RetRegion = M.getReturnValue().getAsRegion(); + ExplodedNode *Pred = C.getPredecessor(); + // When there is an entry available for the return symbol in DynamicTypeMap, + // the call was inlined, and the information in the DynamicTypeMap is should + // be precise. + if (RetRegion && !State->get<DynamicTypeMap>(RetRegion)) { + // TODO: we have duplicated information in DynamicTypeMap and + // MostSpecializedTypeArgsMap. We should only store anything in the later if + // the stored data differs from the one stored in the former. + State = setDynamicTypeInfo(State, RetRegion, ResultType, + /*CanBeSubclass=*/true); + Pred = C.addTransition(State); + } + + const auto *ResultPtrType = ResultType->getAs<ObjCObjectPointerType>(); + + if (isReturnValueMisused(MessageExpr, ResultPtrType, RecSym, Method, + *TypeArgs, M.getMessageKind() != OCM_Message, C)) return; - const auto *ResultPtrType = - getReturnTypeForMethod(Method, *TypeArgs, *TrackedType, ASTCtxt); if (!ResultPtrType || ResultPtrType->isUnspecialized()) return; @@ -874,7 +892,7 @@ void DynamicTypePropagation::checkPostObjCMessage(const ObjCMethodCall &M, // for the result symbol. if (!State->get<MostSpecializedTypeArgsMap>(RetSym)) { State = State->set<MostSpecializedTypeArgsMap>(RetSym, ResultPtrType); - C.addTransition(State); + C.addTransition(State, Pred); } } |