| // RUN: %clang_cc1 -fsyntax-only -verify %s |
| |
| extern int funcInt(int); |
| extern float funcFloat(float); |
| extern double funcDouble(double); |
| // figure out why "char *" doesn't work (with gcc, nothing to do with clang) |
| //extern void funcCharPtr(char *); |
| |
| #define func(expr) \ |
| do { \ |
| typeof(expr) tmp; \ |
| if (__builtin_types_compatible_p(typeof(expr), int)) funcInt(tmp); \ |
| else if (__builtin_types_compatible_p(typeof(expr), float)) funcFloat(tmp); \ |
| else if (__builtin_types_compatible_p(typeof(expr), double)) funcDouble(tmp); \ |
| } while (0) |
| #define func_choose(expr) \ |
| __builtin_choose_expr(__builtin_types_compatible_p(typeof(expr), int), funcInt(expr), \ |
| __builtin_choose_expr(__builtin_types_compatible_p(typeof(expr), float), funcFloat(expr), \ |
| __builtin_choose_expr(__builtin_types_compatible_p(typeof(expr), double), funcDouble(expr), (void)0))) |
| |
| static void test() |
| { |
| int a; |
| float b; |
| double d; |
| |
| func(a); |
| func(b); |
| func(d); |
| a = func_choose(a); |
| b = func_choose(b); |
| d = func_choose(d); |
| |
| int c; |
| struct xx { int a; } x, y; |
| |
| c = __builtin_choose_expr(a+3-7, b, x); // expected-error{{'__builtin_choose_expr' requires a constant expression}} |
| c = __builtin_choose_expr(0, b, x); // expected-error{{assigning to 'int' from incompatible type 'struct xx'}} |
| c = __builtin_choose_expr(5+3-7, b, x); |
| y = __builtin_choose_expr(4+3-7, b, x); |
| |
| } |
| |
| enum E1 { E1Foo }; |
| enum E2 { E2Foo }; |
| |
| static void testGccCompatibility() { |
| _Static_assert(__builtin_types_compatible_p(const volatile int, int), ""); |
| _Static_assert(__builtin_types_compatible_p(int[5], int[]), ""); |
| _Static_assert(!__builtin_types_compatible_p(int[5], int[4]), ""); |
| _Static_assert(!__builtin_types_compatible_p(int *, int **), ""); |
| _Static_assert(!__builtin_types_compatible_p(const int *, int *), ""); |
| _Static_assert(!__builtin_types_compatible_p(enum E1, enum E2), ""); |
| |
| // GCC's __builtin_types_compatible_p ignores qualifiers on arrays. |
| _Static_assert(__builtin_types_compatible_p(const int[4], int[4]), ""); |
| _Static_assert(__builtin_types_compatible_p(int[4], const int[4]), ""); |
| _Static_assert(__builtin_types_compatible_p(const int[5][4], int[][4]), ""); |
| _Static_assert(!__builtin_types_compatible_p(const int(*)[], int(*)[]), ""); |
| } |