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]

Patch to split common_type


This patch separates the C front end function common_type, which was
trying to do three different things, into three separate functions
each doing one thing specified by the standard.  In the process it
fixes bug 13519, and what seems to be an old bug with enums (shown in
the enum-3.c testcase added) that I'm surprised hadn't been found
before.  (Some cases in pr13519-1.c, not immediately related to the
subject of this patch or to that PR, are left as XFAILs; they failed
before this patch as well and are not part of the testcase included in
that PR.)

Bug 13519 is strictly a regression (some of the bogus errors don't
occur in some previous releases), but given the size of the patch and
that mainline common_type already has an extra feature over 3.4 branch
(support for C99 integer promotion rules), I'm not proposing this
patch for 3.4 branch.

Note: the documentation of vector extensions doesn't say quite how the
usual arithmetic conversions are applied to them - except to give the
impression that they shouldn't be, and if one operand of an operation
is of a vector type then the other must be of the same vector type.
The old common_type had no sensible handling for vector types.  The
new one handles them compatibly enough to pass the testsuite, but the
vector extension maintainers should check this and write and implement
the specification for how vector types should be handled here.

Bootstrapped with no regressions on i686-pc-linux-gnu.  Applied to
mainline.

2004-06-06  Joseph S. Myers  <jsm@polyomino.org.uk>

	PR c/13519
	* c-typeck.c (composite_type, common_pointer_type): New functions.
	(common_type): Split parts into composite_type and
	common_pointer_type.  Ensure that arithmetic operations return
	unqualified types without attributes.  Don't make composite type
	of signed enum and compatible integer be unsigned.
	(build_conditional_expr, build_binary_op): Use
	common_pointer_type.
	* c-decl.c (merge_decls): Use composite_type.
	* c-tree.h (composite_type): Declare.

testsuite:
2004-06-06  Joseph S. Myers  <jsm@polyomino.org.uk>

	PR c/13519
	* gcc.c-torture/enum-3.c, gcc.dg/pr13519-1.c: New tests.

diff -rupN gcc.orig/c-decl.c gcc/c-decl.c
--- gcc.orig/c-decl.c	2004-05-31 22:03:15.000000000 +0000
+++ gcc/c-decl.c	2004-06-05 18:18:51.000000000 +0000
@@ -1452,7 +1452,7 @@ merge_decls (tree newdecl, tree olddecl,
   /* Merge the data types specified in the two decls.  */
   TREE_TYPE (newdecl)
     = TREE_TYPE (olddecl)
-    = common_type (newtype, oldtype);
+    = composite_type (newtype, oldtype);
 
   /* Lay the type out, unless already done.  */
   if (oldtype != TREE_TYPE (newdecl))
diff -rupN gcc.orig/c-tree.h gcc/c-tree.h
--- gcc.orig/c-tree.h	2004-06-01 15:44:17.000000000 +0000
+++ gcc/c-tree.h	2004-06-05 18:20:01.000000000 +0000
@@ -226,6 +226,7 @@ extern tree c_size_in_bytes (tree);
 extern bool c_mark_addressable (tree);
 extern void c_incomplete_type_error (tree, tree);
 extern tree c_type_promotes_to (tree);
+extern tree composite_type (tree, tree);
 extern tree build_component_ref (tree, tree);
 extern tree build_indirect_ref (tree, const char *);
 extern tree build_array_ref (tree, tree);
diff -rupN gcc.orig/c-typeck.c gcc/c-typeck.c
--- gcc.orig/c-typeck.c	2004-06-03 16:40:06.000000000 +0000
+++ gcc/c-typeck.c	2004-06-06 00:05:53.000000000 +0000
@@ -199,19 +199,14 @@ qualify_type (tree type, tree like)
 				 TYPE_QUALS (type) | TYPE_QUALS (like));
 }
 
