1// RUN: %clang_cc1 %s -verify -Wobjc-signed-char-bool 2// RUN: %clang_cc1 -xobjective-c++ %s -verify -Wobjc-signed-char-bool 3 4typedef signed char BOOL; 5#define YES __objc_yes 6#define NO __objc_no 7 8typedef unsigned char Boolean; 9 10BOOL b; 11Boolean boolean; 12float fl; 13int i; 14int *ptr; 15 16void t1(void) { 17 b = boolean; 18 b = fl; // expected-warning {{implicit conversion from floating-point type 'float' to 'BOOL'}} 19 b = i; // expected-warning {{implicit conversion from integral type 'int' to 'BOOL'}} 20 21 b = 1.0; 22 b = 0.0; 23 b = 1.1; // expected-warning {{implicit conversion from 'double' to 'BOOL' (aka 'signed char') changes value from 1.1 to 1}} 24 b = 2.1; // expected-warning {{implicit conversion from constant value 2.1 to 'BOOL'; the only well defined values for 'BOOL' are YES and NO}} 25 26 b = YES; 27 b = ptr; // expected-error {{incompatible pointer to integer conversion assigning to 'BOOL' (aka 'signed char') from 'int *'}} 28} 29 30@interface BoolProp 31@property BOOL p; 32@end 33 34void t2(BoolProp *bp) { 35 bp.p = YES; 36 bp.p = NO; 37 bp.p = boolean; 38 bp.p = fl; // expected-warning {{implicit conversion from floating-point type 'float' to 'BOOL'}} 39 bp.p = i; // expected-warning {{implicit conversion from integral type 'int' to 'BOOL'}} 40 bp.p = b; 41 bp.p = bp.p; 42 bp.p = ptr; // expected-error {{incompatible pointer to integer conversion assigning to 'BOOL' (aka 'signed char') from 'int *'}} 43 bp.p = 1; 44 bp.p = 2; // expected-warning {{implicit conversion from constant value 2 to 'BOOL'; the only well defined values for 'BOOL' are YES and NO}} 45} 46 47struct has_bf { 48 int signed_bf1 : 1; 49 int signed_bf2 : 2; 50 unsigned unsigned_bf1 : 1; 51 unsigned unsigned_bf2 : 2; 52 53 struct has_bf *nested; 54}; 55 56void t3(struct has_bf *bf) { 57 b = bf->signed_bf1; // expected-warning{{implicit conversion from integral type 'int' to 'BOOL'}} 58 b = bf->signed_bf2; // expected-warning{{implicit conversion from integral type 'int' to 'BOOL'}} 59 b = bf->unsigned_bf1; // no warning 60 b = bf->unsigned_bf2; // expected-warning{{implicit conversion from integral type 'unsigned int' to 'BOOL'}} 61 struct has_bf local; 62 b = local.unsigned_bf1; 63 b = local.unsigned_bf2; // expected-warning{{implicit conversion from integral type 'unsigned int' to 'BOOL'}} 64 b = local.nested->unsigned_bf1; 65 b = local.nested->unsigned_bf2; // expected-warning{{implicit conversion from integral type 'unsigned int' to 'BOOL'}} 66} 67 68void t4(BoolProp *bp) { 69 BOOL local = YES; 70 bp.p = 1 ? local : NO; // no warning 71} 72 73__attribute__((objc_root_class)) 74@interface BFIvar { 75 struct has_bf bf; 76 unsigned unsigned_bf1 : 1; 77 unsigned unsigned_bf2 : 2; 78} 79@end 80 81@implementation BFIvar 82-(void)m { 83 b = bf.unsigned_bf1; 84 b = bf.unsigned_bf2; // expected-warning{{implicit conversion from integral type 'unsigned int' to 'BOOL'}} 85 b = unsigned_bf1; 86 b = unsigned_bf2; // expected-warning{{implicit conversion from integral type 'unsigned int' to 'BOOL'}} 87} 88@end 89 90#ifdef __cplusplus 91template <class T> 92struct S { 93 unsigned i : sizeof(T); 94}; 95 96template <class T> 97void f() { 98 S<T> i; 99 BOOL b = i.i; // expected-warning{{implicit conversion from integral type 'unsigned int' to 'BOOL'}} 100} 101 102int main() { 103 f<char>(); 104 f<short>(); // expected-note {{in instantiation of function template specialization 'f<short>' requested here}} 105} 106#endif 107 108void t5(BOOL b) { 109 int i; 110 b = b ?: YES; // no warning 111 b = b ?: i; // expected-warning {{implicit conversion from integral type 'int' to 'BOOL'}} 112 b = (b = i) // expected-warning {{implicit conversion from integral type 'int' to 'BOOL'}} 113 ?: YES; 114 b = (1 ? YES : i) ?: YES; // expected-warning {{implicit conversion from integral type 'int' to 'BOOL'}} 115 b = b ?: (1 ? i : i); // expected-warning 2 {{implicit conversion from integral type 'int' to 'BOOL'}} 116 117 b = b ? YES : (i ?: 0); // expected-warning {{implicit conversion from integral type 'int' to 'BOOL'}} 118} 119