Patch for PR c/6024 [includes Fortran front end fallout]

Joseph S. Myers jsm@polyomino.org.uk
Wed Jan 7 01:58:00 GMT 2004


This patch fixes PR c/6024: enumerated types in the same translation
unit that are compatible with the same integer type are nevertheless
not compatible with each other unless they are the same type (since
there is nothing in the standard to make them compatible).  (I'm
making this unconditional in the hope that there won't be a
significant amount of broken code out there expecting them to be
compatible; if necessary, it could be conditioned on -pedantic.)

(The change to the documentation of __builtin_types_compatible_p
brings it back closer to how early drafts of the implementation
documented it: my incorrect comments on those drafts at the time were
based on a failure to appreciate the nontransitivity of compatibility
in this case.)

Bootstrapped with no regressions on i686-pc-linux-gnu.  OK to commit
the Fortran part of the patch (fixing a problem shown up by this
patch)?  I'll apply the rest of the patch at the same time if so.

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

	PR c/6024
	* c-typeck.c (comptypes): Only treat enumerated types in the same
	translation unit as compatible with each other when they are the
	same type.
	* doc/extend.texi: Update.

f:
2004-01-07  Joseph S. Myers  <jsm@polyomino.org.uk>

	* com.h (ffecom_gfrt_basictype): Correct return type.

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

	PR c/6024
	* gcc.dg/enum-compat-1.c: New test.
	* gcc.c-torture/execute/builtin-types-compatible-p.c: Update.

--- GCC/gcc/c-typeck.c.orig	2004-01-03 11:59:47.000000000 +0000
+++ GCC/gcc/c-typeck.c	2004-01-06 19:13:06.000000000 +0000
@@ -474,12 +474,13 @@ comptypes (tree type1, tree type2, int f
       && TYPE_DOMAIN (t2) != 0)
     t2 = TYPE_DOMAIN (t2);
 
-  /* Treat an enum type as the integer type of the same width and
-     signedness.  */
+  /* Enumerated types are compatible with integer types, but this is
+     not transitive: two enumerated types in the same translation unit
+     are compatible with each other only if they are the same type.  */
 
-  if (TREE_CODE (t1) == ENUMERAL_TYPE)
+  if (TREE_CODE (t1) == ENUMERAL_TYPE && TREE_CODE (t2) != ENUMERAL_TYPE)
     t1 = c_common_type_for_size (TYPE_PRECISION (t1), TREE_UNSIGNED (t1));
-  if (TREE_CODE (t2) == ENUMERAL_TYPE)
+  else if (TREE_CODE (t2) == ENUMERAL_TYPE && TREE_CODE (t1) != ENUMERAL_TYPE)
     t2 = c_common_type_for_size (TYPE_PRECISION (t2), TREE_UNSIGNED (t2));
 
   if (t1 == t2)
--- GCC/gcc/doc/extend.texi.orig	2004-01-04 20:31:31.000000000 +0000
+++ GCC/gcc/doc/extend.texi	2004-01-07 00:08:32.000000000 +0000
@@ -5265,8 +5265,10 @@
 @code{short **}.  Furthermore, two types that are typedefed are
 considered compatible if their underlying types are compatible.
 
-An @code{enum} type is considered to be compatible with another
-@code{enum} type.  For example, @code{enum @{foo, bar@}} is similar to
+An @code{enum} type is not considered to be compatible with another
+@code{enum} type even if both are compatible with the same integer
+type; this is what the C standard specifies.
+For example, @code{enum @{foo, bar@}} is not similar to
 @code{enum @{hot, dog@}}.
 
 You would typically use this function in code whose execution varies
--- GCC/gcc/f/com.h.orig	2003-10-04 07:34:43.000000000 +0000
+++ GCC/gcc/f/com.h	2004-01-06 21:37:50.000000000 +0000
@@ -228,7 +228,7 @@
 void ffecom_finish_progunit (void);
 tree ffecom_get_invented_identifier (const char *pattern, ...)
   ATTRIBUTE_PRINTF_1;
-ffeinfoKindtype ffecom_gfrt_basictype (ffecomGfrt ix);
+ffeinfoBasictype ffecom_gfrt_basictype (ffecomGfrt ix);
 ffeinfoKindtype ffecom_gfrt_kindtype (ffecomGfrt ix);
 void ffecom_init_0 (void);
 void ffecom_init_2 (void);
--- GCC/gcc/testsuite/gcc.dg/enum-compat-1.c	2002-08-26 16:21:36.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/enum-compat-1.c	2004-01-06 20:29:53.000000000 +0000
@@ -0,0 +1,32 @@
+/* Test that enumerated types are only considered compatible when they
+   are the same type.  PR c/6024.  */
+/* Origin: Joseph Myers <jsm@polyomino.org.uk>, based on
+   PR c/6024 from Richard Earnshaw <rearnsha@arm.com> */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+/* Original test from PR c/6024.  */
+enum e1 {a, b};
+enum e2 {c, d};
+
+void f(enum e1); /* { dg-error "prototype" "error at decl" } */
+
+void f(x)
+     enum e2 x;
+{ /* { dg-error "doesn't match prototype" "error at defn" } */
+  return;
+}
+
+/* Other compatibility tests.  */
+enum e3 { A };
+enum e4 { B };
+
+enum e3 v3;
+enum e4 *p = &v3; /* { dg-warning "incompatible" "incompatible pointer" } */
+enum e3 *q = &v3;
+
+void g(enum e3); /* { dg-error "declaration" "error at first decl" } */
+void g(enum e4); /* { dg-error "conflicting types" "error at second decl" } */
+
+void h(enum e3);
+void h(enum e3);
--- GCC/gcc/testsuite/gcc.c-torture/execute/builtin-types-compatible-p.c.orig	2001-12-08 22:29:03.000000000 +0000
+++ GCC/gcc/testsuite/gcc.c-torture/execute/builtin-types-compatible-p.c	2004-01-07 00:02:00.000000000 +0000
@@ -19,7 +19,6 @@
 	&& __builtin_types_compatible_p (typeof (hot), int)
 	&& __builtin_types_compatible_p (typeof (hot), typeof (laura))
 	&& __builtin_types_compatible_p (int[5], int[])
-	&& __builtin_types_compatible_p (typeof (dingos), typeof (cranberry))
 	&& __builtin_types_compatible_p (same1, same2)))
     abort ();
 
@@ -28,6 +27,7 @@
       || __builtin_types_compatible_p (char *, const char *)
       || __builtin_types_compatible_p (long double, double)
       || __builtin_types_compatible_p (typeof (i), typeof (d))
+      || __builtin_types_compatible_p (typeof (dingos), typeof (cranberry))
       || __builtin_types_compatible_p (char, int)
       || __builtin_types_compatible_p (char *, char **))
     abort ();

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



More information about the Gcc-patches mailing list