This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: Fix PR2971
- To: gcc-patches at gcc dot gnu dot org
- Subject: PATCH: Fix PR2971
- From: Mark Mitchell <mark at codesourcery dot com>
- Date: Fri, 08 Jun 2001 15:32:50 -0700
- Organization: CodeSourcery, LLC
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" } */
}