mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-19 11:35:51 -04:00

The '%tu'/'%td' as formatting specifiers have been used to print out the NSInteger/NSUInteger values for a long time. Typically their ABI matches, but that's not the case on watchOS. The ABI difference boils down to the following: - Regular 32-bit darwin targets (like armv7) use 'ptrdiff_t' of type 'int', which matches 'NSInteger'. - WatchOS arm target (armv7k) uses 'ptrdiff_t' of type 'long', which doesn't match 'NSInteger' of type 'int'. Because of this ABI difference these specifiers trigger -Wformat warnings only for watchOS builds, which is really inconvenient for cross-platform code. This patch avoids this -Wformat warning for '%tu'/'%td' and NS[U]Integer only, and instead uses the new -Wformat-pedantic warning that JF introduced in https://reviews.llvm.org/D47290. This is acceptable because Darwin guarantees that, despite the watchOS ABI differences, sizeof(ptrdiff_t) == sizeof(NS[U]Integer), and alignof(ptrdiff_t) == alignof(NS[U]Integer) so the warning is therefore noisy for pedantic reasons. I'll update public documentation to ensure that this behaviour is properly communicated. rdar://41739204 Differential Revision: https://reviews.llvm.org/D48852 llvm-svn: 336396
53 lines
1.8 KiB
Objective-C
53 lines
1.8 KiB
Objective-C
// RUN: %clang_cc1 -triple thumbv7-apple-ios -Wno-objc-root-class -fsyntax-only -verify -Wformat %s
|
|
// RUN: %clang_cc1 -triple thumbv7-apple-ios -Wno-objc-root-class -fsyntax-only -verify -Wformat-pedantic -DPEDANTIC %s
|
|
// RUN: %clang_cc1 -triple thumbv7k-apple-watchos2.0.0 -fsyntax-only -fblocks -verify %s
|
|
// RUN: %clang_cc1 -triple thumbv7k-apple-watchos2.0.0 -fsyntax-only -fblocks -verify -Wformat-pedantic -DPEDANTIC %s
|
|
|
|
#if !defined(PEDANTIC)
|
|
// expected-no-diagnostics
|
|
#endif
|
|
|
|
#if __LP64__
|
|
typedef unsigned long NSUInteger;
|
|
typedef long NSInteger;
|
|
typedef long ptrdiff_t;
|
|
#else
|
|
typedef unsigned int NSUInteger;
|
|
typedef int NSInteger;
|
|
#if __is_target_os(watchos)
|
|
// Watch ABI uses long for ptrdiff_t.
|
|
typedef long ptrdiff_t;
|
|
#else
|
|
typedef int ptrdiff_t;
|
|
#endif
|
|
#endif
|
|
|
|
@class NSString;
|
|
|
|
extern void NSLog(NSString *format, ...);
|
|
|
|
void testSizeSpecifier() {
|
|
NSInteger i = 0;
|
|
NSUInteger j = 0;
|
|
NSLog(@"max NSInteger = %zi", i);
|
|
NSLog(@"max NSUinteger = %zu", j);
|
|
|
|
#if defined(PEDANTIC)
|
|
// expected-warning@-4 {{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
|
|
// expected-warning@-4 {{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
|
|
#endif
|
|
}
|
|
|
|
void testPtrdiffSpecifier(ptrdiff_t x) {
|
|
NSInteger i = 0;
|
|
NSUInteger j = 0;
|
|
|
|
NSLog(@"ptrdiff_t NSUinteger: %tu", j);
|
|
NSLog(@"ptrdiff_t NSInteger: %td", i);
|
|
NSLog(@"ptrdiff_t %tu, %td", x, x);
|
|
#if __is_target_os(watchos) && defined(PEDANTIC)
|
|
// expected-warning@-4 {{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
|
|
// expected-warning@-4 {{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
|
|
#endif
|
|
}
|