-/* Return the composite type of two compatible types, or the common
-   type for two arithmetic types under the usual arithmetic
-   conversions.
-
-   Unless both types are arithmetic types, we assume that comptypes
-   has already been done and returned 1; if that isn't so, this may
-   crash.  In particular, we assume that qualifiers match.
+/* Return the composite type of two compatible types.
 
-   This is the type for the result of most arithmetic operations
-   if the operands have the given two types.  */
+   We assume that comptypes has already been done and returned
+   nonzero; if that isn't so, this may crash.  In particular, we
+   assume that qualifiers match.  */
 
 tree
-common_type (tree t1, tree t2)
+composite_type (tree t1, tree t2)
 {
   enum tree_code code1;
   enum tree_code code2;
@@ -227,145 +222,40 @@ common_type (tree t1, tree t2)
   if (t2 == error_mark_node)
     return t1;
 
+  code1 = TREE_CODE (t1);
+  code2 = TREE_CODE (t2);
+
   /* Merge the attributes.  */
   attributes = targetm.merge_type_attributes (t1, t2);
 
-  /* Treat an enum type as the unsigned integer type of the same width.  */
-
-  if (TREE_CODE (t1) == ENUMERAL_TYPE)
-    t1 = c_common_type_for_size (TYPE_PRECISION (t1), 1);
-  if (TREE_CODE (t2) == ENUMERAL_TYPE)
-    t2 = c_common_type_for_size (TYPE_PRECISION (t2), 1);
-
-  code1 = TREE_CODE (t1);
-  code2 = TREE_CODE (t2);
+  /* If one is an enumerated type and the other is the compatible
+     integer type, the composite type might be either of the two
+     (DR#013 question 3).  For consistency, use the enumerated type as
+     the composite type.  */
 
-  /* If one type is complex, form the common type of the non-complex
-     components, then make that complex.  Use T1 or T2 if it is the
-     required type.  */
-  if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
-    {
-      tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
-      tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
-      tree subtype = common_type (subtype1, subtype2);
+  if (code1 == ENUMERAL_TYPE && code2 == INTEGER_TYPE)
+    return t1;
+  if (code2 == ENUMERAL_TYPE && code1 == INTEGER_TYPE)
+    return t2;
 
-      if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
-	return build_type_attribute_variant (t1, attributes);
-      else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
-	return build_type_attribute_variant (t2, attributes);
-      else
-	return build_type_attribute_variant (build_complex_type (subtype),
-					     attributes);
-    }
+  if (code1 != code2)
+    abort ();
 
   switch (code1)
     {
-    case INTEGER_TYPE:
-    case REAL_TYPE:
-      /* If only one is real, use it as the result.  */
-
-      if (code1 == REAL_TYPE && code2 != REAL_TYPE)
-	return build_type_attribute_variant (t1, attributes);
-
-      if (code2 == REAL_TYPE && code1 != REAL_TYPE)
-	return build_type_attribute_variant (t2, attributes);
-
-      /* Both real or both integers; use the one with greater precision.  */
-
-      if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
-	return build_type_attribute_variant (t1, attributes);
-      else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
-	return build_type_attribute_variant (t2, attributes);
-
-      /* Same precision.  Prefer long longs to longs to ints when the
-	 same precision, following the C99 rules on integer type rank
-	 (which are equivalent to the C90 rules for C90 types).
-	 Make sure that we don't lose the type qualifications when
-	 creating the new variant.  */
-
-      if (TYPE_MAIN_VARIANT (t1) == long_long_unsigned_type_node
-	  || TYPE_MAIN_VARIANT (t2) == long_long_unsigned_type_node)
-	{
-	  t1 = build_qualified_type (long_long_unsigned_type_node,
-				     TYPE_QUALS (t1));
-	  return build_type_attribute_variant (t1, attributes);
-	}
-
-      if (TYPE_MAIN_VARIANT (t1) == long_long_integer_type_node
-	  || TYPE_MAIN_VARIANT (t2) == long_long_integer_type_node)
-	{
-	  tree ntype;
-
-	  if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
-	     ntype = long_long_unsigned_type_node;
-	  else
-	     ntype = long_long_integer_type_node;
-
-	  ntype = build_qualified_type (ntype, TYPE_QUALS (t1));
-	  return build_type_attribute_variant (ntype, attributes);
-	}
-
-      if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node
-	  || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node)
-	{
-	  t1 = build_qualified_type (long_unsigned_type_node,
-				     TYPE_QUALS (t1));
-	  return build_type_attribute_variant (t1, attributes);
-	}
-
-      if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node
-	  || TYPE_MAIN_VARIANT (t2) == long_integer_type_node)
-	{
-	  tree ntype;
-
-	  /* But preserve unsignedness from the other type,
-	     since long cannot hold all the values of an unsigned int.  */
-	  if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
-	     ntype = long_unsigned_type_node;
-	  else
-	     ntype = long_integer_type_node;
-
-	  ntype = build_qualified_type (ntype, TYPE_QUALS (t1));
-	  return build_type_attribute_variant (ntype, attributes);
-	}
-
-      /* Likewise, prefer long double to double even if same size.  */
-      if (TYPE_MAIN_VARIANT (t1) == long_double_type_node
-	  || TYPE_MAIN_VARIANT (t2) == long_double_type_node)
-	{
-	  t1 = build_qualified_type (long_double_type_node,
-				     TYPE_QUALS (t1));
-	  return build_type_attribute_variant (t1, attributes);
-	}
-
-      /* Otherwise prefer the unsigned one.  */
-
-      if (TYPE_UNSIGNED (t1))
-	return build_type_attribute_variant (t1, attributes);
-      else
-	return build_type_attribute_variant (t2, attributes);
-
     case POINTER_TYPE:
