0

I maintain an Objective-C project which uses a C library that implements a garbage-collected scripting environment. In several cases, I need to put a retained Objective-C object in the private field of a scripting object. The Objective-C object is then released in a finalize callback.

The call to set the private value looks like this, with hopefully obvious semantics:

if (!JS_SetPrivate(context, jsSelf, [self retain])) /* handle error */

The finalize callback does this:

id object = JS_GetPrivate(context, jsSelf);
if (object != nil)
{
    [object clearJSSelf:jsSelf]; // Remove reference to JS wrapper.
    [object release];  // JS wrapper owned a reference.
    JS_SetPrivate(context, jsSelf, nil);
}

The Clang Static Analyzer has no objection to the random release in the finalize callback, but where the value is initially set it says “Potential leak of an object allocated on line N.”

Is there an annotation or non-ugly pattern that would suppress this message? (I’d rather not be doing silly things like [object performSelector:@selector(retain)]. I’d also prefer not to mess with the header declaring JS_SetPrivate. Also note that the value given to JS_SetPrivate is an arbitrary pointer, not necessarily an Objective-C object.

Jens Ayton
  • 14,532
  • 3
  • 33
  • 47

1 Answers1

2

You can use the new NS_CONSUMED attribute on JS_SetPrivate:

http://clang-analyzer.llvm.org/annotations.html#attr_ns_consumed

  • As per Twitter: ns_consumed does not work with `void *` pointers. This is a reasonably general issue for context pointers/refcons/“closures”. http://llvm.org/bugs/show_bug.cgi?id=9075 – Jens Ayton Jan 27 '11 at 22:12
  • My “solution” – read it and weep: `static inline OOConsumeReference(id __attribute__(ns_consume) value) __attribute__((always_inline)) { return value; }` – Jens Ayton Jan 27 '11 at 23:35
  • I just get unknown attribute. Even when I force Xcode 4 to compile with “LLVM 2”. – mxcl Apr 13 '11 at 14:02
  • @Max Are you using `ns_consumed`? There’s a typo in Ahruman’s comment. –  May 11 '11 at 22:36
  • For the record, my nasty solution no longer works (checker-262/263). I haven’t investigated new hackarounds yet. – Jens Ayton Mar 25 '12 at 19:29