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

Collapse All | Expand All

(-)gcc/c-family/c-common.c (-21 / +40 lines)
Lines 2517-2526 shorten_binary_op (tree result_type, tre Link Here
2517
   Function allows conversions between types of different signedness and
2517
   Function allows conversions between types of different signedness and
2518
   does not return true in that case.  Function can produce signedness
2518
   does not return true in that case.  Function can produce signedness
2519
   warnings if PRODUCE_WARNS is true.  */
2519
   warnings if PRODUCE_WARNS is true.  */
2520
bool
2520
enum conversion_safety
2521
unsafe_conversion_p (tree type, tree expr, bool produce_warns)
2521
unsafe_conversion_p (tree type, tree expr, bool produce_warns)
2522
{
2522
{
2523
  bool give_warning = false;
2523
  enum conversion_safety give_warning = SAFE_CONVERSION; /* is 0 or false */
2524
  tree expr_type = TREE_TYPE (expr);
2524
  tree expr_type = TREE_TYPE (expr);
2525
  location_t loc = EXPR_LOC_OR_HERE (expr);
2525
  location_t loc = EXPR_LOC_OR_HERE (expr);
2526
2526
Lines 2532-2538 unsafe_conversion_p (tree type, tree exp Link Here
2532
	  && TREE_CODE (type) == INTEGER_TYPE)
2532
	  && TREE_CODE (type) == INTEGER_TYPE)
2533
	{
2533
	{
2534
	  if (!real_isinteger (TREE_REAL_CST_PTR (expr), TYPE_MODE (expr_type)))
2534
	  if (!real_isinteger (TREE_REAL_CST_PTR (expr), TYPE_MODE (expr_type)))
2535
	    give_warning = true;
2535
	    give_warning = UNSAFE_REAL;
2536
	}
2536
	}
2537
      /* Warn for an integer constant that does not fit into integer type.  */
2537
      /* Warn for an integer constant that does not fit into integer type.  */
2538
      else if (TREE_CODE (expr_type) == INTEGER_TYPE
2538
      else if (TREE_CODE (expr_type) == INTEGER_TYPE
Lines 2553-2559 unsafe_conversion_p (tree type, tree exp Link Here
2553
			    " constant value to negative integer");
2553
			    " constant value to negative integer");
2554
	    }
2554
	    }
2555
	  else
2555
	  else
2556
	    give_warning = true;
2556
	    give_warning = UNSAFE_OTHER;
2557
	}
2557
	}
2558
      else if (TREE_CODE (type) == REAL_TYPE)
2558
      else if (TREE_CODE (type) == REAL_TYPE)
2559
	{
2559
	{
Lines 2562-2568 unsafe_conversion_p (tree type, tree exp Link Here
2562
	    {
2562
	    {
2563
	      REAL_VALUE_TYPE a = real_value_from_int_cst (0, expr);
2563
	      REAL_VALUE_TYPE a = real_value_from_int_cst (0, expr);
2564
	      if (!exact_real_truncate (TYPE_MODE (type), &a))
2564
	      if (!exact_real_truncate (TYPE_MODE (type), &a))
2565
		give_warning = true;
2565
		give_warning = UNSAFE_REAL;
2566
	    }
2566
	    }
2567
	  /* Warn for a real constant that does not fit into a smaller
2567
	  /* Warn for a real constant that does not fit into a smaller
2568
	     real type.  */
2568
	     real type.  */
Lines 2571-2577 unsafe_conversion_p (tree type, tree exp Link Here
2571
	    {
2571
	    {
2572
	      REAL_VALUE_TYPE a = TREE_REAL_CST (expr);
2572
	      REAL_VALUE_TYPE a = TREE_REAL_CST (expr);
2573
	      if (!exact_real_truncate (TYPE_MODE (type), &a))
2573
	      if (!exact_real_truncate (TYPE_MODE (type), &a))
2574
		give_warning = true;
2574
		give_warning = UNSAFE_REAL;
2575
	    }
2575
	    }
2576
	}
2576
	}
2577
    }
2577
    }