-      /* For two pointers, do this recursively on the target type,
-	 and combine the qualifiers of the two types' targets.  */
-      /* This code was turned off; I don't know why.
-	 But ANSI C specifies doing this with the qualifiers.
-	 So I turned it on again.  */
+      /* For two pointers, do this recursively on the target type.  */
       {
 	tree pointed_to_1 = TREE_TYPE (t1);
 	tree pointed_to_2 = TREE_TYPE (t2);
-	tree target = common_type (TYPE_MAIN_VARIANT (pointed_to_1),
-				   TYPE_MAIN_VARIANT (pointed_to_2));
-	t1 = build_pointer_type (c_build_qualified_type
-				 (target,
-				  TYPE_QUALS (pointed_to_1) |
-				  TYPE_QUALS (pointed_to_2)));
+	tree target = composite_type (pointed_to_1, pointed_to_2);
+	t1 = build_pointer_type (target);
 	return build_type_attribute_variant (t1, attributes);
       }
 
     case ARRAY_TYPE:
       {
-	tree elt = common_type (TREE_TYPE (t1), TREE_TYPE (t2));
+	tree elt = composite_type (TREE_TYPE (t1), TREE_TYPE (t2));
 	/* Save space: see if the result is identical to one of the args.  */
 	if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
 	  return build_type_attribute_variant (t1, attributes);
@@ -380,7 +270,7 @@ common_type (tree t1, tree t2)
       /* Function types: prefer the one that specified arg types.
 	 If both do, merge the arg types.  Also merge the return types.  */
       {
-	tree valtype = common_type (TREE_TYPE (t1), TREE_TYPE (t2));
+	tree valtype = composite_type (TREE_TYPE (t1), TREE_TYPE (t2));
 	tree p1 = TYPE_ARG_TYPES (t1);
 	tree p2 = TYPE_ARG_TYPES (t2);
 	int len;
@@ -468,7 +358,7 @@ common_type (tree t1, tree t2)
 		      goto parm_done;
 		    }
 	      }
-	    TREE_VALUE (n) = common_type (TREE_VALUE (p1), TREE_VALUE (p2));
+	    TREE_VALUE (n) = composite_type (TREE_VALUE (p1), TREE_VALUE (p2));
 	  parm_done: ;
 	  }
 
