View | Details | Return to bug 53001 | Differences between
and this patch

Collapse All | Expand All

(-)gcc/c-family/c-common.c (-18 / +29 lines)
Lines 2518-2524 shorten_binary_op (tree result_type, tre Link Here
2518
}
2518
}
2519
2519
2520
/* Checks if expression EXPR of real/integer type cannot be converted 
2520
/* Checks if expression EXPR of real/integer type cannot be converted 
2521
   to the real/integer type TYPE. Function returns true when:
2521
   to the real/integer type TYPE. Function returns non-zero when:
2522
	* EXPR is a constant which cannot be exactly converted to TYPE 
2522
	* EXPR is a constant which cannot be exactly converted to TYPE 
2523
	* EXPR is not a constant and size of EXPR's type > than size of TYPE, 
2523
	* EXPR is not a constant and size of EXPR's type > than size of TYPE, 
2524
	  for EXPR type and TYPE being both integers or both real.
2524
	  for EXPR type and TYPE being both integers or both real.
Lines 2526-2537 shorten_binary_op (tree result_type, tre Link Here
2526
	* EXPR is not a constant of integer type which cannot be 
2526
	* EXPR is not a constant of integer type which cannot be 
2527
	  exactly converted to real type.  
2527
	  exactly converted to real type.  
2528
   Function allows conversions between types of different signedness and
2528
   Function allows conversions between types of different signedness and
2529
   does not return true in that case.  Function can produce signedness
2529
   can return SAFE_CONVERSION (zero) in that case.  Function can produce
2530
   warnings if PRODUCE_WARNS is true.  */
2530
   signedness warnings if PRODUCE_WARNS is true.  */
2531
bool
2531
enum conversion_safety
2532
unsafe_conversion_p (tree type, tree expr, bool produce_warns)
2532
unsafe_conversion_p (tree type, tree expr, bool produce_warns)
2533
{
2533
{
2534
  bool give_warning = false;
2534
  enum conversion_safety give_warning = SAFE_CONVERSION; /* is 0 or false */
2535
  tree expr_type = TREE_TYPE (expr);
2535
  tree expr_type = TREE_TYPE (expr);
2536
  location_t loc = EXPR_LOC_OR_HERE (expr);
2536
  location_t loc = EXPR_LOC_OR_HERE (expr);
2537
2537
Lines 2543-2549 unsafe_conversion_p (tree type, tree exp Link Here
2543
	  && TREE_CODE (type) == INTEGER_TYPE)
2543
	  && TREE_CODE (type) == INTEGER_TYPE)
2544
	{
2544
	{
2545
	  if (!real_isinteger (TREE_REAL_CST_PTR (expr), TYPE_MODE (expr_type)))
2545
	  if (!real_isinteger (TREE_REAL_CST_PTR (expr), TYPE_MODE (expr_type)))
2546
	    give_warning = true;
2546
	    give_warning = UNSAFE_REAL;
2547
	}
2547
	}
2548
      /* Warn for an integer constant that does not fit into integer type.  */
2548
      /* Warn for an integer constant that does not fit into integer type.  */
2549
      else if (TREE_CODE (expr_type) == INTEGER_TYPE
2549
      else if (TREE_CODE (expr_type) == INTEGER_TYPE
Lines 2564-2570 unsafe_conversion_p (tree type, tree exp Link Here
2564
			    " constant value to negative integer");
2564
			    " constant value to negative integer");
2565
	    }
2565
	    }
2566
	  else
2566
	  else
2567
	    give_warning = true;
2567
	    give_warning = UNSAFE_OTHER;
2568
	}
2568
	}
2569
      else if (TREE_CODE (type) == REAL_TYPE)
2569
      else if (TREE_CODE (type) == REAL_TYPE)
