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
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
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
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
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
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 }