@@ -482,6 +372,182 @@ common_type (tree t1, tree t2)
     }
 
 }
+
+/* Return the type of a conditional expression between pointers to
+   possibly differently qualified versions of compatible types.
+
+   We assume that comp_target_types has already been done and returned
+   nonzero; if that isn't so, this may crash.  */
+
+static tree
+common_pointer_type (tree t1, tree t2)
+{
+  tree attributes;
+  tree pointed_to_1;
+  tree pointed_to_2;
+  tree target;
+
+  /* Save time if the two types are the same.  */
+
+  if (t1 == t2) return t1;
+
+  /* If one type is nonsense, use the other.  */
+  if (t1 == error_mark_node)
+    return t2;
+  if (t2 == error_mark_node)
+    return t1;
+
+  if (TREE_CODE (t1) != POINTER_TYPE || TREE_CODE (t2) != POINTER_TYPE)
+    abort ();
+
+  /* Merge the attributes.  */
+  attributes = targetm.merge_type_attributes (t1, t2);
+
+  /* Find the composite type of the target types, and combine the
+     qualifiers of the two types' targets.  */
+  pointed_to_1 = TREE_TYPE (t1);
+  pointed_to_2 = TREE_TYPE (t2);
+  target = composite_type (TYPE_MAIN_VARIANT (pointed_to_1),
+			   TYPE_MAIN_VARIANT (pointed_to_2));
+  t1 = build_pointer_type (c_build_qualified_type
+			   (target,
+			    TYPE_QUALS (pointed_to_1) |
+			    TYPE_QUALS (pointed_to_2)));
+  return build_type_attribute_variant (t1, attributes);
+}
+
+/* Return the common type for two arithmetic types under the usual
+   arithmetic conversions.  The default conversions have already been
+   applied, and enumerated types converted to their compatible integer
+   types.  The resulting type is unqualified and has no attributes.
+
+   This is the type for the result of most arithmetic operations
+   if the operands have the given two types.  */
+
+tree
+common_type (tree t1, tree t2)
+{
+  enum tree_code code1;
+  enum tree_code code2;
+
+  /* If one type is nonsense, use the other.  */
+  if (t1 == error_mark_node)
+    return t2;
+  if (t2 == error_mark_node)
+    return t1;
+
+  if (TYPE_QUALS (t1) != TYPE_UNQUALIFIED)
+    t1 = TYPE_MAIN_VARIANT (t1);
+
+  if (TYPE_QUALS (t2) != TYPE_UNQUALIFIED)
+    t2 = TYPE_MAIN_VARIANT (t2);
+
+  if (TYPE_ATTRIBUTES (t1) != NULL_TREE)
+    t1 = build_type_attribute_variant (t1, NULL_TREE);
+
+  if (TYPE_ATTRIBUTES (t2) != NULL_TREE)
+    t2 = build_type_attribute_variant (t2, NULL_TREE);
+
+  /* Save time if the two types are the same.  */
+
+  if (t1 == t2) return t1;
+
+  code1 = TREE_CODE (t1);
+  code2 = TREE_CODE (t2);
+
+  if (code1 != VECTOR_TYPE && code1 != COMPLEX_TYPE
+      && code1 != REAL_TYPE && code1 != INTEGER_TYPE)
+    abort ();
+
+  if (code2 != VECTOR_TYPE && code2 != COMPLEX_TYPE
+      && code2 != REAL_TYPE && code2 != INTEGER_TYPE)
+    abort ();
+
+  /* If one type is a vector type, return that type.  (How the usual
+     arithmetic conversions apply to the vector types extension is not
+     precisely specified.)  */
+  if (code1 == VECTOR_TYPE)
+    return t1;
+
+  if (code2 == VECTOR_TYPE)
+    return t2;
+
+  /* If one type is complex, form the common type of the non-complex
+     components, then make that complex.  Use T1 or T2 if it is the
+     required type.  */
+  if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
+    {
+      tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
+      tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
+      tree subtype = common_type (subtype1, subtype2);
+
+      if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
+	return t1;
+      else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
+	return t2;
+      else
+	return build_complex_type (subtype);
+    }
+
+  /* If only one is real, use it as the result.  */
+
+  if (code1 == REAL_TYPE && code2 != REAL_TYPE)
+    return t1;
+
+  if (code2 == REAL_TYPE && code1 != REAL_TYPE)
+    return t2;
+
+  /* Both real or both integers; use the one with greater precision.  */
+
+  if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
+    return t1;
+  else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
+    return t2;
+
+  /* Same precision.  Prefer long longs to longs to ints when the
+     same precision, following the C99 rules on integer type rank
+     (which are equivalent to the C90 rules for C90 types).  */
+
+  if (TYPE_MAIN_VARIANT (t1) == long_long_unsigned_type_node
+      || TYPE_MAIN_VARIANT (t2) == long_long_unsigned_type_node)
+    return long_long_unsigned_type_node;
+
+  if (TYPE_MAIN_VARIANT (t1) == long_long_integer_type_node
+      || TYPE_MAIN_VARIANT (t2) == long_long_integer_type_node)
+    {
+      if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
+	return long_long_unsigned_type_node;
+      else
+        return long_long_integer_type_node;
+    }
+
+  if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node
+      || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node)
+    return long_unsigned_type_node;
+
+  if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node
+      || TYPE_MAIN_VARIANT (t2) == long_integer_type_node)
+    {
+      /* But preserve unsignedness from the other type,
+	 since long cannot hold all the values of an unsigned int.  */
+      if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
+	return long_unsigned_type_node;
+      else
+	return long_integer_type_node;
+    }
+
+  /* Likewise, prefer long double to double even if same size.  */
+  if (TYPE_MAIN_VARIANT (t1) == long_double_type_node
+      || TYPE_MAIN_VARIANT (t2) == long_double_type_node)
+    return long_double_type_node;
+
+  /* Otherwise prefer the unsigned one.  */
+
+  if (TYPE_UNSIGNED (t1))
+    return t1;
+  else
+    return t2;
+}
 
 /* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
    or various other operations.  Return 2 if they are compatible
@@ -2760,7 +2826,7 @@ build_conditional_expr (tree ifexp, tree
   else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE)
     {
       if (comp_target_types (type1, type2, 1))
-	result_type = common_type (type1, type2);
+	result_type = common_pointer_type (type1, type2);
       else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node
 	       && TREE_CODE (orig_op1) != NOP_EXPR)
 	result_type = qualify_type (type2, type1);
@@ -6704,7 +6770,7 @@ build_binary_op (enum tree_code code, tr
 	     Otherwise, the targets must be compatible
 	     and both must be object or both incomplete.  */
 	  if (comp_target_types (type0, type1, 1))
