1 /* { dg-do compile } */
2 /* { dg-options "-Wdouble-promotion" } */
3 
4 #include <stddef.h>
5 
6 /* Some targets do not provide <complex.h> so we define I ourselves.  */
7 #define I 1.0iF
8 #define ID ((_Complex double)I)
9 
10 float f;
11 double d;
12 int i;
13 long double ld;
14 _Complex float cf;
15 _Complex double cd;
16 _Complex long double cld;
17 size_t s;
18 
19 extern void unprototyped_fn ();
20 extern void varargs_fn (int, ...);
21 extern void double_fn (double);
22 extern float float_fn (void);
23 
24 void
usual_arithmetic_conversions(void)25 usual_arithmetic_conversions(void)
26 {
27   float local_f;
28   _Complex float local_cf;
29 
30   /* Values of type "float" are implicitly converted to "double" or
31      "long double" due to use in arithmetic with "double" or "long
32      double" operands.  */
33   local_f = f + 1.0;         /* { dg-warning "implicit" } */
34   local_f = f - d;           /* { dg-warning "implicit" } */
35   local_f = 1.0f * 1.0;      /* { dg-warning "implicit" } */
36   local_f = 1.0f / d;        /* { dg-warning "implicit" } */
37 
38   local_cf = cf + 1.0;       /* { dg-warning "implicit" } */
39   local_cf = cf - d;         /* { dg-warning "implicit" } */
40   local_cf = cf + 1.0 * ID;  /* { dg-warning "implicit" } */
41   local_cf = cf - cd;        /* { dg-warning "implicit" } */
42 
43   local_f = i ? f : d;       /* { dg-warning "implicit" } */
44   i = f == d;                /* { dg-warning "implicit" } */
45   i = d != f;                /* { dg-warning "implicit" } */
46 }
47 
48 void
default_argument_promotion(void)49 default_argument_promotion (void)
50 {
51   /* Because there is no prototype, "f" is promoted to "double".  */
52   unprototyped_fn (f); /* { dg-warning "implicit" } */
53   undeclared_fn (f);   /* { dg-warning "implicit" } */
54   /* Because "f" is part of the variable argument list, it is promoted
55      to "double".  */
56   varargs_fn (1, f);   /* { dg-warning "implicit" } */
57 }
58 
59 /* There is no warning when an explicit cast is used to perform the
60    conversion.  */
61 
62 void
casts(void)63 casts (void)
64 {
65   float local_f;
66   _Complex float local_cf;
67 
68   local_f = (double)f + 1.0;                 /* { dg-bogus "implicit" } */
69   local_f = (double)f - d;                   /* { dg-bogus "implicit" } */
70   local_f = (double)1.0f + 1.0;              /* { dg-bogus "implicit" } */
71   local_f = (double)1.0f - d;                /* { dg-bogus "implicit" } */
72 
73   local_cf = (_Complex double)cf + 1.0;      /* { dg-bogus "implicit" } */
74   local_cf = (_Complex double)cf - d;        /* { dg-bogus "implicit" } */
75   local_cf = (_Complex double)cf + 1.0 * ID; /* { dg-bogus "implicit" } */
76   local_cf = (_Complex double)cf - cd;       /* { dg-bogus "implicit" } */
77 
78   local_f = i ? (double)f : d;               /* { dg-bogus "implicit" } */
79   i = (double)f == d;                        /* { dg-bogus "implicit" } */
80   i = d != (double)f;                        /* { dg-bogus "implicit" } */
81 }
82 
83 /* There is no warning on conversions that occur in assignment (and
84    assignment-like) contexts.  */
85 
86 void
assignments(void)87 assignments (void)
88 {
89   d = f;           /* { dg-bogus "implicit" } */
90   double_fn (f);   /* { dg-bogus "implicit" } */
91   d = float_fn (); /* { dg-bogus "implicit" } */
92 }
93 
94 /* There is no warning in non-evaluated contexts.  */
95 
96 void
non_evaluated(void)97 non_evaluated (void)
98 {
99   s = sizeof (f + 1.0);             /* { dg-bogus "implicit" } */
100   s = __alignof__ (f + 1.0);        /* { dg-bogus "implicit" } */
101   d = (__typeof__(f + 1.0))f;       /* { dg-bogus "implicit" } */
102   s = sizeof (i ? f : d);           /* { dg-bogus "implicit" } */
103   s = sizeof (unprototyped_fn (f)); /* { dg-bogus "implicit" } */
104 }
105