Lines 2580-2586 unsafe_conversion_p (tree type, tree exp Link Here
2580
      /* Warn for real types converted to integer types.  */
2580
      /* Warn for real types converted to integer types.  */
2581
      if (TREE_CODE (expr_type) == REAL_TYPE
2581
      if (TREE_CODE (expr_type) == REAL_TYPE
2582
	  && TREE_CODE (type) == INTEGER_TYPE)
2582
	  && TREE_CODE (type) == INTEGER_TYPE)
2583
	give_warning = true;
2583
	give_warning = UNSAFE_REAL;
2584
2584
2585
      else if (TREE_CODE (expr_type) == INTEGER_TYPE
2585
      else if (TREE_CODE (expr_type) == INTEGER_TYPE
2586
	       && TREE_CODE (type) == INTEGER_TYPE)
2586
	       && TREE_CODE (type) == INTEGER_TYPE)
Lines 2618-2624 unsafe_conversion_p (tree type, tree exp Link Here
2618
			  && int_fits_type_p (op1, c_common_signed_type (type))
2618
			  && int_fits_type_p (op1, c_common_signed_type (type))
2619
			  && int_fits_type_p (op1,
2619
			  && int_fits_type_p (op1,
2620
					      c_common_unsigned_type (type))))
2620
					      c_common_unsigned_type (type))))
2621
		    return false;
2621
		    return SAFE_CONVERSION;
2622
		  /* If constant is unsigned and fits in the target
2622
		  /* If constant is unsigned and fits in the target
2623
		     type, then the result will also fit.  */
2623
		     type, then the result will also fit.  */
2624
		  else if ((TREE_CODE (op0) == INTEGER_CST
2624
		  else if ((TREE_CODE (op0) == INTEGER_CST
Lines 2627-2638 unsafe_conversion_p (tree type, tree exp Link Here
2627
			   || (TREE_CODE (op1) == INTEGER_CST
2627
			   || (TREE_CODE (op1) == INTEGER_CST
2628
			       && unsigned1
2628
			       && unsigned1
2629
			       && int_fits_type_p (op1, type)))
2629
			       && int_fits_type_p (op1, type)))
2630
		    return false;
2630
		    return SAFE_CONVERSION;
2631
		}
2631
		}
2632
	    }
2632
	    }
2633
	  /* Warn for integer types converted to smaller integer types.  */
2633
	  /* Warn for integer types converted to smaller integer types.  */
2634
	  if (TYPE_PRECISION (type) < TYPE_PRECISION (expr_type))
2634
	  if (TYPE_PRECISION (type) < TYPE_PRECISION (expr_type))
2635
	    give_warning = true;
2635
	    give_warning = UNSAFE_OTHER;
2636
2636
2637
	  /* When they are the same width but different signedness,
2637
	  /* When they are the same width but different signedness,
2638
	     then the value may change.  */
2638
	     then the value may change.  */
Lines 2668-2681 unsafe_conversion_p (tree type, tree exp Link Here
2668
2668
2669
	  if (!exact_real_truncate (TYPE_MODE (type), &real_low_bound)
2669
	  if (!exact_real_truncate (TYPE_MODE (type), &real_low_bound)
2670
	      || !exact_real_truncate (TYPE_MODE (type), &real_high_bound))
2670
	      || !exact_real_truncate (TYPE_MODE (type), &real_high_bound))
2671
	    give_warning = true;
2671
	    give_warning = UNSAFE_OTHER;
2672
	}
2672
	}
2673
2673
2674
      /* Warn for real types converted to smaller real types.  */
2674
      /* Warn for real types converted to smaller real types.  */
2675
      else if (TREE_CODE (expr_type) == REAL_TYPE
2675
      else if (TREE_CODE (expr_type) == REAL_TYPE
2676
	       && TREE_CODE (type) == REAL_TYPE
2676
	       && TREE_CODE (type) == REAL_TYPE
2677
	       && TYPE_PRECISION (type) < TYPE_PRECISION (expr_type))
2677
	       && TYPE_PRECISION (type) < TYPE_PRECISION (expr_type))
2678
	give_warning = true;
2678
	give_warning = UNSAFE_REAL;
2679
    }
2679
    }
2680
2680
2681
  return give_warning;
2681
  return give_warning;
