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
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!
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);
}
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.