From: Anna Zaks Date: Wed, 6 Mar 2013 20:26:02 +0000 (+0000) Subject: [analyzer] Pass the correct Expr to the bug reporter visitors when dealing with Compo... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=42773d64f98db0dd5cc80181c3b2d561851668f7;p=clang [analyzer] Pass the correct Expr to the bug reporter visitors when dealing with CompoundLiteralExpr This allows us to trigger the IDC visitor in the added test case. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176577 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp b/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp index de5e6dca5e..87e218505b 100644 --- a/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp @@ -57,10 +57,11 @@ void AttrNonNullChecker::checkPreCall(const CallEvent &Call, if (!DV) continue; + const Expr *ArgE = Call.getArgExpr(idx); + if (!DV->getAs()) { // If the argument is a union type, we want to handle a potential // transparent_union GCC extension. - const Expr *ArgE = Call.getArgExpr(idx); if (!ArgE) continue; @@ -77,7 +78,13 @@ void AttrNonNullChecker::checkPreCall(const CallEvent &Call, DV = V.getAs(); assert(++CSV_I == CSV->end()); if (!DV) - continue; + continue; + // Retrieve the corresponding expression. + if (const CompoundLiteralExpr *CE = dyn_cast(ArgE)) + if (const InitListExpr *IE = + dyn_cast(CE->getInitializer())) + ArgE = dyn_cast(*(IE->begin())); + } else { // FIXME: Handle LazyCompoundVals? continue; @@ -106,7 +113,7 @@ void AttrNonNullChecker::checkPreCall(const CallEvent &Call, // Highlight the range of the argument that was null. R->addRange(Call.getArgSourceRange(idx)); - if (const Expr *ArgE = Call.getArgExpr(idx)) + if (ArgE) bugreporter::trackNullOrUndefValue(errorNode, ArgE, *R); // Emit the bug report. C.emitReport(R); diff --git a/test/Analysis/inlining/inline-defensive-checks.m b/test/Analysis/inlining/inline-defensive-checks.m new file mode 100644 index 0000000000..bafc812486 --- /dev/null +++ b/test/Analysis/inlining/inline-defensive-checks.m @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-inlined-defensive-checks=true -verify %s + +typedef signed char BOOL; +typedef struct objc_class *Class; +typedef struct objc_object { + Class isa; +} *id; +@protocol NSObject - (BOOL)isEqual:(id)object; @end +@interface NSObject {} ++(id)alloc; ++(id)new; +-(id)init; +-(id)autorelease; +-(id)copy; +- (Class)class; +-(id)retain; +@end + +// expected-no-diagnostics +// Check that inline defensive checks is triggered for null expressions +// within CompoundLiteralExpr. +typedef union { + struct dispatch_object_s *_do; + struct dispatch_source_s *_ds; +} dispatch_object_t __attribute__((__transparent_union__)); +typedef struct dispatch_source_s *dispatch_source_t; + +extern __attribute__((visibility("default"))) __attribute__((__nonnull__)) __attribute__((__nothrow__)) +void +dispatch_resume(dispatch_object_t object); + +@interface AppDelegate : NSObject { +@protected + dispatch_source_t p; +} +@end +@implementation AppDelegate +- (void)updateDeleteTimer { + if (p != ((void*)0)) + ; +} +- (void)createAndStartDeleteTimer { + [self updateDeleteTimer]; + dispatch_resume(p); // no warning +} +@end