Index: lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp +++ lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp @@ -665,38 +665,36 @@ /// 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 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(); + 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 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,26 @@ 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(); + if (RetRegion) { + State = setDynamicTypeInfo(State, RetRegion, ResultType, + /*CanBeSubclass=*/true); + Pred = C.addTransition(State); + } + + const auto *ResultPtrType = ResultType->getAs(); + + 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 +886,7 @@ // for the result symbol. if (!State->get(RetSym)) { State = State->set(RetSym, ResultPtrType); - C.addTransition(State); + C.addTransition(State, Pred); } } Index: test/Analysis/DynamicTypePropagation.m =================================================================== --- test/Analysis/DynamicTypePropagation.m +++ test/Analysis/DynamicTypePropagation.m @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.osx.cocoa.ObjCGenerics -verify %s -// XFAIL: * #if !__has_feature(objc_generics) # error Compiler does not support Objective-C generics?