Friday, May 6, 2016

Re: Clang not enforcing that block returns a value

On May 6, 2016, at 11:28 AM, Jens Alfke <jens@mooseyard.com> wrote:

I just had a bizarre failure in a new unit test, which I finally tracked down to a callback block returning NO when it should have returned YES. In fact I'd forgotten to add "return YES" at the end of the block, which the compiler should have flagged as an error — instead it somehow synthesized a NO return.

It is probably just falling off the end and leaving the result uninitialized.

I reduced it down to the following invalid code, which compiles without warnings or errors:

    BOOL (^block)();
    block = ^BOOL {
        @try {
        } @catch (...) {
        }
    };

It looks like as soon as you add an @try statement to a block, the compiler stops enforcing that the block has to return a value. Yikes! In my original code, the @try was hidden inside the definition of the XCTAssert() macro, so an equivalent test case is

    BOOL (^block)();
    block = ^BOOL {
        XCTAssert(2 + 2 == 4);
    };

I'm 99% certain this is a Clang bug, but I thought I'd ask first in case any of you rules lawyers can think of a reason this should be valid :)

It's likely that the compiler is just being more conservative about control flow in the presence of try/catch, but I think we could reasonably catch cases like this; please file a bug.

John.

No comments:

Post a Comment