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]

PATCH: Fix PR2971



A little while back, I changed dwarf2out.c to not generate brand-new
types.  That was good.  I didn't quite do it right, though, and that
was bad.

For a variable of type `const foo' the C front-end creates a VAR_DECL
of type `foo' and marks the VAR_DECL as TREE_READONLY.  That's silly;
the type of the variable is `const foo'.  TREE_READONLYness of the
VAR_DECL should be a different concept: even a variable that was
declared as plain `foo' might be TREE_READONLY if we could determine
that it was never modified.

I fixed the same breakage in the C++ front-end eons ago.  But, I was
hoping to put it off in the C front-end until we merged the two.
Sadly, we have to it now to fix the DWARF2 problem.  The basic
invariant should be that DWARF2 never tries to talk about a type that
the front-end hasn't already created.  What possible excuse could
there be for doing otherwise?

This patch also fixes a bug that several of our test-cases
disturbingly relied upon: namely, the ability to redeclare a variable
with different cv-qualifiers like this:

   extern int i;

   volatile int i;

That is nonsense -- it is not C, of any known dialect so far as I can
tell, and it is patently dangerous.  If you use `i' in between the
declaration and the use we will not know that it is volatile, and we
do the wrong thing.  Similarly, we allow you to write to a variable
that you subsequently declare `const'.  In the case of `const', we at
least warned -- for `volatile' we just silently did the wrong thing.
In any case, if you know of some reason why this kind of program
should be accepted, please shout.

I did not remove all the cruft in the C front-end that go now that the
types are correct -- there is still lots of:

   TREE_READONLY (decl) || TYPE_READONLY (TREE_TYPE (decl))

that can be simplified to checking only the type.

Tested on i686-pc-linux-gnu, applied on the mainline and the branch.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

2001-06-08  Mark Mitchell  <mark@codesourcery.com>

	* c-decl.c (grokdeclarator): Make the TREE_TYPE for declarations
	accurately reflect its cv-qualification.
	* c-typeck.c (type_lists_compatible_p): Ignore the top-levl
	cv-qualifiers on function types.

Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.207.2.14
diff -c -p -r1.207.2.14 c-decl.c
*** c-decl.c	2001/06/06 03:05:19	1.207.2.14
--- c-decl.c	2001/06/08 21:56:37
*************** grokdeclarator (declarator, declspecs, d
*** 4674,4680 ****
  
      if (decl_context == PARM)
        {
! 	tree type_as_written = type;
  	tree promoted_type;
  
  	/* A parameter declared as an array of T is really a pointer to T.
--- 4674,4680 ----
  
      if (decl_context == PARM)
        {
! 	tree type_as_written;
  	tree promoted_type;
  
  	/* A parameter declared as an array of T is really a pointer to T.
*************** grokdeclarator (declarator, declspecs, d
*** 4699,4704 ****
--- 4699,4708 ----
  	    type = build_pointer_type (type);
  	    type_quals = TYPE_UNQUALIFIED;
  	  }
+ 	else if (type_quals)
+ 	  type = c_build_qualified_type (type, type_quals);
+ 	  
+ 	type_as_written = type;
  
  	decl = build_decl (PARM_DECL, declarator, type);
  	if (size_varies)
*************** grokdeclarator (declarator, declspecs, d
*** 4825,4831 ****
  	    type_quals = TYPE_UNQUALIFIED;
  #endif
  	  }
! 
  	decl = build_decl (VAR_DECL, declarator, type);
  	if (size_varies)
  	  C_DECL_VARIABLE_SIZE (decl) = 1;
--- 4829,4837 ----
  	    type_quals = TYPE_UNQUALIFIED;
  #endif
  	  }
! 	else if (type_quals)
! 	  type = c_build_qualified_type (type, type_quals);
! 	  
  	decl = build_decl (VAR_DECL, declarator, type);
  	if (size_varies)
  	  C_DECL_VARIABLE_SIZE (decl) = 1;
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.114.2.6
diff -c -p -r1.114.2.6 c-typeck.c
*** c-typeck.c	2001/06/04 19:49:28	1.114.2.6
--- c-typeck.c	2001/06/08 21:56:39
*************** type_lists_compatible_p (args1, args2)
*** 651,657 ****
  	  if (simple_type_promotes_to (TREE_VALUE (args1)) != NULL_TREE)
  	    return 0;
  	}
!       else if (! (newval = comptypes (TREE_VALUE (args1), TREE_VALUE (args2))))
  	{
  	  /* Allow  wait (union {union wait *u; int *i} *)
  	     and  wait (union wait *)  to be compatible.  */
--- 651,658 ----
  	  if (simple_type_promotes_to (TREE_VALUE (args1)) != NULL_TREE)
  	    return 0;
  	}
!       else if (! (newval = comptypes (TYPE_MAIN_VARIANT (TREE_VALUE (args1)), 
! 				      TYPE_MAIN_VARIANT (TREE_VALUE (args2)))))
  	{
  	  /* Allow  wait (union {union wait *u; int *i} *)
  	     and  wait (union wait *)  to be compatible.  */
Index: testsuite/gcc.c-torture/compile/920729-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.c-torture/compile/920729-1.c,v
retrieving revision 1.2
diff -c -p -r1.2 920729-1.c
*** 920729-1.c	1998/12/16 22:07:26	1.2
--- 920729-1.c	2001/06/08 21:56:44
***************
*** 1,2 ****
! extern int i;extern volatile int i;
  f(){int j;for(;;)j = i;}
--- 1,2 ----
! extern volatile int i;
  f(){int j;for(;;)j = i;}
Index: testsuite/gcc.c-torture/execute/931018-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.c-torture/execute/931018-1.c,v
retrieving revision 1.2
diff -c -p -r1.2 931018-1.c
*** 931018-1.c	1998/12/16 22:13:03	1.2
--- 931018-1.c	2001/06/08 21:56:45
***************
*** 1,5 ****
  unsigned int a[0x1000];
! extern unsigned long v;
  
  main ()
  {
--- 1,5 ----
  unsigned int a[0x1000];
! extern const unsigned long v;
  
  main ()
  {
Index: testsuite/gcc.dg/noncompile/redecl-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/noncompile/redecl-1.c,v
retrieving revision 1.2
diff -c -p -r1.2 redecl-1.c
*** redecl-1.c	2000/07/30 23:54:59	1.2
--- redecl-1.c	2001/06/08 21:56:45
***************
*** 4,10 ****
  int
  foo ()
  {
!   int bar; /* { dg-error "previously declared" "previously declared" } */
!   volatile int bar; /* { dg-error "redeclaration" "redeclaration" } */
  }
  
--- 4,10 ----
  int
  foo ()
  {
!   int bar; /* { dg-error "previous.*decl" "previous.*decl" } */
!   volatile int bar; /* { dg-error "conflicting types" "conflicting types" } */
  }
  


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