Lines 2689-2696 conversion_warning (tree type, tree expr Link Here
2689
{
2689
{
2690
  tree expr_type = TREE_TYPE (expr);
2690
  tree expr_type = TREE_TYPE (expr);
2691
  location_t loc = EXPR_LOC_OR_HERE (expr);
2691
  location_t loc = EXPR_LOC_OR_HERE (expr);
2692
  enum conversion_safety conversion_kind;
2692
2693
2693
  if (!warn_conversion && !warn_sign_conversion)
2694
  if (!warn_conversion && !warn_sign_conversion && !warn_float_conversion)
2694
    return;
2695
    return;
2695
2696
2696
  switch (TREE_CODE (expr))
2697
  switch (TREE_CODE (expr))
Lines 2717-2726 conversion_warning (tree type, tree expr Link Here
2717
2718
2718
    case REAL_CST:
2719
    case REAL_CST:
2719
    case INTEGER_CST:
2720
    case INTEGER_CST:
2720
      if (unsafe_conversion_p (type, expr, true))
2721
      conversion_kind = unsafe_conversion_p (type, expr, true);
2721
	warning_at (loc, OPT_Wconversion,
2722
      if(conversion_kind == UNSAFE_REAL) 
2722
		    "conversion to %qT alters %qT constant value",
2723
	{
2723
		    type, expr_type);
2724
	  warning_at (loc, OPT_Wfloat_conversion,
2725
		      "conversion to %qT alters %qT constant value",
2726
		      type, expr_type);
2727
	} 
2728
      else if(conversion_kind)
2729
	{
2730
	  warning_at (loc, OPT_Wconversion,
2731
		      "conversion to %qT alters %qT constant value",
2732
		      type, expr_type);
2733
	}
2724
      return;
2734
      return;
2725
2735
2726
    case COND_EXPR:
2736
    case COND_EXPR:
Lines 2736-2745 conversion_warning (tree type, tree expr Link Here
2736
      }
2746
      }
2737
2747
2738
    default: /* 'expr' is not a constant.  */
2748
    default: /* 'expr' is not a constant.  */
2739
      if (unsafe_conversion_p (type, expr, true))
2749
      conversion_kind = unsafe_conversion_p (type, expr, true);
2740
	warning_at (loc, OPT_Wconversion,
2750
      if(conversion_kind == UNSAFE_REAL)
2741
		    "conversion to %qT from %qT may alter its value",
2751
	{
2742
		    type, expr_type);
2752
	  warning_at (loc, OPT_Wfloat_conversion,
2753
		      "conversion to %qT from %qT may alter its value",
2754
		      type, expr_type);
2755
	} 
2756
      else if(conversion_kind)
2757
	{
2758
	  warning_at (loc, OPT_Wconversion,
2759
		      "conversion to %qT from %qT may alter its value",
2760
		      type, expr_type);
2761
	}
2743
    }
2762
    }
2744
}
2763
}
2745
2764
(-)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 variables 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/Wconversion-real.c (-14 / +14 lines)
Lines 2-9 Link Here
2
2
3
/* { dg-do compile } */
3
/* { dg-do compile } */
4
/* { dg-skip-if "doubles are floats" { "avr-*-*" } { "*" } { "" } } */
4
/* { dg-skip-if "doubles are floats" { "avr-*-*" } { "*" } { "" } } */
5
/* { dg-options "-std=c99 -Wconversion" { target c } } */
5
/* { dg-options "-std=c99 -Wfloat-conversion" { target c } } */
6
/* { dg-options "-Wconversion" { target c++ } } */
6
/* { dg-options "-Wfloat-conversion" { target c++ } } */
7
/* { dg-require-effective-target large_double } */
7
/* { dg-require-effective-target large_double } */
8
8
9
float  vfloat;
9
float  vfloat;
Lines 20-37 void h (void) Link Here
20
  double d = 0;
20
  double d = 0;
21
  long double ld = 0;
21
  long double ld = 0;
22
22
23
  ffloat (3.1); /* { dg-warning "conversion" } */
23
  ffloat (3.1); /* { dg-warning "float-conversion" } */
24
  vfloat = 3.1; /* { dg-warning "conversion" } */
24
  vfloat = 3.1; /* { dg-warning "float-conversion" } */
25
  ffloat (3.1L); /* { dg-warning "conversion" } */
25
  ffloat (3.1L); /* { dg-warning "float-conversion" } */
26
  vfloat = 3.1L;  /* { dg-warning "conversion" } */
26
  vfloat = 3.1L;  /* { dg-warning "float-conversion" } */
27
  fdouble (3.1L); /* { dg-warning "conversion" "" { target large_long_double } } */
27
  fdouble (3.1L); /* { dg-warning "float-conversion" "" { target large_long_double } } */
28
  vdouble = 3.1L; /* { dg-warning "conversion" "" { target large_long_double } } */
28
  vdouble = 3.1L; /* { dg-warning "float-conversion" "" { target large_long_double } } */
29
  ffloat (vdouble); /* { dg-warning "conversion" } */
29
  ffloat (vdouble); /* { dg-warning "float-conversion" } */
30
  vfloat = vdouble; /* { dg-warning "conversion" } */
30
  vfloat = vdouble; /* { dg-warning "float-conversion" } */
31
  ffloat (vlongdouble); /* { dg-warning "conversion" } */
31
  ffloat (vlongdouble); /* { dg-warning "float-conversion" } */