2570
	{
2570
	{
Lines 2573-2579 unsafe_conversion_p (tree type, tree exp Link Here
2573
	    {
2573
	    {
2574
	      REAL_VALUE_TYPE a = real_value_from_int_cst (0, expr);
2574
	      REAL_VALUE_TYPE a = real_value_from_int_cst (0, expr);
2575
	      if (!exact_real_truncate (TYPE_MODE (type), &a))
2575
	      if (!exact_real_truncate (TYPE_MODE (type), &a))
2576
		give_warning = true;
2576
		give_warning = UNSAFE_REAL;
2577
	    }
2577
	    }
2578
	  /* Warn for a real constant that does not fit into a smaller
2578
	  /* Warn for a real constant that does not fit into a smaller
2579
	     real type.  */
2579
	     real type.  */
Lines 2582-2588 unsafe_conversion_p (tree type, tree exp Link Here
2582
	    {
2582
	    {
2583
	      REAL_VALUE_TYPE a = TREE_REAL_CST (expr);
2583
	      REAL_VALUE_TYPE a = TREE_REAL_CST (expr);
2584
	      if (!exact_real_truncate (TYPE_MODE (type), &a))
2584
	      if (!exact_real_truncate (TYPE_MODE (type), &a))
2585
		give_warning = true;
2585
		give_warning = UNSAFE_REAL;
2586
	    }
2586
	    }
2587
	}
2587
	}
2588
    }
2588
    }
Lines 2591-2597 unsafe_conversion_p (tree type, tree exp Link Here
2591
      /* Warn for real types converted to integer types.  */
2591
      /* Warn for real types converted to integer types.  */
2592
      if (TREE_CODE (expr_type) == REAL_TYPE
2592
      if (TREE_CODE (expr_type) == REAL_TYPE
2593
	  && TREE_CODE (type) == INTEGER_TYPE)
2593
	  && TREE_CODE (type) == INTEGER_TYPE)
2594
	give_warning = true;
2594
	give_warning = UNSAFE_REAL;
2595
2595
2596
      else if (TREE_CODE (expr_type) == INTEGER_TYPE
2596
      else if (TREE_CODE (expr_type) == INTEGER_TYPE
2597
	       && TREE_CODE (type) == INTEGER_TYPE)
2597
	       && TREE_CODE (type) == INTEGER_TYPE)
Lines 2629-2635 unsafe_conversion_p (tree type, tree exp Link Here
2629
			  && int_fits_type_p (op1, c_common_signed_type (type))
2629
			  && int_fits_type_p (op1, c_common_signed_type (type))
2630
			  && int_fits_type_p (op1,
2630
			  && int_fits_type_p (op1,
2631
					      c_common_unsigned_type (type))))
2631
					      c_common_unsigned_type (type))))
2632
		    return false;
2632
		    return SAFE_CONVERSION;
2633
		  /* If constant is unsigned and fits in the target
2633
		  /* If constant is unsigned and fits in the target
2634
		     type, then the result will also fit.  */
2634
		     type, then the result will also fit.  */
2635
		  else if ((TREE_CODE (op0) == INTEGER_CST
2635
		  else if ((TREE_CODE (op0) == INTEGER_CST
Lines 2638-2649 unsafe_conversion_p (tree type, tree exp Link Here
2638
			   || (TREE_CODE (op1) == INTEGER_CST
2638
			   || (TREE_CODE (op1) == INTEGER_CST
2639
			       && unsigned1
2639
			       && unsigned1
2640
			       && int_fits_type_p (op1, type)))
2640
			       && int_fits_type_p (op1, type)))
2641
		    return false;
2641
		    return SAFE_CONVERSION;
2642
		}
2642
		}
2643
	    }
2643
	    }
2644
	  /* Warn for integer types converted to smaller integer types.  */
2644
	  /* Warn for integer types converted to smaller integer types.  */
2645
	  if (TYPE_PRECISION (type) < TYPE_PRECISION (expr_type))
2645
	  if (TYPE_PRECISION (type) < TYPE_PRECISION (expr_type))
2646
	    give_warning = true;
2646
	    give_warning = UNSAFE_OTHER;
2647
2647
2648
	  /* When they are the same width but different signedness,
2648
	  /* When they are the same width but different signedness,
2649
	     then the value may change.  */
