diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 237207a5ef49066597d63c9eaded4119b09c420b..c9984460b3dc73afb961a51492b31e780d5b4827 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2004-01-07 Joseph S. Myers <jsm@polyomino.org.uk> + + PR c/12165 + * c-decl.c (grokdeclarator): Take type qualifiers of typedefed + array type from the array element type. + 2004-01-07 Alan Modra <amodra@bigpond.net.au> * config/rs6000/rs6000.c (rs6000_dbx_register_number): New function. diff --git a/gcc/c-decl.c b/gcc/c-decl.c index ee2db9e1fc42ac94378bedd667725d5b08dea629..b41ed8671bcd4c3097d75678efa194f1a03ecccf 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -1,6 +1,6 @@ /* Process declarations and variables for C compiler. Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003 Free Software Foundation, Inc. + 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GCC. @@ -3349,6 +3349,7 @@ grokdeclarator (tree declarator, tree declspecs, int array_parm_static = 0; tree returned_attrs = NULL_TREE; bool bitfield = width != NULL; + tree element_type; if (decl_context == FUNCDEF) funcdef_flag = 1, decl_context = NORMAL; @@ -3694,10 +3695,19 @@ grokdeclarator (tree declarator, tree declspecs, two ways a declaration can become qualified. One is something like `const int i' where the `const' is explicit. Another is something like `typedef const int CI; CI i' where the type of the - declaration contains the `const'. */ - constp = !! (specbits & 1 << (int) RID_CONST) + TYPE_READONLY (type); - restrictp = !! (specbits & 1 << (int) RID_RESTRICT) + TYPE_RESTRICT (type); - volatilep = !! (specbits & 1 << (int) RID_VOLATILE) + TYPE_VOLATILE (type); + declaration contains the `const'. A third possibility is that + there is a type qualifier on the element type of a typedefed + array type, in which case we should extract that qualifier so + that c_apply_type_quals_to_decls receives the full list of + qualifiers to work with (C90 is not entirely clear about whether + duplicate qualifiers should be diagnosed in this case, but it + seems most appropriate to do so). */ + element_type = strip_array_types (type); + constp = !! (specbits & 1 << (int) RID_CONST) + TYPE_READONLY (element_type); + restrictp + = !! (specbits & 1 << (int) RID_RESTRICT) + TYPE_RESTRICT (element_type); + volatilep + = !! (specbits & 1 << (int) RID_VOLATILE) + TYPE_VOLATILE (element_type); inlinep = !! (specbits & (1 << (int) RID_INLINE)); if (constp > 1 && ! flag_isoc99) pedwarn ("duplicate `const'"); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f57a826865238fdc2fa083035a6c23fce5691972..020ffd89b924db49f735398efc84bb066f2dfa31 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2004-01-07 Joseph S. Myers <jsm@polyomino.org.uk> + + PR c/12165 + * gcc.dg/array-quals-1.c, gcc.dg/c90-idem-qual-3.c, + gcc.dg/c99-idem-qual-3.c: New tests. + 2004-01-07 Alan Modra <amodra@bigpond.net.au> * gcc.dg/winline-7.c: Don't cast void * to int. diff --git a/gcc/testsuite/gcc.dg/array-quals-1.c b/gcc/testsuite/gcc.dg/array-quals-1.c new file mode 100644 index 0000000000000000000000000000000000000000..7d2b72c6b980b7e9b3507e223c756818b5c96f94 --- /dev/null +++ b/gcc/testsuite/gcc.dg/array-quals-1.c @@ -0,0 +1,29 @@ +/* Test for various combinations of const, arrays and typedefs: + should never actually get const on the final array type, but + all should end up in a read-only section. PR c/12165. */ +/* Origin: Joseph Myers <jsm@polyomino.org.uk> */ +/* { dg-do compile } */ +/* { dg-final { scan-assembler-not "\\.data" } } */ +static const int a[2] = { 1, 2 }; +const int a1[2] = { 1, 2 }; +typedef const int ci; +static ci b[2] = { 3, 4 }; +ci b1[2] = { 3, 4 }; +typedef int ia[2]; +static const ia c = { 5, 6 }; +const ia c1 = { 5, 6 }; +typedef const int cia[2]; +static cia d = { 7, 8 }; +cia d1 = { 7, 8 }; +static cia e[2] = { { 1, 2 }, { 3, 4 } }; +cia e1[2] = { { 1, 2 }, { 3, 4 } }; +void *const p = &a; +void *const q = &b; +void *const r = &c; +void *const s = &d; +void *const t = &e; +void *const p1 = &a1; +void *const q1 = &b1; +void *const r1 = &c1; +void *const s1 = &d1; +void *const t1 = &e1; diff --git a/gcc/testsuite/gcc.dg/c90-idem-qual-3.c b/gcc/testsuite/gcc.dg/c90-idem-qual-3.c new file mode 100644 index 0000000000000000000000000000000000000000..9976a0888fb51f6f36c971fed806e8ea6a04cb2c --- /dev/null +++ b/gcc/testsuite/gcc.dg/c90-idem-qual-3.c @@ -0,0 +1,11 @@ +/* Test for idempotent type qualifiers: in C99 only. Test duplicate + type qualifiers with array element types. */ +/* Origin: Joseph Myers <jsm@polyomino.org.uk> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1990 -pedantic-errors" } */ + +typedef const int cia[2]; +const cia a; /* { dg-bogus "warning" "warning in place of error" } */ +/* { dg-error "duplicate" "duplicate type qualifier error" { target *-*-* } 8 } */ +const cia b[2]; /* { dg-bogus "warning" "warning in place of error" } */ +/* { dg-error "duplicate" "duplicate type qualifier error" { target *-*-* } 10 } */ diff --git a/gcc/testsuite/gcc.dg/c99-idem-qual-3.c b/gcc/testsuite/gcc.dg/c99-idem-qual-3.c new file mode 100644 index 0000000000000000000000000000000000000000..0f34f832188661c5472a61c59c3f2035b562d42d --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-idem-qual-3.c @@ -0,0 +1,9 @@ +/* Test for idempotent type qualifiers: in C99 only. Test duplicate + type qualifiers with array element types. */ +/* Origin: Joseph Myers <jsm@polyomino.org.uk> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */ + +typedef const int cia[2]; +const cia a; /* { dg-bogus "duplicate" "duplicate type qualifier warning" } */ +const cia b[2]; /* { dg-bogus "duplicate" "duplicate type qualifier warning" } */