A BOOL stored in NSValue will get the 'c' type in the 64 bit runtime.

Originator:steipete
Number:rdar://14972905 Date Originated:Sept 12 2013
Status:Open Resolved:
Product:iOS SDK Product Version:7.0
Classification:Other Reproducible:Always
 
In the 64-bit build there is an unexpected value for the method return type in one of the method signatures during an invocation ("B" instead of the expected "c").  

This breaks my code which checks for equality in the method signature for certain tasks.

#### Original method invocation

```
BOOL allowChange = [[(id)self.delegateProxy copyThatDefaultsToYES] multiPDFController:self shouldChangeDocuments:documents];
```

#### Failure point

```
- (void)forwardInvocation:(NSInvocation *)invocation {
    // Set a default return type if set.
==> if (_defaultReturnValue && strcmp(_defaultReturnValue.objCType, invocation.methodSignature.methodReturnType) == 0) {
        char buffer[invocation.methodSignature.methodReturnLength];
        [_defaultReturnValue getValue:buffer];
        [invocation setReturnValue:&buffer];
    }
}
```

#### 32-bit signature

((lldb) p _defaultReturnValue
(NSValue *) $3 = 0x03864350 1
(lldb) p _defaultReturnValue.objCType
(char *) $4 = 0x0380c2c2 "c"
(lldb) p (char *)[invocation.methodSignature methodReturnType]
(char *) $5 = 0x0d5d6fed "c"

#### 64-bit signature

(lldb) p _defaultReturnValue
(NSValue *) $2 = 0x0000000103ba50d0 1
(lldb) p _defaultReturnValue.objCType
(char *) $3 = 0x0000000103b28fef "c"
(lldb) p (char *)[invocation.methodSignature methodReturnType]
(char *) $4 = 0x000000010cfafad5 "B"

My workaround is to do a special check for this case - but it's ugly.

- (void)forwardInvocation:(NSInvocation *)invocation {
    // Set a default return type if set.
    if (_defaultReturnValue) {
        const char *methodReturnType = invocation.methodSignature.methodReturnType;
        if (strcmp(_defaultReturnValue.objCType, methodReturnType) == 0 ||
            // The 64-bit runtime returns 'B' for BOOL, a bool in NSValue is still a char though.
            (strcmp(_defaultReturnValue.objCType, "c") == 0 && strcmp(methodReturnType, "B") == 0)) {
            char buffer[invocation.methodSignature.methodReturnLength];
            [_defaultReturnValue getValue:buffer];
            [invocation setReturnValue:&buffer];
        }
    }
}

Steps to Reproduce:
Pack a BOOL into NSValue, call `objCType`. 
The code for this is also on GitHub: https://github.com/steipete/PSTDelegateProxy

Expected Results:
objCType should return 'B' on iOS64, not 'c'.

Actual Results:


Version:
7.0 GM

Notes:


Configuration:


Attachments:

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!