// 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(*)[]), ""); }