From: Ted Kremenek Date: Thu, 14 Nov 2013 01:42:17 +0000 (+0000) Subject: Suppress -Wunused-variable when initializer uses bridge casts for memory management. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1f64cfc5b3d164c3cdf397d82035a6a92e543443;p=clang Suppress -Wunused-variable when initializer uses bridge casts for memory management. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@194647 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 9281951a81..a7b37c55e9 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1313,6 +1313,28 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) { } } + // Under ARC, bridged casts can have side-effects on memory + // management semantics. Some users assign a bridged + // value to a temporary to adjust reference counts. + const Expr *Init = VD->getInit(); + if (Init) { + if (const ExprWithCleanups *EC = dyn_cast(Init)) + Init = EC->getSubExpr(); + Init = Init->IgnoreParens(); + if (const ImplicitCastExpr *IC = dyn_cast(Init)) { + switch (IC->getCastKind()) { + case CK_ARCProduceObject: + case CK_ARCConsumeObject: + case CK_ARCReclaimReturnedObject: + case CK_ARCExtendBlockObject: + case CK_CopyAndAutoreleaseBlockObject: + return false; + default: + break; + } + } + } + // TODO: __attribute__((unused)) templates? } diff --git a/test/SemaObjC/arc-bridged-cast.m b/test/SemaObjC/arc-bridged-cast.m index 439d382116..6f5f3782d5 100644 --- a/test/SemaObjC/arc-bridged-cast.m +++ b/test/SemaObjC/arc-bridged-cast.m @@ -62,3 +62,15 @@ CFTypeRef fixitsWithSpace(id obj) { // CHECK: fix-it:"{{.*}}":{59:9-59:9}:"(__bridge CFTypeRef)" // CHECK: fix-it:"{{.*}}":{59:9-59:9}:" CFBridgingRetain" } + +// +// Suppressed -Wunused-variable when the initializer is a bridge cast. +#pragma clang diagnostic push +#pragma clang diagnostic warning "-Wunused-variable" +void rdar15432770() { + void (^block1)() = ^ { }; + void *ptr = (__bridge_retained void *)(block1); + void (^block2)() = (__bridge_transfer void(^)())ptr; // no-warning + int x = 1; // expected-warning {{unused variable}} +} +#pragma clang diagnostic pop