const FunctionDecl *FuncDecl) {
if (FuncDecl->hasBody())
return false;
- bool HasAtLeastOnePointer = false;
+
CallEffects CE = CallEffects::getEffect(FuncDecl);
- if (!FuncDecl->getAttr<CFReturnsRetainedAttr>() &&
- !FuncDecl->getAttr<CFReturnsNotRetainedAttr>()) {
+ bool FuncIsReturnAnnotated = (FuncDecl->getAttr<CFReturnsRetainedAttr>() ||
+ FuncDecl->getAttr<CFReturnsNotRetainedAttr>());
+
+ // Trivial case of when funciton is annotated and has no argument.
+ if (FuncIsReturnAnnotated && FuncDecl->getNumParams() == 0)
+ return false;
+
+ bool HasAtLeastOnePointer = FuncIsReturnAnnotated;
+ if (!FuncIsReturnAnnotated) {
RetEffect Ret = CE.getReturnValue();
const char *AnnotationString = 0;
if (Ret.getObjKind() == RetEffect::CF && Ret.isOwned()) {
else if (!AuditedType(FuncDecl->getResultType(), HasAtLeastOnePointer))
return false;
}
- else
- HasAtLeastOnePointer = true;
// At this point result type is either annotated or audited.
// Now, how about argument types.
IOServiceNameMatching(name); // expected-warning{{leak}}
}
-
-CF_IMPLICIT_BRIDGING_ENABLED
-
CF_RETURNS_RETAINED CFDictionaryRef CreateDict();
-CF_IMPLICIT_BRIDGING_DISABLED
-
-
void IOServiceAddNotification_wrapper(mach_port_t masterPort, const io_name_t notificationType,
mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) {
// value as tracked, even if the object isn't a known CF type.
//===----------------------------------------------------------------------===//
-
-CF_IMPLICIT_BRIDGING_ENABLED
-
MyCFType getCustom() __attribute__((cf_returns_not_retained));
MyCFType makeCustom() __attribute__((cf_returns_retained));
-CF_IMPLICIT_BRIDGING_DISABLED
-
-
void testCustomReturnsRetained() {
MyCFType obj = makeCustom(); // expected-warning {{leak of an object stored into 'obj'}}
}