2649
	     then the value may change.  */
Lines 2679-2692 unsafe_conversion_p (tree type, tree exp Link Here
2679
2679
2680
	  if (!exact_real_truncate (TYPE_MODE (type), &real_low_bound)
2680
	  if (!exact_real_truncate (TYPE_MODE (type), &real_low_bound)
2681
	      || !exact_real_truncate (TYPE_MODE (type), &real_high_bound))
2681
	      || !exact_real_truncate (TYPE_MODE (type), &real_high_bound))
2682
	    give_warning = true;
2682
	    give_warning = UNSAFE_OTHER;
2683
	}
2683
	}
2684
2684
2685
      /* Warn for real types converted to smaller real types.  */
2685
      /* Warn for real types converted to smaller real types.  */
2686
      else if (TREE_CODE (expr_type) == REAL_TYPE
2686
      else if (TREE_CODE (expr_type) == REAL_TYPE
2687
	       && TREE_CODE (type) == REAL_TYPE
2687
	       && TREE_CODE (type) == REAL_TYPE
2688
	       && TYPE_PRECISION (type) < TYPE_PRECISION (expr_type))
2688
	       && TYPE_PRECISION (type) < TYPE_PRECISION (expr_type))
2689
	give_warning = true;
2689
	give_warning = UNSAFE_REAL;
2690
    }
2690
    }
2691
2691
2692
  return give_warning;
2692
  return give_warning;
