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)25usual_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)49default_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)63casts (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)87assignments (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)97non_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