r176054 - [analyzer] Restrict ObjC type inference to methods that have related result type.

Anna Zaks ganna at apple.com
Mon Feb 25 14:10:34 PST 2013


Author: zaks
Date: Mon Feb 25 16:10:34 2013
New Revision: 176054

URL: http://llvm.org/viewvc/llvm-project?rev=176054&view=rev
Log:
[analyzer] Restrict ObjC type inference to methods that have related result type.

This addresses a case when we inline a wrong method due to incorrect
dynamic type inference. Specifically, when user code contains a method from init
family, which creates an instance of another class.

Use hasRelatedResultType() to find out if our inference rules should be triggered.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
    cfe/trunk/test/Analysis/inlining/ObjCDynTypePopagation.m

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp?rev=176054&r1=176053&r2=176054&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp Mon Feb 25 16:10:34 2013
@@ -110,38 +110,40 @@ void DynamicTypePropagation::checkPostCa
       return;
 
     ProgramStateRef State = C.getState();
+    const ObjCMethodDecl *D = Msg->getDecl();
+    
+    if (D && D->hasRelatedResultType()) {
+      switch (Msg->getMethodFamily()) {
+      default:
+        break;
 
-    switch (Msg->getMethodFamily()) {
-    default:
-      break;
-
-    // We assume that the type of the object returned by alloc and new are the
-    // pointer to the object of the class specified in the receiver of the
-    // message.
-    case OMF_alloc:
-    case OMF_new: {
-      // Get the type of object that will get created.
-      const ObjCMessageExpr *MsgE = Msg->getOriginExpr();
-      const ObjCObjectType *ObjTy = getObjectTypeForAllocAndNew(MsgE, C);
-      if (!ObjTy)
-        return;
-      QualType DynResTy =
+      // We assume that the type of the object returned by alloc and new are the
+      // pointer to the object of the class specified in the receiver of the
+      // message.
+      case OMF_alloc:
+      case OMF_new: {
+        // Get the type of object that will get created.
+        const ObjCMessageExpr *MsgE = Msg->getOriginExpr();
+        const ObjCObjectType *ObjTy = getObjectTypeForAllocAndNew(MsgE, C);
+        if (!ObjTy)
+          return;
+        QualType DynResTy =
                  C.getASTContext().getObjCObjectPointerType(QualType(ObjTy, 0));
-      C.addTransition(State->setDynamicTypeInfo(RetReg, DynResTy, false));
-      break;
-    }
-    case OMF_init: {
-      // Assume, the result of the init method has the same dynamic type as
-      // the receiver and propagate the dynamic type info.
-      const MemRegion *RecReg = Msg->getReceiverSVal().getAsRegion();
-      if (!RecReg)
-        return;
-      DynamicTypeInfo RecDynType = State->getDynamicTypeInfo(RecReg);
-      C.addTransition(State->setDynamicTypeInfo(RetReg, RecDynType));
-      break;
+        C.addTransition(State->setDynamicTypeInfo(RetReg, DynResTy, false));
+        break;
+      }
+      case OMF_init: {
+        // Assume, the result of the init method has the same dynamic type as
+        // the receiver and propagate the dynamic type info.
+        const MemRegion *RecReg = Msg->getReceiverSVal().getAsRegion();
+        if (!RecReg)
+          return;
+        DynamicTypeInfo RecDynType = State->getDynamicTypeInfo(RecReg);
+        C.addTransition(State->setDynamicTypeInfo(RetReg, RecDynType));
+        break;
+      }
+      }
     }
-    }
-
     return;
   }
 

Modified: cfe/trunk/test/Analysis/inlining/ObjCDynTypePopagation.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inlining/ObjCDynTypePopagation.m?rev=176054&r1=176053&r2=176054&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inlining/ObjCDynTypePopagation.m (original)
+++ cfe/trunk/test/Analysis/inlining/ObjCDynTypePopagation.m Mon Feb 25 16:10:34 2013
@@ -82,3 +82,20 @@ int testDynamicClass(BOOL coin) {
    return [x getZero];
  return 1;
 }
+
+ at interface UserClass : NSObject
+- (PublicSubClass2 *) _newPublicSubClass2;
+- (int) getZero;
+- (void) callNew;
+ at end
+
+ at implementation UserClass
+- (PublicSubClass2 *) _newPublicSubClass2 {
+  return [[PublicSubClass2 alloc] init];
+}
+- (int) getZero { return 5; }
+- (void) callNew {
+  PublicSubClass2 *x = [self _newPublicSubClass2];
+  clang_analyzer_eval([x getZero] == 0); //expected-warning{{TRUE}}
+}
+ at end
\ No newline at end of file





More information about the cfe-commits mailing list