[PATCH] D12916: [Static Analyzer] Use generics related information to infer dynamic types.

Gábor Horváth via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 16 17:05:07 PDT 2015


xazax.hun created this revision.
xazax.hun added reviewers: zaks.anna, dcoughlin, jordan_rose.
xazax.hun added a subscriber: cfe-commits.

This patch makes the DynamicTypePropagation checker utilize the information about generics. Using this additional information more precise inlining can be done. It also fixes an XFAIL test.

The same stored information will be used by a separate general type checker. That checker will make it possible to get rid of the isReturnValueMisused function.

http://reviews.llvm.org/D12916

Files:
  lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
  test/Analysis/DynamicTypePropagation.m

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?
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<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,20 +859,34 @@
   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<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;
 
   // When the result is a specialized type and it is not tracked yet, track it
   // for the result symbol.
   if (!State->get<MostSpecializedTypeArgsMap>(RetSym)) {
     State = State->set<MostSpecializedTypeArgsMap>(RetSym, ResultPtrType);
-    C.addTransition(State);
+    C.addTransition(State, Pred);
   }
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D12916.34942.patch
Type: text/x-patch
Size: 3932 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150917/fd45e2da/attachment.bin>


More information about the cfe-commits mailing list