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 for PR c/12373


PR c/12373 is about a crash which happens on sh-elf.  The crash occurs
when the compiler is checking whether an explicit declaration of
vprintf is compatible with the builtin declaration.  The relevant part
of the test case looks like this:

    typedef long __va_greg;
    typedef double __va_freg;

    typedef struct {
      __va_greg * __va_next_o;		 
      __va_greg * __va_next_o_limit;	 
      __va_freg * __va_next_fp;		 
      __va_freg * __va_next_fp_limit;	 
      __va_greg * __va_next_stack;		 
    } __gnuc_va_list;

    int	 vprintf    (const char *, __gnuc_va_list )  ;

This causes gcc to check whether __gnuc_va_list is the same as the
builtin type held in the variable va_list_type_node.

The C frontend gives va_list_type_node a name: __builtin_va_list.
When it does this, pushdecl() calls clone_underlying_type().
clone_underlying_type() does this:

  if (DECL_SOURCE_LINE (x) == 0)
    {
      if (TYPE_NAME (TREE_TYPE (x)) == 0)
	TYPE_NAME (TREE_TYPE (x)) = x;
    }

With a non-built-in type, clone_underlying_type() duplicates the type
node.  The above is a special case if the type is a built-in type.  I
guess that this is for efficiency.

The important point here is that the result is that we have a type
with TYPE_NAME set but DECL_ORIGINAL_TYPE not set.  This can only
happen for a built-in type.  It does not appear to be a bug.  The code
has worked this way since the CVS repository was created.

Last year, Geoff added the function tagged_types_tu_compatible_p() as
part of the big intermodule patch.  This function checks whether two
types are compatible.  It does this:

  while (TYPE_NAME (t1) && TREE_CODE (TYPE_NAME (t1)) == TYPE_DECL)
    t1 = DECL_ORIGINAL_TYPE (TYPE_NAME (t1));

The problem, of course, is that this assumes that if TYPE_NAME is set
that DECL_ORIGINAL_TYPE is set.  As we can see from the above, this is
not the case for a built-in type.

The comment above tagged_types_tu_compatible_p() appears to say that
this sort of case can only arise when compiling multiple translation
units.  This test case shows that the comment is wrong, unless you
consider the builtin declarations to be a separate translation unit.

Anyhow, the fix to the code would seem to be straightforward.

OK for mainline?

This PR is currently targeted at 3.4.0.  Mark, let me know if you want
this patch on the 3.4 branch.  The patch should never introduce a new
crash.  But I suppose it is conceivable that it could introduce a case
where the compiler currently crashes but, after this patch, it
generates bad code.  I think that is unlikely in this case.

Ian


2004-03-19  Ian Lance Taylor  <ian@wasabisystems.com>

	PR c/12373
	* c-typeck.c (tagged_types_tu_compatible_p): Don't use
	DECL_ORIGINAL_TYPE if there isn't one.


Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.289
diff -p -u -r1.289 c-typeck.c
--- c-typeck.c	18 Mar 2004 20:58:34 -0000	1.289
+++ c-typeck.c	20 Mar 2004 03:00:15 -0000
@@ -674,10 +674,14 @@ tagged_types_tu_compatible_p (tree t1, t
      is harder than it looks because this may be a typedef, so we have
      to go look at the original type.  It may even be a typedef of a
      typedef...  */
-  while (TYPE_NAME (t1) && TREE_CODE (TYPE_NAME (t1)) == TYPE_DECL)
+  while (TYPE_NAME (t1)
+	 && TREE_CODE (TYPE_NAME (t1)) == TYPE_DECL
+	 && DECL_ORIGINAL_TYPE (TYPE_NAME (t1)))
     t1 = DECL_ORIGINAL_TYPE (TYPE_NAME (t1));
 
-  while (TYPE_NAME (t2) && TREE_CODE (TYPE_NAME (t2)) == TYPE_DECL)
+  while (TYPE_NAME (t2)
+	 && TREE_CODE (TYPE_NAME (t2)) == TYPE_DECL
+	 && DECL_ORIGINAL_TYPE (TYPE_NAME (t2)))
     t2 = DECL_ORIGINAL_TYPE (TYPE_NAME (t2));
 
   /* C90 didn't have the requirement that the two tags be the same.  */


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