1ee0259d308e72141982a85b40863e760a8447edfJordan Rose// RUN: %clang_cc1 -triple i386-apple-darwin9 -x c++ -std=c++11 -verify %s 2ee0259d308e72141982a85b40863e760a8447edfJordan Rose// RUN: %clang_cc1 -triple i386-apple-darwin9 -x objective-c -verify %s 3ee0259d308e72141982a85b40863e760a8447edfJordan Rose// RUN: %clang_cc1 -triple i386-apple-darwin9 -x objective-c++ -verify %s 4ee0259d308e72141982a85b40863e760a8447edfJordan Rose 5ee0259d308e72141982a85b40863e760a8447edfJordan Rose#ifdef __cplusplus 6ee0259d308e72141982a85b40863e760a8447edfJordan Rose# define EXTERN_C extern "C" 7ee0259d308e72141982a85b40863e760a8447edfJordan Rose#else 8ee0259d308e72141982a85b40863e760a8447edfJordan Rose# define EXTERN_C extern 9ee0259d308e72141982a85b40863e760a8447edfJordan Rose#endif 10ee0259d308e72141982a85b40863e760a8447edfJordan Rose 11ee0259d308e72141982a85b40863e760a8447edfJordan RoseEXTERN_C int printf(const char *,...); 12ee0259d308e72141982a85b40863e760a8447edfJordan Rose 13ee0259d308e72141982a85b40863e760a8447edfJordan Rosetypedef enum : short { Constant = 0 } TestEnum; 14ee0259d308e72141982a85b40863e760a8447edfJordan Rose// Note that in C (and Objective-C), the type of 'Constant' is 'short'. 15ee0259d308e72141982a85b40863e760a8447edfJordan Rose// In C++ (and Objective-C++) it is 'TestEnum'. 16ee0259d308e72141982a85b40863e760a8447edfJordan Rose// This is why we don't check for that in the expected output. 17ee0259d308e72141982a85b40863e760a8447edfJordan Rose 18ee0259d308e72141982a85b40863e760a8447edfJordan Rosevoid test(TestEnum input) { 19ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printf("%hhd", input); // expected-warning{{format specifies type 'char' but the argument has underlying type 'short'}} 20ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%hhd", Constant); // expected-warning{{format specifies type 'char'}} 21ee0259d308e72141982a85b40863e760a8447edfJordan Rose 22ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%hd", input); // no-warning 23ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%hd", Constant); // no-warning 24ee0259d308e72141982a85b40863e760a8447edfJordan Rose 25ee0259d308e72141982a85b40863e760a8447edfJordan Rose // While these are less correct, they are still safe. 26ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%d", input); // no-warning 27ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%d", Constant); // no-warning 28ee0259d308e72141982a85b40863e760a8447edfJordan Rose 29ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has underlying type 'short'}} 30ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%lld", Constant); // expected-warning{{format specifies type 'long long'}} 31ee0259d308e72141982a85b40863e760a8447edfJordan Rose} 32ee0259d308e72141982a85b40863e760a8447edfJordan Rose 33ee0259d308e72141982a85b40863e760a8447edfJordan Rose 34ee0259d308e72141982a85b40863e760a8447edfJordan Rosetypedef enum : unsigned long { LongConstant = ~0UL } LongEnum; 35ee0259d308e72141982a85b40863e760a8447edfJordan Rose 36ee0259d308e72141982a85b40863e760a8447edfJordan Rosevoid testLong(LongEnum input) { 37ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printf("%u", input); // expected-warning{{format specifies type 'unsigned int' but the argument has underlying type 'unsigned long'}} 38ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%u", LongConstant); // expected-warning{{format specifies type 'unsigned int'}} 39ee0259d308e72141982a85b40863e760a8447edfJordan Rose 40ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%lu", input); 41ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%lu", LongConstant); 42ee0259d308e72141982a85b40863e760a8447edfJordan Rose} 43ee0259d308e72141982a85b40863e760a8447edfJordan Rose 44ee0259d308e72141982a85b40863e760a8447edfJordan Rose 45ee0259d308e72141982a85b40863e760a8447edfJordan Rosetypedef short short_t; 46ee0259d308e72141982a85b40863e760a8447edfJordan Rosetypedef enum : short_t { ShortConstant = 0 } ShortEnum; 47ee0259d308e72141982a85b40863e760a8447edfJordan Rose 48ee0259d308e72141982a85b40863e760a8447edfJordan Rosevoid testUnderlyingTypedef(ShortEnum input) { 49ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printf("%hhd", input); // expected-warning{{format specifies type 'char' but the argument has underlying type 'short_t' (aka 'short')}} 50ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%hhd", ShortConstant); // expected-warning{{format specifies type 'char'}} 51ee0259d308e72141982a85b40863e760a8447edfJordan Rose 52ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%hd", input); // no-warning 53ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%hd", ShortConstant); // no-warning 54ee0259d308e72141982a85b40863e760a8447edfJordan Rose 55ee0259d308e72141982a85b40863e760a8447edfJordan Rose // While these are less correct, they are still safe. 56ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%d", input); // no-warning 57ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%d", ShortConstant); // no-warning 58ee0259d308e72141982a85b40863e760a8447edfJordan Rose 59ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has underlying type 'short_t' (aka 'short')}} 60ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%lld", ShortConstant); // expected-warning{{format specifies type 'long long'}} 61ee0259d308e72141982a85b40863e760a8447edfJordan Rose} 62ee0259d308e72141982a85b40863e760a8447edfJordan Rose 63ee0259d308e72141982a85b40863e760a8447edfJordan Rose 64ee0259d308e72141982a85b40863e760a8447edfJordan Rosetypedef ShortEnum ShortEnum2; 65ee0259d308e72141982a85b40863e760a8447edfJordan Rose 66ee0259d308e72141982a85b40863e760a8447edfJordan Rosevoid testTypedefChain(ShortEnum2 input) { 67ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printf("%hhd", input); // expected-warning{{format specifies type 'char' but the argument has underlying type 'short_t' (aka 'short')}} 68ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%hd", input); // no-warning 69ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%d", input); // no-warning 70ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has underlying type 'short_t' (aka 'short')}} 71ee0259d308e72141982a85b40863e760a8447edfJordan Rose} 72ee0259d308e72141982a85b40863e760a8447edfJordan Rose 73ee0259d308e72141982a85b40863e760a8447edfJordan Rose 74ee0259d308e72141982a85b40863e760a8447edfJordan Rosetypedef enum : char { CharConstant = 'a' } CharEnum; 75ee0259d308e72141982a85b40863e760a8447edfJordan Rose 76ee0259d308e72141982a85b40863e760a8447edfJordan Rose// %hhd is deliberately not required to be signed, because 'char' isn't either. 77ee0259d308e72141982a85b40863e760a8447edfJordan Rose// This is a separate code path in FormatString.cpp. 78ee0259d308e72141982a85b40863e760a8447edfJordan Rosevoid testChar(CharEnum input) { 79ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%hhd", input); // no-warning 80ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%hhd", CharConstant); // no-warning 81ee0259d308e72141982a85b40863e760a8447edfJordan Rose 82ee0259d308e72141982a85b40863e760a8447edfJordan Rose // This is not correct but it is safe. We warn because '%hd' shows intent. 83ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printf("%hd", input); // expected-warning{{format specifies type 'short' but the argument has underlying type 'char'}} 84ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%hd", CharConstant); // expected-warning{{format specifies type 'short'}} 85ee0259d308e72141982a85b40863e760a8447edfJordan Rose 86ee0259d308e72141982a85b40863e760a8447edfJordan Rose // This is not correct but it matches the promotion rules (and is safe). 87ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%d", input); // no-warning 88ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%d", CharConstant); // no-warning 89ee0259d308e72141982a85b40863e760a8447edfJordan Rose 90ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has underlying type 'char'}} 91ee0259d308e72141982a85b40863e760a8447edfJordan Rose printf("%lld", CharConstant); // expected-warning{{format specifies type 'long long'}} 92ee0259d308e72141982a85b40863e760a8447edfJordan Rose} 93