summaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/warn/Wdouble-promotion.C
blob: 9b4044f77f62695f2cc17513817cedc4f3f0d030 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/* { dg-do compile } */
/* { dg-options "-Wdouble-promotion" } */

#include <stddef.h>

/* Some targets do not provide <complex.h> so we define I ourselves.  */
#define I 1.0iF
#define ID ((_Complex double)I)

float f;
double d;
int i;
long double ld;
_Complex float cf;
_Complex double cd;
_Complex long double cld;
size_t s;

extern void varargs_fn (int, ...);
extern void double_fn (double);
extern float float_fn (void);

void 
usual_arithmetic_conversions(void) 
{
  float local_f;
  _Complex float local_cf;

  /* Values of type "float" are implicitly converted to "double" or
     "long double" due to use in arithmetic with "double" or "long
     double" operands.  */
  local_f = f + 1.0;         /* { dg-warning "implicit" } */
  local_f = f - d;           /* { dg-warning "implicit" } */
  local_f = 1.0f * 1.0;      /* { dg-warning "implicit" } */
  local_f = 1.0f / d;        /* { dg-warning "implicit" } */

  local_cf = cf + 1.0;       /* { dg-warning "implicit" } */
  local_cf = cf - d;         /* { dg-warning "implicit" } */
  local_cf = cf + 1.0 * ID;  /* { dg-warning "implicit" } */
  local_cf = cf - cd;        /* { dg-warning "implicit" } */
  
  local_f = i ? f : d;       /* { dg-warning "implicit" } */
  i = f == d;                /* { dg-warning "implicit" } */
  i = d != f;                /* { dg-warning "implicit" } */
}

void 
default_argument_promotion (void) 
{
  /* Because "f" is part of the variable argument list, it is promoted
     to "double".  */
  varargs_fn (1, f);   /* { dg-warning "implicit" } */
}

/* There is no warning when an explicit cast is used to perform the
   conversion.  */

void
casts (void) 
{
  float local_f;
  _Complex float local_cf;

  local_f = (double)f + 1.0;                 /* { dg-bogus "implicit" } */
  local_f = (double)f - d;                   /* { dg-bogus "implicit" } */
  local_f = (double)1.0f + 1.0;              /* { dg-bogus "implicit" } */
  local_f = (double)1.0f - d;                /* { dg-bogus "implicit" } */

  local_cf = (_Complex double)cf + 1.0;      /* { dg-bogus "implicit" } */
  local_cf = (_Complex double)cf - d;        /* { dg-bogus "implicit" } */
  local_cf = (_Complex double)cf + 1.0 * ID; /* { dg-bogus "implicit" } */
  local_cf = (_Complex double)cf - cd;       /* { dg-bogus "implicit" } */

  local_f = i ? (double)f : d;               /* { dg-bogus "implicit" } */
  i = (double)f == d;                        /* { dg-bogus "implicit" } */
  i = d != (double)f;                        /* { dg-bogus "implicit" } */
}

/* There is no warning on conversions that occur in assignment (and
   assignment-like) contexts.  */

void 
assignments (void)
{
  d = f;           /* { dg-bogus "implicit" } */
  double_fn (f);   /* { dg-bogus "implicit" } */
  d = float_fn (); /* { dg-bogus "implicit" } */
}

/* There is no warning in non-evaluated contexts.  */

void
non_evaluated (void)
{
  s = sizeof (f + 1.0);             /* { dg-bogus "implicit" } */
  s = __alignof__ (f + 1.0);        /* { dg-bogus "implicit" } */
  d = (__typeof__(f + 1.0))f;       /* { dg-bogus "implicit" } */
  s = sizeof (i ? f : d);           /* { dg-bogus "implicit" } */
}