Suppress -Wunused-variable when initializer uses bridge casts for memory management.

Fixes <rdar://problem/15432770>.

llvm-svn: 194647
This commit is contained in:
Ted Kremenek 2013-11-14 01:42:17 +00:00
parent 5cbcf56a7e
commit f6171b3cdf
2 changed files with 34 additions and 0 deletions

View File

@ -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<ExprWithCleanups>(Init))
Init = EC->getSubExpr();
Init = Init->IgnoreParens();
if (const ImplicitCastExpr *IC = dyn_cast<ImplicitCastExpr>(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?
}

View File

@ -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"
}
// <rdar://problem/15432770>
// 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