Our current base compiler will abort with an error if it finds a typedef
being redefined, even if the new definition is no different from the one
it knows about.

Allowing this kind of type redefinition is a new C11 feature, which some
third-party software has already started using. Moreover, recent gcc
compilers will indeed accept this, even in non-c11 mode, with an
optional warning.

Consider the following testcase:
$ cat type.c
typedef unsigned char uint8_t;
typedef unsigned char char_t;

/* the following should not cause errors */
typedef unsigned char uint8_t;
typedef char_t uint8_t;

/* the following should cause errors */
typedef unsigned int uint8_t;
$

With the current in-tree compiler, it will produce these errors:

type.c:5: error: redefinition of typedef 'uint8_t'
type.c:1: error: previous declaration of 'uint8_t' was here
type.c:6: error: redefinition of typedef 'uint8_t'
type.c:5: error: previous declaration of 'uint8_t' was here
type.c:9: error: conflicting types for 'uint8_t'
type.c:6: error: previous declaration of 'uint8_t' was here

with the diff I am proposing below, it will only produce these errors:

type.c:9: error: conflicting types for 'uint8_t'
type.c:6: error: previous declaration of 'uint8_t' was here

and adding -pedantic will produce these warnings:

type.c:5: warning: redefinition of typedef 'uint8_t'
type.c:6: warning: redefinition of typedef 'uint8_t'

Any objections?

Index: c-decl.c
===================================================================
RCS file: /OpenBSD/src/gnu/gcc/gcc/c-decl.c,v
retrieving revision 1.2
diff -u -p -r1.2 c-decl.c
--- c-decl.c    29 Apr 2010 18:37:37 -0000      1.2
+++ c-decl.c    2 May 2015 14:35:28 -0000
@@ -1285,9 +1285,17 @@ diagnose_mismatched_decls (tree newdecl,
       if (DECL_IN_SYSTEM_HEADER (newdecl) || DECL_IN_SYSTEM_HEADER (olddecl))
        return true;  /* Allow OLDDECL to continue in use.  */
 
-      error ("redefinition of typedef %q+D", newdecl);
-      locate_old_decl (olddecl, error);
-      return false;
+      if (pedantic)
+       {
+         pedwarn ("redefinition of typedef %q+D", newdecl);
+         if (flag_pedantic_errors)
+           {
+             locate_old_decl (olddecl, error);
+             return false;
+           }
+       }
+
+      return true;
     }
 
   /* Function declarations can either be 'static' or 'extern' (no

Reply via email to