Index: gcc/coretypes.h
===================================================================
--- gcc/coretypes.h	2017-07-13 09:19:00.088160188 +0100
+++ gcc/coretypes.h	2017-07-13 09:19:00.526129740 +0100
@@ -58,6 +58,7 @@ typedef const struct rtx_def *const_rtx;
 class scalar_mode;
 class scalar_int_mode;
 class scalar_float_mode;
+class complex_mode;
 template<typename> class opt_mode;
 typedef opt_mode<scalar_mode> opt_scalar_mode;
 typedef opt_mode<scalar_int_mode> opt_scalar_int_mode;
@@ -323,6 +324,7 @@ #define const_tree union _dont_use_tree_
 typedef struct scalar_mode scalar_mode;
 typedef struct scalar_int_mode scalar_int_mode;
 typedef struct scalar_float_mode scalar_float_mode;
+typedef struct complex_mode complex_mode;
 
 #endif
 
Index: gcc/gdbhooks.py
===================================================================
--- gcc/gdbhooks.py	2017-07-13 09:19:00.090160049 +0100
+++ gcc/gdbhooks.py	2017-07-13 09:19:00.527129670 +0100
@@ -551,7 +551,8 @@ def build_pretty_printer():
     pp.add_printer_for_types(['scalar_int_mode_pod',
                               'scalar_mode_pod'],
                              'pod_mode', MachineModePrinter)
-    for mode in 'scalar_mode', 'scalar_int_mode', 'scalar_float_mode':
+    for mode in ('scalar_mode', 'scalar_int_mode', 'scalar_float_mode',
+                 'complex_mode'):
         pp.add_printer_for_types([mode], mode, MachineModePrinter)
 
     return pp
Index: gcc/machmode.h
===================================================================
--- gcc/machmode.h	2017-07-13 09:19:00.090160049 +0100
+++ gcc/machmode.h	2017-07-13 09:19:00.528129601 +0100
@@ -451,6 +451,30 @@ scalar_mode::includes_p (machine_mode m)
     }
 }
 
+/* Represents a machine mode that is known to be a COMPLEX_MODE_P.  */
+class complex_mode
+{
+public:
+  typedef mode_traits<complex_mode>::from_int from_int;
+
+  ALWAYS_INLINE complex_mode () {}
+  ALWAYS_INLINE complex_mode (from_int m) : m_mode (machine_mode (m)) {}
+  ALWAYS_INLINE operator machine_mode () const { return m_mode; }
+
+  static bool includes_p (machine_mode);
+
+protected:
+  machine_mode m_mode;
+};
+
+/* Return true if M is a complex_mode.  */
+
+inline bool
+complex_mode::includes_p (machine_mode m)
+{
+  return COMPLEX_MODE_P (m);
+}
+
 /* Return the base GET_MODE_SIZE value for MODE.  */
 
 ALWAYS_INLINE unsigned short
@@ -770,6 +794,36 @@ is_float_mode (machine_mode mode, T *flo
       return true;
     }
   return false;
+}
+
+/* Return true if MODE has class MODE_COMPLEX_INT, storing it as
+   a complex_mode in *CMODE if so.  */
+
+template<typename T>
+inline bool
+is_complex_int_mode (machine_mode mode, T *cmode)
+{
+  if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
+    {
+      *cmode = complex_mode (complex_mode::from_int (mode));
+      return true;
+    }
+  return false;
+}
+
+/* Return true if MODE has class MODE_COMPLEX_FLOAT, storing it as
+   a complex_mode in *CMODE if so.  */
+
+template<typename T>
+inline bool
+is_complex_float_mode (machine_mode mode, T *cmode)
+{
+  if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
+    {
+      *cmode = complex_mode (complex_mode::from_int (mode));
+      return true;
+    }
+  return false;
 }
 
 namespace mode_iterator
Index: gcc/genmodes.c
===================================================================
--- gcc/genmodes.c	2017-07-13 09:18:53.274650323 +0100
+++ gcc/genmodes.c	2017-07-13 09:19:00.527129670 +0100
@@ -1152,6 +1152,10 @@ get_mode_class (struct mode_data *mode)
     case MODE_DECIMAL_FLOAT:
       return "scalar_float_mode";
 
+    case MODE_COMPLEX_INT:
+    case MODE_COMPLEX_FLOAT:
+      return "complex_mode";
+
     default:
       return NULL;
     }
Index: gcc/function.c
===================================================================
--- gcc/function.c	2017-07-13 09:18:53.273650396 +0100
+++ gcc/function.c	2017-07-13 09:19:00.527129670 +0100
@@ -5503,6 +5503,7 @@ expand_function_end (void)
 	  : DECL_REGISTER (decl_result))
 	{
 	  rtx real_decl_rtl = crtl->return_rtx;
+	  complex_mode cmode;
 
 	  /* This should be set in assign_parms.  */
 	  gcc_assert (REG_FUNCTION_VALUE_P (real_decl_rtl));
@@ -5543,8 +5544,8 @@ expand_function_end (void)
 	     need to generate some non-trivial bitfield insertions.  Do that
 	     on a pseudo and not the hard register.  */
 	  else if (GET_CODE (decl_rtl) == CONCAT
-		   && GET_MODE_CLASS (GET_MODE (decl_rtl)) == MODE_COMPLEX_INT
-		   && GET_MODE_BITSIZE (GET_MODE (decl_rtl)) <= BITS_PER_WORD)
+		   && is_complex_int_mode (GET_MODE (decl_rtl), &cmode)
+		   && GET_MODE_BITSIZE (cmode) <= BITS_PER_WORD)
 	    {
 	      int old_generating_concat_p;
 	      rtx tmp;
Index: gcc/go/go-lang.c
===================================================================
--- gcc/go/go-lang.c	2017-07-13 09:18:31.699428322 +0100
+++ gcc/go/go-lang.c	2017-07-13 09:19:00.527129670 +0100
@@ -384,7 +384,7 @@ go_langhook_type_for_mode (machine_mode
 
   scalar_int_mode imode;
   scalar_float_mode fmode;
-  enum mode_class mc = GET_MODE_CLASS (mode);
+  complex_mode cmode;
   if (is_int_mode (mode, &imode))
     return go_langhook_type_for_size (GET_MODE_BITSIZE (imode), unsignedp);
   else if (is_float_mode (mode, &fmode))
@@ -402,9 +402,9 @@ go_langhook_type_for_mode (machine_mode
 	    return long_double_type_node;
 	}
     }
-  else if (mc == MODE_COMPLEX_FLOAT)
+  else if (is_complex_float_mode (mode, &cmode))
     {
-      switch (GET_MODE_BITSIZE (mode))
+      switch (GET_MODE_BITSIZE (cmode))
 	{
 	case 64:
 	  return complex_float_type_node;
@@ -413,7 +413,7 @@ go_langhook_type_for_mode (machine_mode
 	default:
 	  // We have to check for long double in order to support
 	  // i386 excess precision.
-	  if (mode == TYPE_MODE(complex_long_double_type_node))
+	  if (cmode == TYPE_MODE(complex_long_double_type_node))
 	    return complex_long_double_type_node;
 	}
     }