32
  vfloat = vlongdouble; /* { dg-warning "conversion" } */
32
  vfloat = vlongdouble; /* { dg-warning "float-conversion" } */
33
  fdouble (vlongdouble); /* { dg-warning "conversion" "" { target large_long_double } } */
33
  fdouble (vlongdouble); /* { dg-warning "float-conversion" "" { target large_long_double } } */
34
  vdouble = vlongdouble; /* { dg-warning "conversion" "" { target large_long_double } } */
34
  vdouble = vlongdouble; /* { dg-warning "float-conversion" "" { target large_long_double } } */
35
35
36
36
37
  ffloat ((float) 3.1); 
37
  ffloat ((float) 3.1); 
(-)gcc/testsuite/gcc.dg/Wconversion-real-integer.c (-10 / +10 lines)
Lines 25-42 void h (void) Link Here
25
  float  f = 3;
25
  float  f = 3;
26
  double d = 3;
26
  double d = 3;
27
27
28
  fsi (3.1f); /* { dg-warning "conversion" } */
28
  fsi (3.1f); /* { dg-warning "float-conversion" } */
29
  si = 3.1f; /* { dg-warning "conversion" } */
29
  si = 3.1f; /* { dg-warning "float-conversion" } */
30
  fsi (3.1);  /* { dg-warning "conversion" } */
30
  fsi (3.1);  /* { dg-warning "float-conversion" } */
31
  si = 3.1;  /* { dg-warning "conversion" } */
31
  si = 3.1;  /* { dg-warning "float-conversion" } */
32
  fsi (d);    /* { dg-warning "conversion" } */
32
  fsi (d);    /* { dg-warning "float-conversion" } */
33
  si = d;    /* { dg-warning "conversion" } */
33
  si = d;    /* { dg-warning "float-conversion" } */
34
  fui (-1.0); /* { dg-warning "overflow" } */
34
  fui (-1.0); /* { dg-warning "overflow" } */
35
  ui = -1.0;   /* { dg-warning "overflow" } */
35
  ui = -1.0;   /* { dg-warning "overflow" } */
36
  ffloat (INT_MAX);  /* { dg-warning "conversion" } */
36
  ffloat (INT_MAX);  /* { dg-warning "float-conversion" } */
37
  vfloat = INT_MAX;  /* { dg-warning "conversion" } */
37
  vfloat = INT_MAX;  /* { dg-warning "float-conversion" } */
38
  ffloat (16777217); /* { dg-warning "conversion" } */
38
  ffloat (16777217); /* { dg-warning "float-conversion" } */
39
  vfloat = 16777217; /* { dg-warning "conversion" } */
39
  vfloat = 16777217; /* { dg-warning "float-conversion" } */
40
  ffloat (si); /* { dg-warning "conversion" } */
40
  ffloat (si); /* { dg-warning "conversion" } */
41
  vfloat = si; /* { dg-warning "conversion" } */
41
  vfloat = si; /* { dg-warning "conversion" } */
42
  ffloat (ui); /* { dg-warning "conversion" } */
42
  ffloat (ui); /* { dg-warning "conversion" } */
(-)gcc/testsuite/gcc.dg/pr35635.c (-2 / +2 lines)
Lines 45-51 void func2() Link Here
45
45
46
  /* At least one branch of ? does not fit in the destination, thus
46
  /* At least one branch of ? does not fit in the destination, thus
47
     warn.  */
47
     warn.  */
48
  schar_x = bar != 0 ? 2.1 : 10; /* { dg-warning "conversion" } */
48
  schar_x = bar != 0 ? 2.1 : 10; /* { dg-warning "float-conversion" } */
49
  schar_x = bar != 0 ? (signed char) 1024: -1024; /* { dg-warning "conversion" } */
49
  schar_x = bar != 0 ? (signed char) 1024: -1024; /* { dg-warning "conversion" } */
50
}
50
}
51
51
Lines 61-67 void func3() Link Here
61
61
62
  /* At least one branch of ? does not fit in the destination, thus
62
  /* At least one branch of ? does not fit in the destination, thus
63
     warn.  */
63
     warn.  */
64
  uchar_x = bar != 0 ? 2.1 : 10; /* { dg-warning "conversion" } */
64
  uchar_x = bar != 0 ? 2.1 : 10; /* { dg-warning "float-conversion" } */
65
  uchar_x = bar != 0 
65
  uchar_x = bar != 0 
66
    ? (unsigned char) 1024 
66
    ? (unsigned char) 1024 
67
    : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
67
    : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */

Return to bug 53001