From e7c647cece3aa94ab4b3da032fbd8459146827c3 Mon Sep 17 00:00:00 2001 From: Gabor Horvath Date: Fri, 18 Sep 2015 23:38:57 +0000 Subject: [PATCH] [Static Analyzer] Fixed a false positive case in DynamicTypeChecker when dealing with forward declarations. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@248065 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp | 11 +++++++++++ test/Analysis/dynamic_type_check.m | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp b/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp index af4187005c..7e0cb8e933 100644 --- a/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp @@ -151,6 +151,14 @@ PathDiagnosticPiece *DynamicTypeChecker::DynamicTypeBugVisitor::VisitNode( return new PathDiagnosticEventPiece(Pos, OS.str(), true, nullptr); } +static bool hasDefinition(const ObjCObjectPointerType *ObjPtr) { + const ObjCInterfaceDecl *Decl = ObjPtr->getInterfaceDecl(); + if (!Decl) + return false; + + return Decl->getDefinition(); +} + // TODO: consider checking explicit casts? void DynamicTypeChecker::checkPostStmt(const ImplicitCastExpr *CE, CheckerContext &C) const { @@ -177,6 +185,9 @@ void DynamicTypeChecker::checkPostStmt(const ImplicitCastExpr *CE, if (!DynObjCType || !StaticObjCType) return; + if (!hasDefinition(DynObjCType) || !hasDefinition(StaticObjCType)) + return; + ASTContext &ASTCtxt = C.getASTContext(); // Strip kindeofness to correctly detect subtyping relationships. diff --git a/test/Analysis/dynamic_type_check.m b/test/Analysis/dynamic_type_check.m index 029bbed38f..f9b181e308 100644 --- a/test/Analysis/dynamic_type_check.m +++ b/test/Analysis/dynamic_type_check.m @@ -26,8 +26,18 @@ __attribute__((objc_root_class)) @interface NSNumber : NSObject @end +@class MyType; + void testTypeCheck(NSString* str) { id obj = str; NSNumber *num = obj; // expected-warning {{}} (void)num; } + +void testForwardDeclarations(NSString* str) { + id obj = str; + // Do not warn, since no information is available wether MyType is a sub or + // super class of any other type. + MyType *num = obj; // no warning + (void)num; +} -- 2.40.0