C++ templates with pointer template parameter specialization is broken

Originator:idoru42
Number:rdar://13751596 Date Originated:26-Apr-2013 04:53 PM, EDT
Status:Open Resolved:
Product:Developer Tools Product Version:4.6.2 (4H1003)
Classification:Serious Bug Reproducible:Always
 
26-Apr-2013 04:53 PM Sam Coward:
Summary:
When ARC is enabled, C++ candidate templates' pointer template parameters are not correctly substituted for objective-C object pointers.


Steps to reproduce:
Compile the following main.mm file, with and without ARC:

#import <Foundation/Foundation.h>

template <typename T>
void testing(const T & whoCares) {
    NSLog(@"================> Non pointer template");
}

template <typename T>
void testing(T * const & whoCares) {
    NSLog(@"================> Pointer template");
}

int main(int argc, const char * argv[])
{
    NSString *stringObject = @"hi";
    char *cString = "abc";
    testing(1);
    testing(cString);
    testing(stringObject);
    testing<NSString>(stringObject);
    return 0;
}


Expected Results:
The template with the pointer parameter should be instantiated for cString and stringObject, without needing to parameterize the template explicitly, as demonstrated by the output when compiled without ARC:

================> Non pointer template
================> Pointer template
================> Pointer template
================> Pointer template


Actual Results:
When ARC is enabled and the template is not parameterized explicitly, the non-pointer template is instantiated if the pointer is an objective-c type, as demonstrated by the output when compiled with ARC:

================> Non pointer template
================> Pointer template
================> Non pointer template         <== WRONG
================> Pointer template


Regression:

Notes:
It seems clear that the substitution is incorrect since there is a more specialized template for T * const, which should be elected instead of const T for NSString *.

Comments

Still breaks for __weak

Supplying another template for __weak causes an ambiguous template match error between all 3 (the weak, strong and unqualified).

template void testing(const T & whoCares) { NSLog(@"================> Non pointer template"); }

template void testing(T * const & whoCares) { NSLog(@"================> Pointer template"); }

template void testing(T * __strong const & whoCares) { NSLog(@"================> Pointer template"); }

int main(int argc, const char * argv[]) { NSString *stringObject = @"hi"; __weak NSString weakString = stringObject; char cString = "abc"; testing(1); testing(cString); testing(stringObject); testing(weakString); testing(stringObject); return 0; }

Not a bug?

template void testing(const T & whoCares) { NSLog(@"================> Non pointer template"); }

template void testing(T * __strong const & whoCares) { NSLog(@"================> Pointer template"); }

template void testing(T * const & whoCares) { NSLog(@"================> Pointer template"); }

int main(int argc, const char * argv[]) { NSString stringObject = @"hi"; char cString = "abc"; testing(1); testing(cString); testing(stringObject); testing(stringObject);

sleep(5);
return 0;

}

works as you expect -- I'm not at all convinced that this is a bug, it's just that ARC introduces a new thing to handle.


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!