Objective-C in `goto` label block.

Hello.

I am testing `goto` with Objective-C (ARC enabled).
And I discovered Objective-C object cannot be exist under `goto` label.

      {
        AA* a1; // Fine.
      
      LABEL3:
        AA* a2; // Compiler error: "Expected expression".
      }

Anyway it's possible to put Objective-C object in nested block.

      {
      LABEL1:
        {
          AA* a1 = [AA new];
        }
      }

This makes me confused.

(1) Why Objective-C objects cannot be placed directly in label?
(2) Why it's possible in nested block?
(3) Is it designed or buggy behavior?

Can I know accurate behavior of `goto` and labels under Objective-C context?

ARC relies on local variables of object type being initialized to nil.
A goto which jumps into the scope of an uninitialized local variable
could leave the function in an undefined state, causing it to crash
when the variable goes out of scope.

It could be argued that the compiler should implicitly zero-initialize
such variables when performing a goto, but that's actually quite
complicated to implement, and so the current rule is simply to ban this
kind of jump.

What's going on in your nested block is that you've explicitly limited
the scope of 'a1' so that "goto LABEL1;" completely skips its scope
instead of jumping into the middle of it.

John.

This is a quirk of standard C99 grammar that isn't Objective-C specific—a
label must be followed by a *statement*, not a declaration. This code is
invalid C, for instance:

void foo() {
foo:
  int x;
}

Putting an empty statement after the label works around it:

void foo() {
foo:;
  int x;
}

-Joe

Ick. We should give a better diagnostic for this.

Indeed. I filed http://llvm.org/bugs/show_bug.cgi?id=12828 ages ago but it got lost in the slipstream.

-Joe

Thanks for great answers!