This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch, c, ping] Fix PR c/48956: diagnostics for conversions involving complex types (reviewed)


On 04/17/2015 05:01 AM, Mikhail Maltsev wrote:
> I would like to ping the following patch:
> https://gcc.gnu.org/ml/gcc-patches/2014-12/msg01925.html
> Review: https://gcc.gnu.org/ml/gcc-patches/2015-01/msg02672.html
> 
> I fixed minor issues mentioned in the review and updated the changelog
> message. Rebased on current trunk (r222157), bootstrapped and regtested
> on x86_64-unknown-linux-gnu.
> If it is OK for trunk, please assist with applying (I don't have write
> access), and I will then create a new PR in bugzilla for the remaining
> cases mentioned in review.

Since I now have write access, I am installing this patch into trunk. I
discovered and fixed a minor issue in testcase (no warning when
converting from long to int on -m32; changed long to long long. I hope
it's OK to be considered as obvious fix).

Bootstrapped/regtested on x86_64-unknown-linux-gnu {,-m32}.

-- 
Regards,
    Mikhail Maltsev
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 48d483e..199ba43 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,13 @@
+2015-05-15  Mikhail Maltsev  <maltsevm@gmail.com>
+
+	PR c/48956
+	* c-common.c (int_safely_convertible_to_real_p): Define.
+	(unsafe_conversion_p): Check conversions involving complex types.
+	(conversion_warning): Add new warning message for conversions which
+	discard imaginary component.
+	* c-common.h: (enum conversion_safety): Add new enumerator for such
+	conversions.
+
 2015-05-14  Marek Polacek  <polacek@redhat.com>
 
 	PR c/66066
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 31c4c0d..8c7fdd2 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -2707,17 +2707,42 @@ shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise)
   return result_type;
 }
 
-/* Checks if expression EXPR of real/integer type cannot be converted
-   to the real/integer type TYPE. Function returns non-zero when:
+/* Returns true iff any integer value of type FROM_TYPE can be represented as
+   real of type TO_TYPE.  This is a helper function for unsafe_conversion_p.  */
+
+static bool
+int_safely_convertible_to_real_p (const_tree from_type, const_tree to_type)
+{
+  tree type_low_bound = TYPE_MIN_VALUE (from_type);
+  tree type_high_bound = TYPE_MAX_VALUE (from_type);
+  REAL_VALUE_TYPE real_low_bound =
+	  real_value_from_int_cst (0, type_low_bound);
+  REAL_VALUE_TYPE real_high_bound =
+	  real_value_from_int_cst (0, type_high_bound);
+
+  return exact_real_truncate (TYPE_MODE (to_type), &real_low_bound)
+	 && exact_real_truncate (TYPE_MODE (to_type), &real_high_bound);
+}
+
+/* Checks if expression EXPR of complex/real/integer type cannot be converted
+   to the complex/real/integer type TYPE.  Function returns non-zero when:
 	* EXPR is a constant which cannot be exactly converted to TYPE.
 	* EXPR is not a constant and size of EXPR's type > than size of TYPE,
-	  for EXPR type and TYPE being both integers or both real.
+	  for EXPR type and TYPE being both integers or both real, or both
+	  complex.
+	* EXPR is not a constant of complex type and TYPE is a real or
+	  an integer.
 	* EXPR is not a constant of real type and TYPE is an integer.
 	* EXPR is not a constant of integer type which cannot be
 	  exactly converted to real type.
+
    Function allows conversions between types of different signedness and
    can return SAFE_CONVERSION (zero) in that case.  Function can produce
-   signedness warnings if PRODUCE_WARNS is true.  */
+   signedness warnings if PRODUCE_WARNS is true.
+
+   Function allows conversions from complex constants to non-complex types,
+   provided that imaginary part is zero and real part can be safely converted
+   to TYPE.  */
 
 enum conversion_safety
 unsafe_conversion_p (location_t loc, tree type, tree expr, bool produce_warns)
@@ -2728,6 +2753,11 @@ unsafe_conversion_p (location_t loc, tree type, tree expr, bool produce_warns)
 
   if (TREE_CODE (expr) == REAL_CST || TREE_CODE (expr) == INTEGER_CST)
     {
+      /* If type is complex, we are interested in compatibility with
+	 underlying type.  */
+      if (TREE_CODE (type) == COMPLEX_TYPE)
+	  type = TREE_TYPE (type);
+
       /* Warn for real constant that is not an exact integer converted
 	 to integer type.  */
       if (TREE_CODE (expr_type) == REAL_TYPE
@@ -2777,6 +2807,63 @@ unsafe_conversion_p (location_t loc, tree type, tree expr, bool produce_warns)
 	    }
 	}
     }