-	    result_type = common_type (type0, type1);
+	    result_type = common_pointer_type (type0, type1);
 	  else if (VOID_TYPE_P (tt0))
 	    {
 	      /* op0 != orig_op0 detects the case of something
@@ -6752,7 +6818,7 @@ build_binary_op (enum tree_code code, tr
 	{
 	  if (comp_target_types (type0, type1, 1))
 	    {
-	      result_type = common_type (type0, type1);
+	      result_type = common_pointer_type (type0, type1);
 	      if (pedantic
 		  && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
 		pedwarn ("ISO C forbids ordered comparisons of pointers to functions");
@@ -6777,7 +6843,7 @@ build_binary_op (enum tree_code code, tr
 	{
 	  if (comp_target_types (type0, type1, 1))
 	    {
-	      result_type = common_type (type0, type1);
+	      result_type = common_pointer_type (type0, type1);
 	      if (!COMPLETE_TYPE_P (TREE_TYPE (type0))
 		  != !COMPLETE_TYPE_P (TREE_TYPE (type1)))
 		pedwarn ("comparison of complete and incomplete pointers");
diff -rupN gcc.orig/testsuite/gcc.c-torture/execute/enum-3.c gcc/testsuite/gcc.c-torture/execute/enum-3.c
--- gcc.orig/testsuite/gcc.c-torture/execute/enum-3.c	1970-01-01 00:00:00.000000000 +0000
+++ gcc/testsuite/gcc.c-torture/execute/enum-3.c	2004-06-05 18:57:43.000000000 +0000
@@ -0,0 +1,24 @@
+/* The composite type of int and an enum compatible with int might be
+   either of the two types, but it isn't an unsigned type.  */
+/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
+
+#include <limits.h>
+
+#include <stdio.h>
+
+extern void abort (void);
+extern void exit (int);
+
+enum e { a = INT_MIN };
+
+int *p;
+enum e *q;
+int
+main (void)
+{
+  enum e x = a;
+  q = &x;
+  if (*(1 ? q : p) > 0)
+    abort ();
+  exit (0);
+}
diff -rupN gcc.orig/testsuite/gcc.dg/pr13519-1.c gcc/testsuite/gcc.dg/pr13519-1.c
--- gcc.orig/testsuite/gcc.dg/pr13519-1.c	1970-01-01 00:00:00.000000000 +0000
+++ gcc/testsuite/gcc.dg/pr13519-1.c	2004-06-05 21:40:26.000000000 +0000
@@ -0,0 +1,47 @@
+/* typeof applied to const+nonconst should be nonconst, as should
+   typeof applied to other arithmetic expressions.  Bug 13519.  */
+/* Origin: Debian bug report 208981
+   from Kalle Olavi Niemitalo <kon@iki.fi>, adapted to a testcase by
+   Joseph Myers <jsm@polyomino.org.uk>.  */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void fn(void)
+{
+  int n;
+  const int c;
+
+  { __typeof__(n) a1; a1=0; }
+  { __typeof__(c) a2; a2=0; } /* { dg-error "read-only" "correct error" } */
+  { __typeof__((int)n) a3; a3=0; }
+  { __typeof__((int)c) a4; a4=0; } /* { dg-bogus "read-only" "bogus error" { xfail *-*-* } } */
+  { __typeof__((const int)n) a5; a5=0; } /* { dg-error "read-only" "correct error" { xfail *-*-* } } */
+  { __typeof__((const int)c) a6; a6=0; } /* { dg-error "read-only" "correct error" } */
+  { __typeof__(0) a7; a7=0; }
+  { __typeof__(1) a8; a8=0; }
+
+  { __typeof__(n+n) b0; b0=0; }
+  { __typeof__(n+c) b1; b1=0; }
+  { __typeof__(c+n) b2; b2=0; }
+  { __typeof__(c+c) b3; b3=0; }
+
+  { __typeof__(0+n) c0; c0=0; }
+  { __typeof__(0+c) c1; c1=0; }
+  { __typeof__(n+0) c2; c2=0; }
+  { __typeof__(c+0) c3; c3=0; }
+
+  { __typeof__(1+n) d0; d0=0; }
+  { __typeof__(1+c) d1; d1=0; }
+  { __typeof__(n+1) d2; d2=0; }
+  { __typeof__(c+1) d3; d3=0; }
+
+  { __typeof__(((int)n)+((int)n)) e0; e0=0; }
+  { __typeof__(((int)n)+((int)c)) e1; e1=0; }
+  { __typeof__(((int)c)+((int)n)) e2; e2=0; }
+  { __typeof__(((int)c)+((int)c)) e3; e3=0; }
+
+  { __typeof__(((const int)n)+((const int)n)) f0; f0=0; }
+  { __typeof__(((const int)n)+((const int)c)) f1; f1=0; }
+  { __typeof__(((const int)c)+((const int)n)) f2; f2=0; }
+  { __typeof__(((const int)c)+((const int)c)) f3; f3=0; }
+}

-- 
Joseph S. Myers
jsm@polyomino.org.uk


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