[cfe-commits] r161358 - in /cfe/trunk: lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp test/Analysis/inlining/ObjCDynTypePopagation.m

Jordan Rose jordan_rose at apple.com
Mon Aug 6 17:53:46 PDT 2012


On Aug 6, 2012, at 16:25 , Anna Zaks <ganna at apple.com> wrote:

> +// Return a better dynamic type if one can be derived from the cast.
> +// Compare the current dynamic type of the region and the new type to which we
> +// are casting. If the new type is lower in the inheritance hierarchy, pick it.
> +const ObjCObjectPointerType *
> +DynamicTypePropagation::getBetterObjCType(const Expr *CastE,
> +                                          CheckerContext &C) const {
> +  const MemRegion *ToR = C.getSVal(CastE).getAsRegion();
> +  assert(ToR);
> +
> +  // Get the old and new types.
> +  const ObjCObjectPointerType *NewTy =
> +      CastE->getType()->getAs<ObjCObjectPointerType>();
> +  if (!NewTy)
> +    return 0;
> +  QualType OldDTy = C.getState()->getDynamicTypeInfo(ToR).getType();
> +  if (OldDTy.isNull()) {
> +    return NewTy;
> +  }
> +  const ObjCObjectPointerType *OldTy =
> +    OldDTy->getAs<ObjCObjectPointerType>();
> +  if (!OldTy)
> +    return 0;
> +
> +  // Id the old type is 'id', the new one is more precise.
> +  if (OldTy->isObjCIdType() && !NewTy->isObjCIdType())
> +    return NewTy;
> +
> +  // Return new if it's a subclass of old.
> +  const ObjCInterfaceDecl *ToI = NewTy->getInterfaceDecl();
> +  const ObjCInterfaceDecl *FromI = OldTy->getInterfaceDecl();
> +  if (ToI && FromI && FromI->isSuperClassOf(ToI))
> +    return NewTy;
> +
> +  return 0;
> +}

Why is this here and not in addDynamicTypeInfo? (If there's a good reason that's fine; it just seemed odd.)


> +// Casting to parent should not pessimize the dynamic type. 
> ++ (void) testCastToParent {
> + id a = [[self alloc] init];
> +  MyParent *p = a;  
> +  clang_analyzer_eval([p getZeroOverridden] == 0); // expected-warning{{TRUE}}
> +}
> +
> +// The type of parameter gets used.
> ++ (void)testTypeFromParam:(MyParent*) p {
> +  clang_analyzer_eval([p getZero] == 0); // expected-warning{{TRUE}}
> +}
> +
> +// Test implisit cast.
> ++ (void) testCastFromId:(id) a {
> +  MyParent *p = a;  
> +  clang_analyzer_eval([p getZero] == 0); // expected-warning{{TRUE}}
> }

Typo: "implisit".

This is also eventually the case where we should have a branch, since even if 'a' is a MyParent instance, the implementation of -getZero should have been overridden. (With all the caveats about MyParent being declared in the main source file, but also having subclasses.)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120806/70f961e0/attachment.html>


More information about the cfe-commits mailing list