summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers
diff options
context:
space:
mode:
authorGabor Horvath <xazax.hun@gmail.com>2015-09-18 16:43:27 +0000
committerGabor Horvath <xazax.hun@gmail.com>2015-09-18 16:43:27 +0000
commit6165d31a8395efd19d049e24b06ca70c37f71228 (patch)
tree9a593c50cdd8f86e05a366e57385db38cf362850 /clang/lib/StaticAnalyzer/Checkers
parentcab67cc3ff2896d03a46da8a5eb0823290267252 (diff)
downloadbcm5719-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.cpp44
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);
}
}
OpenPOWER on IntegriCloud