From 9306cccbb5efd2422becd7ed19f0a7b1495083a4 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Wed, 24 Nov 2004 23:18:56 +0000 Subject: [PATCH] re PR c++/17473 (typedef redefinition in struct is accepted) PR c++/17473 * name-lookup.c (supplement_binding): Do not allow typedefs to be redefined in class scope. PR c++/18285 * parser.c (cp_parser_set_decl_type_spec): Do not try to allow redefinitions of builtin types other that "bool" or "wchar_t". PR c++/17473 * g++.dg/tc1/dr56.C: Remove. * g++.dg/template/typedef1.C: Add dg-error markers. * g++.old-deja/g++.other/typedef7.C: Likewise. PR c++/18285 * g++.dg/parse/typedef7.C: New test. From-SVN: r91254 --- gcc/cp/ChangeLog | 10 ++++++++++ gcc/cp/name-lookup.c | 9 +++++++-- gcc/cp/parser.c | 6 ++++-- gcc/testsuite/ChangeLog | 10 ++++++++++ gcc/testsuite/g++.dg/parse/typedef7.C | 2 ++ gcc/testsuite/g++.dg/tc1/dr56.C | 12 ------------ gcc/testsuite/g++.dg/template/typedef1.C | 8 ++++---- gcc/testsuite/g++.old-deja/g++.other/typedef7.C | 11 +++++++---- 8 files changed, 44 insertions(+), 24 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/typedef7.C delete mode 100644 gcc/testsuite/g++.dg/tc1/dr56.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 95e2ed4c4c2e..ecc122e3363b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2004-11-24 Mark Mitchell + + PR c++/17473 + * name-lookup.c (supplement_binding): Do not allow typedefs to be + redefined in class scope. + + PR c++/18285 + * parser.c (cp_parser_set_decl_type_spec): Do not try to allow + redefinitions of builtin types other that "bool" or "wchar_t". + 2004-11-24 Steven Bosscher * decl.c (cxx_init_decl_processing): Don't clear diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 0abe1eca9cf9..29b93ffe921c 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -531,19 +531,24 @@ supplement_binding (cxx_binding *binding, tree decl) else if (TREE_CODE (bval) == TYPE_DECL && TREE_CODE (decl) == TYPE_DECL && DECL_NAME (decl) == DECL_NAME (bval) + && binding->scope->kind != sk_class && (same_type_p (TREE_TYPE (decl), TREE_TYPE (bval)) /* If either type involves template parameters, we must wait until instantiation. */ || uses_template_parms (TREE_TYPE (decl)) || uses_template_parms (TREE_TYPE (bval)))) /* We have two typedef-names, both naming the same type to have - the same name. This is OK because of: + the same name. In general, this is OK because of: [dcl.typedef] In a given scope, a typedef specifier can be used to redefine the name of any type declared in that scope to refer to the - type to which it already refers. */ + type to which it already refers. + + However, in class scopes, this rule does not apply due to the + stricter language in [class.mem] prohibiting redeclarations of + members. */ ok = false; /* There can be two block-scope declarations of the same variable, so long as they are `extern' declarations. However, there cannot diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ccd8a95c434e..1a9786845c49 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -15343,12 +15343,14 @@ cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs, { decl_specs->any_specifiers_p = true; - /* If the user tries to redeclare a built-in type (with, for example, - in "typedef int wchar_t;") we remember that this is what + /* If the user tries to redeclare bool or wchar_t (with, for + example, in "typedef int wchar_t;") we remember that this is what happened. In system headers, we ignore these declarations so that G++ can work with system headers that are not C++-safe. */ if (decl_specs->specs[(int) ds_typedef] && !user_defined_p + && (type_spec == boolean_type_node + || type_spec == wchar_type_node) && (decl_specs->type || decl_specs->specs[(int) ds_long] || decl_specs->specs[(int) ds_short] diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 25f2f13d62c3..19579e98da10 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2004-11-24 Mark Mitchell + + PR c++/17473 + * g++.dg/tc1/dr56.C: Remove. + * g++.dg/template/typedef1.C: Add dg-error markers. + * g++.old-deja/g++.other/typedef7.C: Likewise. + + PR c++/18285 + * g++.dg/parse/typedef7.C: New test. + 2004-11-24 Richard Sandiford * gcc.c-torture/execute/20041124-1.c: New test. diff --git a/gcc/testsuite/g++.dg/parse/typedef7.C b/gcc/testsuite/g++.dg/parse/typedef7.C new file mode 100644 index 000000000000..126fb7ed8506 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/typedef7.C @@ -0,0 +1,2 @@ +// PR c++/18285 +typedef void int char void double X; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/tc1/dr56.C b/gcc/testsuite/g++.dg/tc1/dr56.C deleted file mode 100644 index a5caea82655e..000000000000 --- a/gcc/testsuite/g++.dg/tc1/dr56.C +++ /dev/null @@ -1,12 +0,0 @@ -// { dg-do compile } -// Origin: Giovanni Bajo -// DR56: Redeclaring typedefs within classes - -class X { - typedef int I; - typedef int I; // { dg-error "" "Cannot redeclare a typedef in a class scope" { xfail *-*-* } } -}; - -// In non-class scope, they are allowed. -typedef int A; -typedef int A; diff --git a/gcc/testsuite/g++.dg/template/typedef1.C b/gcc/testsuite/g++.dg/template/typedef1.C index 03257571d1d0..75b00e0fb2a6 100644 --- a/gcc/testsuite/g++.dg/template/typedef1.C +++ b/gcc/testsuite/g++.dg/template/typedef1.C @@ -12,10 +12,10 @@ template struct A template struct B { - typedef int xxx; - typedef T xxx; - typedef typename A::type xxx; - typedef A::type xxx; + typedef int xxx; // { dg-error "" } + typedef T xxx; // { dg-error "" } + typedef typename A::type xxx; // { dg-error "" } + typedef A::type xxx; // { dg-error "" } }; B good; diff --git a/gcc/testsuite/g++.old-deja/g++.other/typedef7.C b/gcc/testsuite/g++.old-deja/g++.other/typedef7.C index f49ae47c879f..42cf4f1c5e23 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/typedef7.C +++ b/gcc/testsuite/g++.old-deja/g++.other/typedef7.C @@ -4,14 +4,17 @@ typedef int I; typedef int I; +// DR56 makes clear that duplicate typedefs in class scopes are +// invalid. + struct A { - typedef int I; - typedef int I; + typedef int I; // { dg-error "" } + typedef int I; // { dg-error "" } }; template struct S { - typedef int I; - typedef int I; + typedef int I; // { dg-error "" } + typedef int I; // { dg-error "" } };