+
+  else if (TREE_CODE (expr) == COMPLEX_CST)
+    {
+      tree imag_part = TREE_IMAGPART (expr);
+      /* Conversion from complex constant with zero imaginary part,
+	 perform check for conversion of real part.  */
+      if ((TREE_CODE (imag_part) == REAL_CST
+	   && real_zerop (imag_part))
+	  || (TREE_CODE (imag_part) == INTEGER_CST
+	      && integer_zerop (imag_part)))
+	/* Note: in this branch we use recursive call to unsafe_conversion_p
+	   with different type of EXPR, but it is still safe, because when EXPR
+	   is a constant, it's type is not used in text of generated warnings
+	   (otherwise they could sound misleading).  */
+	return unsafe_conversion_p (loc, type, TREE_REALPART (expr),
+				    produce_warns);
+      /* Conversion from complex constant with non-zero imaginary part.  */
+      else
+	{
+	  /* Conversion to complex type.
+	     Perform checks for both real and imaginary parts.  */
+	  if (TREE_CODE (type) == COMPLEX_TYPE)
+	    {
+	      /* Unfortunately, produce_warns must be false in two subsequent
+		 calls of unsafe_conversion_p, because otherwise we could
+		 produce strange "double" warnings, if both real and imaginary
+		 parts have conversion problems related to signedness.
+
+		 For example:
+		 int32_t _Complex a = 0x80000000 + 0x80000000i;
+
+		 Possible solution: add a separate function for checking
+		 constants and combine result of two calls appropriately.  */
+	      enum conversion_safety re_safety =
+		  unsafe_conversion_p (loc, type, TREE_REALPART (expr), false);
+	      enum conversion_safety im_safety =
+		  unsafe_conversion_p (loc, type, imag_part, false);
+
+	      /* Merge the results into appropriate single warning.  */
+
+	      /* Note: this case includes SAFE_CONVERSION, i.e. success.  */
+	      if (re_safety == im_safety)
+		give_warning = re_safety;
+	      else if (!re_safety && im_safety)
+		give_warning = im_safety;
+	      else if (re_safety && !im_safety)
+		give_warning = re_safety;
+	      else
+		give_warning = UNSAFE_OTHER;
+	    }
+	  /* Warn about conversion from complex to real or integer type.  */
+	  else
+	    give_warning = UNSAFE_IMAGINARY;
+	}
+    }
+
+  /* Checks for remaining case: EXPR is not constant.  */
   else
     {
       /* Warn for real types converted to integer types.  */
@@ -2856,20 +2943,11 @@ unsafe_conversion_p (location_t loc, tree type, tree expr, bool produce_warns)
       else if (TREE_CODE (expr_type) == INTEGER_TYPE
 	       && TREE_CODE (type) == REAL_TYPE)
 	{
-	  tree type_low_bound, type_high_bound;
-	  REAL_VALUE_TYPE real_low_bound, real_high_bound;
-
 	  /* Don't warn about char y = 0xff; float x = (int) y;  */
 	  expr = get_unwidened (expr, 0);
 	  expr_type = TREE_TYPE (expr);
 
-	  type_low_bound = TYPE_MIN_VALUE (expr_type);
-	  type_high_bound = TYPE_MAX_VALUE (expr_type);
-	  real_low_bound = real_value_from_int_cst (0, type_low_bound);
-	  real_high_bound = real_value_from_int_cst (0, type_high_bound);
-
-	  if (!exact_real_truncate (TYPE_MODE (type), &real_low_bound)
-	      || !exact_real_truncate (TYPE_MODE (type), &real_high_bound))
+	  if (!int_safely_convertible_to_real_p (expr_type, type))
 	    give_warning = UNSAFE_OTHER;
 	}
 
@@ -2878,6 +2956,58 @@ unsafe_conversion_p (location_t loc, tree type, tree expr, bool produce_warns)
 	       && TREE_CODE (type) == REAL_TYPE
 	       && TYPE_PRECISION (type) < TYPE_PRECISION (expr_type))
 	give_warning = UNSAFE_REAL;