Lines 2700-2707 conversion_warning (tree type, tree expr Link Here
2700
{
2700
{
2701
  tree expr_type = TREE_TYPE (expr);
2701
  tree expr_type = TREE_TYPE (expr);
2702
  location_t loc = EXPR_LOC_OR_HERE (expr);
2702
  location_t loc = EXPR_LOC_OR_HERE (expr);
2703
  enum conversion_safety conversion_kind;
2703
2704
2704
  if (!warn_conversion && !warn_sign_conversion)
2705
  if (!warn_conversion && !warn_sign_conversion && !warn_float_conversion)
2705
    return;
2706
    return;
2706
2707
2707
  switch (TREE_CODE (expr))
2708
  switch (TREE_CODE (expr))
Lines 2728-2734 conversion_warning (tree type, tree expr Link Here
2728
2729
2729
    case REAL_CST:
2730
    case REAL_CST:
2730
    case INTEGER_CST:
2731
    case INTEGER_CST:
2731
      if (unsafe_conversion_p (type, expr, true))
2732
      conversion_kind = unsafe_conversion_p (type, expr, true);
2733
      if (conversion_kind == UNSAFE_REAL)
2734
	warning_at (loc, OPT_Wfloat_conversion,
2735
		    "conversion to %qT alters %qT constant value",
2736
		    type, expr_type);
2737
      else if (conversion_kind)
2732
	warning_at (loc, OPT_Wconversion,
2738
	warning_at (loc, OPT_Wconversion,
2733
		    "conversion to %qT alters %qT constant value",
2739
		    "conversion to %qT alters %qT constant value",
2734
		    type, expr_type);
2740
		    type, expr_type);
Lines 2747-2753 conversion_warning (tree type, tree expr Link Here
2747
      }
2753
      }
2748
2754
2749
    default: /* 'expr' is not a constant.  */
2755
    default: /* 'expr' is not a constant.  */
2750
      if (unsafe_conversion_p (type, expr, true))
2756
      conversion_kind = unsafe_conversion_p (type, expr, true);
2757
      if (conversion_kind == UNSAFE_REAL)
2758
	warning_at (loc, OPT_Wfloat_conversion,
2759
		    "conversion to %qT from %qT may alter its value",
2760
		    type, expr_type);
2761
      else if (conversion_kind)
2751
	warning_at (loc, OPT_Wconversion,
2762
	warning_at (loc, OPT_Wconversion,
2752
		    "conversion to %qT from %qT may alter its value",
2763
		    "conversion to %qT from %qT may alter its value",
2753
		    type, expr_type);
2764
		    type, expr_type);
(-)gcc/c-family/c-common.h (-1 / +11 lines)
Lines 685-690 struct visibility_flags Link Here
685
  unsigned inlines_hidden : 1;	/* True when -finlineshidden in effect.  */
685
  unsigned inlines_hidden : 1;	/* True when -finlineshidden in effect.  */
686
};
686
};
687
687
688
/* These enumerators are possible types of unsafe conversions.
689
   SAFE_CONVERSION The conversion is safe
690
   UNSAFE_OTHER Another type of conversion with problems
691
   UNSAFE_SIGN Conversion between signed and unsigned integers
692
    which are all warned about immediately, so this is unused
693
   UNSAFE_REAL Conversions that reduce the precision of reals
694
    including conversions from reals to integers
695
 */
696
enum conversion_safety { SAFE_CONVERSION = 0, UNSAFE_OTHER, UNSAFE_SIGN, UNSAFE_REAL };
697
688
/* Global visibility options.  */
698
/* Global visibility options.  */
689
extern struct visibility_flags visibility_options;
699
extern struct visibility_flags visibility_options;
690
700
Lines 738-744 extern tree c_common_signed_type (tree); Link Here
738
extern tree c_common_signed_or_unsigned_type (int, tree);
748
extern tree c_common_signed_or_unsigned_type (int, tree);
739
extern void c_common_init_ts (void);
749
extern void c_common_init_ts (void);
740
extern tree c_build_bitfield_integer_type (unsigned HOST_WIDE_INT, int);
750
extern tree c_build_bitfield_integer_type (unsigned HOST_WIDE_INT, int);
741
extern bool unsafe_conversion_p (tree, tree, bool);
751
extern enum conversion_safety unsafe_conversion_p (tree, tree, bool);
742
extern bool decl_with_nonnull_addr_p (const_tree);
752
extern bool decl_with_nonnull_addr_p (const_tree);
743
extern tree c_fully_fold (tree, bool, bool *);
753
extern tree c_fully_fold (tree, bool, bool *);
744
extern tree decl_constant_value_for_optimization (tree);
754
extern tree decl_constant_value_for_optimization (tree);
(-)gcc/c-family/c.opt (+4 lines)
Lines 387-392 Werror-implicit-function-declaration Link Here
387
C ObjC RejectNegative Warning Alias(Werror=, implicit-function-declaration)
387
C ObjC RejectNegative Warning Alias(Werror=, implicit-function-declaration)
388
This switch is deprecated; use -Werror=implicit-function-declaration instead
388
This switch is deprecated; use -Werror=implicit-function-declaration instead
389
389
390
Wfloat-conversion
391
C ObjC C++ ObjC++ Var(warn_float_conversion) LangEnabledBy(C ObjC C++ ObjC++,Wconversion)
392
Warn for implicit type conversions that cause loss of floating point precision
393
390
Wfloat-equal
394
Wfloat-equal
391
C ObjC C++ ObjC++ Var(warn_float_equal) Warning
395
C ObjC C++ ObjC++ Var(warn_float_equal) Warning
392
Warn if testing floating point numbers for equality
396
Warn if testing floating point numbers for equality
(-)gcc/doc/invoke.texi (-1 / +10 lines)
Lines 263-269 Objective-C and Objective-C++ Dialects}. Link Here
263
-Wpointer-arith  -Wno-pointer-to-int-cast @gol
263
-Wpointer-arith  -Wno-pointer-to-int-cast @gol
264
-Wredundant-decls  -Wno-return-local-addr @gol
264
-Wredundant-decls  -Wno-return-local-addr @gol
265
-Wreturn-type  -Wsequence-point  -Wshadow @gol
265
-Wreturn-type  -Wsequence-point  -Wshadow @gol
266
-Wsign-compare  -Wsign-conversion  -Wsizeof-pointer-memaccess @gol
266
-Wsign-compare  -Wsign-conversion -Wfloat-conversion @gol
267
-Wsizeof-pointer-memaccess @gol
267
-Wstack-protector -Wstack-usage=@var{len} -Wstrict-aliasing @gol
268
-Wstack-protector -Wstack-usage=@var{len} -Wstrict-aliasing @gol
268
-Wstrict-aliasing=n @gol -Wstrict-overflow -Wstrict-overflow=@var{n} @gol
269
-Wstrict-aliasing=n @gol -Wstrict-overflow -Wstrict-overflow=@var{n} @gol
269
-Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{]} @gol
270
-Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{]} @gol
Lines 4570-4575 value, like assigning a signed integer e Link Here
4570
integer variable. An explicit cast silences the warning. In C, this
4571
integer variable. An explicit cast silences the warning. In C, this
4571
option is enabled also by @option{-Wconversion}.
4572
option is enabled also by @option{-Wconversion}.
4572
4573
4574
@item -Wfloat-conversion
4575
@opindex Wfloat-conversion
4576
@opindex Wno-float-conversion
4577
Warn for implicit conversions that reduce the precision of a real value.
4578
This includes conversions from real to integer, and from higher precision
4579
real to lower precision real values.  This option is also enabled by
4580
@option{-Wconversion}.
4581
4573
@item -Wsizeof-pointer-memaccess
4582
@item -Wsizeof-pointer-memaccess
4574
@opindex Wsizeof-pointer-memaccess
4583
@opindex Wsizeof-pointer-memaccess
4575
@opindex Wno-sizeof-pointer-memaccess
4584
@opindex Wno-sizeof-pointer-memaccess
(-)gcc/testsuite/c-c++-common/Wfloat-conversion.c (-65 / +38 lines)
Lines 1-85 Link Here
1
/* Test for diagnostics for Wconversion for floating-point.  */
1
/* Test for diagnostics for Wconversion for floating-point.  */
2
2
3
/* { dg-do compile } */
3
/* { dg-do compile } */
4
/* { dg-skip-if "doubles are floats" { "avr-*-*" } { "*" } { "" } } */
4
/* { dg-options "-std=c99 -Wfloat-conversion" { target c } } */
5
/* { dg-options "-std=c99 -Wconversion" { target c } } */
5
/* { dg-options "-Wfloat-conversion" { target c++ } } */
6
/* { dg-options "-Wconversion" { target c++ } } */
7
/* { dg-require-effective-target large_double } */
6
/* { dg-require-effective-target large_double } */
7
/* { dg-require-effective-target int32plus } */
8
/* { dg-require-effective-target double64plus } */
9
#include <limits.h>
8
10
9
float  vfloat;
11
float  vfloat;
10
double vdouble;
12
double vdouble;
11
long double vlongdouble;
13
long double vlongdouble;
14
int bar;
12
15
16
void fsi (signed int x);
17
void fui (unsigned int x);
13
void ffloat (float f);
18
void ffloat (float f);
14
void fdouble (double d);
19
void fdouble (double d);
15
void flongdouble (long double ld);
20
void flongdouble (long double ld);
16
21
17
void h (void)
22
void h (void)
18
{
23
{
24
  unsigned int ui = 3;
25
  int   si = 3;
26
  unsigned char uc = 3;
27
  signed char sc = 3;
19
  float f = 0;
28
  float f = 0;
20
  double d = 0;
29
  double d = 0;
21
  long double ld = 0;
30
  long double ld = 0;
22
31
23
  ffloat (3.1); /* { dg-warning "conversion" } */
32
  ffloat (3.1); /* { dg-warning "float-conversion" } */
24
  vfloat = 3.1; /* { dg-warning "conversion" } */
33
  vfloat = 3.1; /* { dg-warning "float-conversion" } */
25
  ffloat (3.1L); /* { dg-warning "conversion" } */
34
  ffloat (3.1L); /* { dg-warning "float-conversion" } */
26
  vfloat = 3.1L;  /* { dg-warning "conversion" } */
35
  vfloat = 3.1L;  /* { dg-warning "float-conversion" } */
27
  fdouble (3.1L); /* { dg-warning "conversion" "" { target large_long_double } } */
36
  fdouble (3.1L); /* { dg-warning "float-conversion" "" { target large_long_double } } */
28
  vdouble = 3.1L; /* { dg-warning "conversion" "" { target large_long_double } } */
37
  vdouble = 3.1L; /* { dg-warning "float-conversion" "" { target large_long_double } } */
29
  ffloat (vdouble); /* { dg-warning "conversion" } */
38
  ffloat (vdouble); /* { dg-warning "float-conversion" } */
30
  vfloat = vdouble; /* { dg-warning "conversion" } */
39
  vfloat = vdouble; /* { dg-warning "float-conversion" } */
31
  ffloat (vlongdouble); /* { dg-warning "conversion" } */
40
  ffloat (vlongdouble); /* { dg-warning "float-conversion" } */
32
  vfloat = vlongdouble; /* { dg-warning "conversion" } */
41
  vfloat = vlongdouble; /* { dg-warning "float-conversion" } */
33
  fdouble (vlongdouble); /* { dg-warning "conversion" "" { target large_long_double } } */
42
  fdouble (vlongdouble); /* { dg-warning "float-conversion" "" { target large_long_double } } */
34
  vdouble = vlongdouble; /* { dg-warning "conversion" "" { target large_long_double } } */
43
  vdouble = vlongdouble; /* { dg-warning "float-conversion" "" { target large_long_double } } */
35
44
36
45
  fsi (3.1f); /* { dg-warning "float-conversion" } */
37
  ffloat ((float) 3.1); 
46
  si = 3.1f; /* { dg-warning "float-conversion" } */
38
  vfloat = (float) 3.1;
47
  fsi (3.1);  /* { dg-warning "float-conversion" } */
39
  ffloat ((float) 3.1L);
48
  si = 3.1;  /* { dg-warning "float-conversion" } */
40
  vfloat = (float) 3.1L; 
49
  fsi (d);    /* { dg-warning "float-conversion" } */
41
  fdouble ((double) 3.1L); 
50
  si = d;    /* { dg-warning "float-conversion" } */
42
  vdouble = (double) 3.1L; 
51
  ffloat (INT_MAX);  /* { dg-warning "float-conversion" } */
43
  ffloat ((float) vdouble); 
52
  vfloat = INT_MAX;  /* { dg-warning "float-conversion" } */
44
  vfloat = (float) vdouble; 
53
  ffloat (16777217); /* { dg-warning "float-conversion" } */
45
  ffloat ((float) vlongdouble); 
54
  vfloat = 16777217; /* { dg-warning "float-conversion" } */
46
  vfloat = (float) vlongdouble;
55
47
  fdouble ((double) vlongdouble);
56
  sc = bar != 0 ? 2.1 : 10; /* { dg-warning "float-conversion" } */
48
  vdouble = (double) vlongdouble;
57
  uc = bar != 0 ? 2.1 : 10; /* { dg-warning "float-conversion" } */
49
50
51
  ffloat (3.0);
52
  vfloat = 3.0;
53
  ffloat (3.1f);
54
  vfloat = 3.1f;
55
  ffloat (0.25L);
56
  vfloat = 0.25L;
57
58
59
  fdouble (3.0);
60
  vdouble = 3.0;
61
  fdouble (3.1f);
62
  vdouble = 3.1f;
63
  fdouble (0.25L);
64
  vdouble = 0.25L;
65
66
  flongdouble (3.0);
67
  vlongdouble = 3.0;
68
  flongdouble (3.1f);
69
  vlongdouble = 3.1f;
70
  flongdouble (0.25L);
71
  vlongdouble = 0.25L;
72
73
  ffloat (f);
74
  vfloat = f;
75
  fdouble (f);
76
  vdouble = f;
77
  fdouble (d);
78
  vdouble = d;
79
  flongdouble (f);
80
  vlongdouble = f;
81
  flongdouble (d);
82
  vlongdouble = d;
83
  flongdouble (ld);
84
  vlongdouble = ld;
85
}
58
}

Return to bug 53001