1// RUN: %clang_cc1 -fsyntax-only -verify %s
2
3extern int funcInt(int);
4extern float funcFloat(float);
5extern double funcDouble(double);
6// figure out why "char *" doesn't work (with gcc, nothing to do with clang)
7//extern void funcCharPtr(char *);
8
9#define func(expr) \
10  do { \
11    typeof(expr) tmp; \
12    if (__builtin_types_compatible_p(typeof(expr), int)) funcInt(tmp); \
13    else if (__builtin_types_compatible_p(typeof(expr), float)) funcFloat(tmp); \
14    else if (__builtin_types_compatible_p(typeof(expr), double)) funcDouble(tmp); \
15  } while (0)
16#define func_choose(expr) \
17  __builtin_choose_expr(__builtin_types_compatible_p(typeof(expr), int), funcInt(expr), \
18    __builtin_choose_expr(__builtin_types_compatible_p(typeof(expr), float), funcFloat(expr), \
19      __builtin_choose_expr(__builtin_types_compatible_p(typeof(expr), double), funcDouble(expr), (void)0)))
20
21static void test()
22{
23  int a;
24  float b;
25  double d;
26
27  func(a);
28  func(b);
29  func(d);
30  a = func_choose(a);
31  b = func_choose(b);
32  d = func_choose(d);
33
34  int c;
35  struct xx { int a; } x, y;
36
37  c = __builtin_choose_expr(a+3-7, b, x); // expected-error{{'__builtin_choose_expr' requires a constant expression}}
38  c = __builtin_choose_expr(0, b, x); // expected-error{{assigning to 'int' from incompatible type 'struct xx'}}
39  c = __builtin_choose_expr(5+3-7, b, x);
40  y = __builtin_choose_expr(4+3-7, b, x);
41
42}
43
44