+
+      /* Check conversion between two complex types.  */
+      else if (TREE_CODE (expr_type) == COMPLEX_TYPE
+	       && TREE_CODE (type) == COMPLEX_TYPE)
+	{
+	  /* Extract underlying types (i.e., type of real and imaginary
+	     parts) of expr_type and type.  */
+	  tree from_type = TREE_TYPE (expr_type);
+	  tree to_type = TREE_TYPE (type);
+
+	  /* Warn for real types converted to integer types.  */
+	  if (TREE_CODE (from_type) == REAL_TYPE
+	      && TREE_CODE (to_type) == INTEGER_TYPE)
+	    give_warning = UNSAFE_REAL;
+
+	  /* Warn for real types converted to smaller real types.  */
+	  else if (TREE_CODE (from_type) == REAL_TYPE
+		   && TREE_CODE (to_type) == REAL_TYPE
+		   && TYPE_PRECISION (to_type) < TYPE_PRECISION (from_type))
+	    give_warning = UNSAFE_REAL;
+
+	  /* Check conversion for complex integer types.  Here implementation
+	     is simpler than for real-domain integers because it does not
+	     involve sophisticated cases, such as bitmasks, casts, etc.  */
+	  else if (TREE_CODE (from_type) == INTEGER_TYPE
+		   && TREE_CODE (to_type) == INTEGER_TYPE)
+	    {
+	      /* Warn for integer types converted to smaller integer types.  */
+	      if (TYPE_PRECISION (to_type) < TYPE_PRECISION (from_type))
+		give_warning = UNSAFE_OTHER;
+
+	      /* Check for different signedness, see case for real-domain
+		 integers (above) for a more detailed comment.  */
+	      else if (((TYPE_PRECISION (to_type) == TYPE_PRECISION (from_type)
+		    && TYPE_UNSIGNED (to_type) != TYPE_UNSIGNED (from_type))
+		    || (TYPE_UNSIGNED (to_type) && !TYPE_UNSIGNED (from_type)))
+		    && produce_warns)
+		warning_at (loc, OPT_Wsign_conversion,
+			"conversion to %qT from %qT "
+			"may change the sign of the result",
+			type, expr_type);
+	    }
+	  else if (TREE_CODE (from_type) == INTEGER_TYPE
+		   && TREE_CODE (to_type) == REAL_TYPE
+		   && !int_safely_convertible_to_real_p (from_type, to_type))
+	    give_warning = UNSAFE_OTHER;
+	}
+
+      /* Warn for complex types converted to real or integer types.  */
+      else if (TREE_CODE (expr_type) == COMPLEX_TYPE
+	       && TREE_CODE (type) != COMPLEX_TYPE)
+	give_warning = UNSAFE_IMAGINARY;
     }
 
   return give_warning;
@@ -2927,6 +3057,7 @@ conversion_warning (location_t loc, tree type, tree expr)
 
     case REAL_CST:
     case INTEGER_CST:
+    case COMPLEX_CST:
       conversion_kind = unsafe_conversion_p (loc, type, expr, true);
       if (conversion_kind == UNSAFE_REAL)
 	warning_at (loc, OPT_Wfloat_conversion,
@@ -2956,6 +3087,10 @@ conversion_warning (location_t loc, tree type, tree expr)
 	warning_at (loc, OPT_Wfloat_conversion,
 		    "conversion to %qT from %qT may alter its value",
 		    type, expr_type);
+      else if (conversion_kind == UNSAFE_IMAGINARY)
+	warning_at (loc, OPT_Wconversion,
+		    "conversion to %qT from %qT discards imaginary component",
+		    type, expr_type);
       else if (conversion_kind)
 	warning_at (loc, OPT_Wconversion,
 		    "conversion to %qT from %qT may alter its value",
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 444d80d..62eac9f 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -728,15 +728,22 @@ struct visibility_flags
   unsigned inlines_hidden : 1;	/* True when -finlineshidden in effect.  */
 };
 
-/* These enumerators are possible types of unsafe conversions.
-   SAFE_CONVERSION The conversion is safe
-   UNSAFE_OTHER Another type of conversion with problems
-   UNSAFE_SIGN Conversion between signed and unsigned integers
-    which are all warned about immediately, so this is unused
-   UNSAFE_REAL Conversions that reduce the precision of reals
-    including conversions from reals to integers
- */
-enum conversion_safety { SAFE_CONVERSION = 0, UNSAFE_OTHER, UNSAFE_SIGN, UNSAFE_REAL };
+/* These enumerators are possible types of unsafe conversions.  */
+enum conversion_safety {
+  /* The conversion is safe.  */
+  SAFE_CONVERSION = 0,
+  /* Another type of conversion with problems.  */
+  UNSAFE_OTHER,
+  /* Conversion between signed and unsigned integers
+     which are all warned about immediately, so this is unused.  */
+  UNSAFE_SIGN,
+  /* Conversions that reduce the precision of reals including conversions
+     from reals to integers.  */
+  UNSAFE_REAL,
+  /* Conversions from complex to reals or integers, that discard imaginary
+     component.  */
+  UNSAFE_IMAGINARY
+};
 
 /* Global visibility options.  */
 extern struct visibility_flags visibility_options;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5875476..cdd1c28 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2015-05-15  Mikhail Maltsev  <maltsevm@gmail.com>
+
+	PR c/48956
+	* gcc.dg/Wconversion-complex-c99.c: New test.
+	* gcc.dg/Wconversion-complex-gnu.c: New test.
+
 2015-05-15  Marc Glisse  <marc.glisse@inria.fr>
 
 	PR tree-optimization/64454
diff --git a/gcc/testsuite/gcc.dg/Wconversion-complex-c99.c b/gcc/testsuite/gcc.dg/Wconversion-complex-c99.c
new file mode 100644
index 0000000..0e6c390
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wconversion-complex-c99.c
@@ -0,0 +1,138 @@
+/* PR c/48956: Test for diagnostics for implicit conversions from complex
+   to real types and narrowing conversions of complex types.  */
+
+/* Architecture restrictions taken from Wconversion-real-integer.c.
+   Likewise, the magic value 16777217.  */
+
+/* { dg-do compile } */
+/* { dg-skip-if "doubles are floats,ints are 16bits" { "avr-*-*" } { "*" } { "" } } */
+/* { dg-options " -std=c99 -pedantic -Wconversion " } */
+/* { dg-require-effective-target int32plus } */
+/* { dg-require-effective-target double64plus } */
+
+/* A number which does not fit into float.  */
+#define MAX_FLOAT_PLUS 16777217.
+
+/* Other types could be added, but that won't affect test coverage.  */
+void ffloatc (float _Complex);
+void fdoublec (double _Complex);
+
+void ffloat (float);
+void fdouble (double);
+
+void fsi (int);
+void fui (unsigned);
+
+float _Complex vfloatc;
+double _Complex vdoublec;
+
+float vfloat;
+double vdouble;
+
+int vsi;
+unsigned vui;
+
+/* Check implicit conversions of complex values to reals.  */
+void
+var_complex_to_real (void)
+{
+  float _Complex floatc = 0.;
+  double _Complex doublec = 0.;
+
+  ffloatc (floatc);
+  fdoublec (doublec);
+  vfloatc = floatc;
+  vdoublec = doublec;
+
+  ffloat (floatc); /* { dg-warning "conversion" } */
+  fdouble (floatc); /* { dg-warning "conversion" } */
+  vfloat = floatc; /* { dg-warning "conversion" } */
+  vdouble = floatc; /* { dg-warning "conversion" } */
+
+  ffloat (doublec); /* { dg-warning "conversion" } */
+  fdouble (doublec); /* { dg-warning "conversion" } */
+  vfloat = doublec; /* { dg-warning "conversion" } */
+  vdouble = doublec; /* { dg-warning "conversion" } */
+}
+
+/* Check implicit narrowing conversions of complex values.  */
+void
+var_complex_narrowing (void)
+{
+  float _Complex floatc = 0.;
+  double _Complex doublec = 0.;
+
+  vdoublec = floatc;
+  vfloatc = doublec; /* { dg-warning "float-conversion" } */
+
+  fdoublec (floatc);
+  ffloatc (doublec); /* { dg-warning "float-conversion" } */
+}
+
+/* Check implicit conversions of complex values to integers.  */
+void
+var_complex_to_int (void)
+{
+  float _Complex floatc = 0.;
+  double _Complex doublec = 0.;
+
+  fsi (floatc); /* { dg-warning "conversion" } */
+  fui (floatc); /* { dg-warning "conversion" } */
+  vsi = floatc; /* { dg-warning "conversion" } */
+  vui = floatc; /* { dg-warning "conversion" } */
+
+  fsi (doublec); /* { dg-warning "conversion" } */
+  fui (doublec); /* { dg-warning "conversion" } */
+  vsi = doublec; /* { dg-warning "conversion" } */
+  vui = doublec; /* { dg-warning "conversion" } */
+}
+
+/* Check implicit conversion of constant complex values to floats.  */
+void
+const_complex_to_real (void)
+{
+  ffloat (__builtin_complex (0., 1.)); /* { dg-warning "conversion" } */
+  fdouble (__builtin_complex (0., 1.)); /* { dg-warning "conversion" } */
+
+  vfloat = __builtin_complex (0., 1.); /* { dg-warning "conversion" } */
+  vdouble = __builtin_complex (0., 1.); /* { dg-warning "conversion" } */
+
+  vfloat = __builtin_complex (1., 0.) + __builtin_complex (1., 0.);
+  vdouble = __builtin_complex (0., 0.) * __builtin_complex (1., 1.);
+  ffloat (__builtin_complex (1., 0.) + __builtin_complex (1., 0.));
+  fdouble (__builtin_complex (1., 0.) + __builtin_complex (1., 0.));
+
+  vfloat = __builtin_complex (MAX_FLOAT_PLUS, 0.); /* { dg-warning "float-conversion" } */
+  ffloat (__builtin_complex (MAX_FLOAT_PLUS, 0.)); /* { dg-warning "float-conversion" } */
+}
+
+/* Check implicit conversion of constant complex values to integers.  */
+void
+const_complex_to_int (void)
+{
+  vsi = __builtin_complex (-1., 0.);
+  vui = __builtin_complex (1., 0.);
+  fsi (__builtin_complex (-1., 0.));
+  fui (__builtin_complex (1., 0.));
+
+  vui = __builtin_complex (-1., 0.); /* { dg-warning "overflow" } */
+  fui (__builtin_complex (-1., 0.)); /* { dg-warning "overflow" } */
+
+  vsi = __builtin_complex (0.5, 0.); /* { dg-warning "float-conversion" } */
+  fui (__builtin_complex (0.5, 0.)); /* { dg-warning "float-conversion" } */
+
+  vsi = __builtin_complex (-0.5, 0.); /* { dg-warning "float-conversion" } */
+  fui (__builtin_complex (-0.5, 0.)); /* { dg-warning "float-conversion" } */
+}
+
+/* Check implicit narrowing conversion of constant complex values to.  */
+void
+const_complex_narrowing (void)
+{
+  ffloatc (__builtin_complex (-100., 100.));
+
+  ffloatc (__builtin_complex (MAX_FLOAT_PLUS, 0.)); /* { dg-warning "float-conversion" } */
+  ffloatc (__builtin_complex (0., MAX_FLOAT_PLUS)); /* { dg-warning "float-conversion" } */
+  ffloatc (__builtin_complex (MAX_FLOAT_PLUS, MAX_FLOAT_PLUS)); /* { dg-warning "float-conversion" } */
+}
+
diff --git a/gcc/testsuite/gcc.dg/Wconversion-complex-gnu.c b/gcc/testsuite/gcc.dg/Wconversion-complex-gnu.c
new file mode 100644
index 0000000..3839a39
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wconversion-complex-gnu.c
@@ -0,0 +1,127 @@
+/* PR c/48956: Test for diagnostics for implicit conversions involving complex
+   types.  See also Wconversion-complex-c99.c.
+
+   These tests cover integer complex values (which are GNU extensions).  */
+
+/* { dg-do compile } */
+/* { dg-skip-if "doubles are floats,ints are 16bits" { "avr-*-*" } { "*" } { "" } } */
+/* { dg-options " -std=gnu99 -Wconversion " } */
+/* { dg-require-effective-target int32plus } */
+/* { dg-require-effective-target double64plus } */
+
+#include <limits.h>
+
+void fsi (int);
+void fui (unsigned);
+void ffloat (float);
+int vsi;
+unsigned int vui;
+float vfloat;
+
+void fsic (int _Complex);
+void fuic (unsigned _Complex);
+void ffloatc (float _Complex);
+int _Complex vsic;
+unsigned _Complex vuic;
+float _Complex vfloatc;
+
+/* Check implicit conversions of float complex-domain values to integer
+   complex-domain types.  */
+void
+var_float_to_int (void)
+{
+  double _Complex doublec = 0.;
+
+  fsic (doublec); /* { dg-warning "float-conversion" } */
+  fuic (doublec); /* { dg-warning "float-conversion" } */
+
+  vsic = doublec; /* { dg-warning "float-conversion" } */
+  vuic = doublec; /* { dg-warning "float-conversion" } */
+}
+
+/* Check implicit conversions of integer complex-domain values to integer
+   real-domain types.  */
+void
+var_complex_to_real (void)
+{
+  int _Complex ic = 0;
+  unsigned _Complex uc = 0;
+  unsigned long long _Complex ullc = 0;
+
+  fsic (ic);
+  fuic (uc);
+  vsic = ic;
+  vuic = uc;
+
+  fsi (ic); /* { dg-warning "conversion" } */
+  vsi = ic; /* { dg-warning "conversion" } */
+  fui (uc); /* { dg-warning "conversion" } */
+  vui = uc; /* { dg-warning "conversion" } */
+
+  fuic (ullc); /* { dg-warning "conversion" } */
+  vuic = ullc; /* { dg-warning "conversion" } */
+
+  fui (ic); /* { dg-warning "conversion" } */
+  vui = ic; /* { dg-warning "conversion" } */
+}
+
+/* Check implicit conversions of float complex-domain constants to integer
+   types.  */
+void
+const_float_to_int (void)
+{
+  fsic (1. - 1.i);
+  fuic (1. + 1.i);
+  vsic = 1. - 1.i;
+  vuic = 1. + 1.i;
+
+  fsic (0.5 + 0.i); /* { dg-warning "float-conversion" } */
+  vsic = 0.5 + 0.i; /* { dg-warning "float-conversion" } */
+  fuic (0.5 + 0.i); /* { dg-warning "float-conversion" } */
+}
+
+/* Check implicit conversions of integer complex-domain constants to integer
+   types.  */
+void
+const_complex_int_to_real_int (void)
+{
+  fsi (-1 + 0i);
+  fui (1 + 0i);
+  vsi = -1 + 0i;
+  vui = 1 + 0i;
+
+  fui (1 + 1i); /* { dg-warning "conversion" } */
+  vui = 1 + 1i; /* { dg-warning "conversion" } */
+
+  fui (UINT_MAX + 1ull + 0i); /* { dg-warning "conversion" } */
+  vui = UINT_MAX + 1ull + 0i; /* { dg-warning "conversion" } */
+
+  ffloat (UINT_MAX + 0i); /* { dg-warning "float-conversion" } */
+  vfloat = UINT_MAX + 0i; /* { dg-warning "float-conversion" } */
+}
+
+void
+const_complex_int_narrowing (void)
+{
+  fsic (1 - 1i);
+  fuic (1 + 1i);
+  vsic = 1 - 1i;
+  vuic = 1 + 1i;
+
+  fuic (UINT_MAX + 1ull + 1i); /* { dg-warning "conversion" } */
+  fuic ((UINT_MAX + 1ull) * 1i); /* { dg-warning "conversion" } */
+  fuic ((UINT_MAX + 1ull) + (UINT_MAX + 1ull) * 1i); /* { dg-warning "conversion" } */
+
+  vuic = (UINT_MAX + 1ull) * 1i; /* { dg-warning "conversion" } */
+  vuic = (UINT_MAX + 1ull) + 1i; /* { dg-warning "conversion" } */
+  vuic = (UINT_MAX + 1ull) + (UINT_MAX + 1ull) * 1i; /* { dg-warning "conversion" } */
+
+  ffloatc (UINT_MAX * 1i); /* { dg-warning "float-conversion" } */
+  ffloatc (UINT_MAX + 1i); /* { dg-warning "float-conversion" } */
+  ffloatc (UINT_MAX + UINT_MAX * 1i); /* { dg-warning "float-conversion" } */
+
+  vfloatc = UINT_MAX * 1i; /* { dg-warning "float-conversion" } */
+  vfloatc = UINT_MAX + 1i; /* { dg-warning "float-conversion" } */
+  vfloatc = UINT_MAX + UINT_MAX * 1i; /* { dg-warning "float-conversion" } */
+}
+

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]