Commit 9306cccb by Mark Mitchell Committed by Mark Mitchell

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
parent b7392506
2004-11-24 Mark Mitchell <mark@codesourcery.com>
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 <stevenb@suse.de> 2004-11-24 Steven Bosscher <stevenb@suse.de>
* decl.c (cxx_init_decl_processing): Don't clear * decl.c (cxx_init_decl_processing): Don't clear
......
...@@ -531,19 +531,24 @@ supplement_binding (cxx_binding *binding, tree decl) ...@@ -531,19 +531,24 @@ supplement_binding (cxx_binding *binding, tree decl)
else if (TREE_CODE (bval) == TYPE_DECL else if (TREE_CODE (bval) == TYPE_DECL
&& TREE_CODE (decl) == TYPE_DECL && TREE_CODE (decl) == TYPE_DECL
&& DECL_NAME (decl) == DECL_NAME (bval) && DECL_NAME (decl) == DECL_NAME (bval)
&& binding->scope->kind != sk_class
&& (same_type_p (TREE_TYPE (decl), TREE_TYPE (bval)) && (same_type_p (TREE_TYPE (decl), TREE_TYPE (bval))
/* If either type involves template parameters, we must /* If either type involves template parameters, we must
wait until instantiation. */ wait until instantiation. */
|| uses_template_parms (TREE_TYPE (decl)) || uses_template_parms (TREE_TYPE (decl))
|| uses_template_parms (TREE_TYPE (bval)))) || uses_template_parms (TREE_TYPE (bval))))
/* We have two typedef-names, both naming the same type to have /* 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] [dcl.typedef]
In a given scope, a typedef specifier can be used to redefine 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 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; ok = false;
/* There can be two block-scope declarations of the same variable, /* There can be two block-scope declarations of the same variable,
so long as they are `extern' declarations. However, there cannot so long as they are `extern' declarations. However, there cannot
......
...@@ -15343,12 +15343,14 @@ cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs, ...@@ -15343,12 +15343,14 @@ cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
{ {
decl_specs->any_specifiers_p = true; decl_specs->any_specifiers_p = true;
/* If the user tries to redeclare a built-in type (with, for example, /* If the user tries to redeclare bool or wchar_t (with, for
in "typedef int wchar_t;") we remember that this is what example, in "typedef int wchar_t;") we remember that this is what
happened. In system headers, we ignore these declarations so happened. In system headers, we ignore these declarations so
that G++ can work with system headers that are not C++-safe. */ that G++ can work with system headers that are not C++-safe. */
if (decl_specs->specs[(int) ds_typedef] if (decl_specs->specs[(int) ds_typedef]
&& !user_defined_p && !user_defined_p
&& (type_spec == boolean_type_node
|| type_spec == wchar_type_node)
&& (decl_specs->type && (decl_specs->type
|| decl_specs->specs[(int) ds_long] || decl_specs->specs[(int) ds_long]
|| decl_specs->specs[(int) ds_short] || decl_specs->specs[(int) ds_short]
......
2004-11-24 Mark Mitchell <mark@codesourcery.com>
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 <rsandifo@redhat.com> 2004-11-24 Richard Sandiford <rsandifo@redhat.com>
* gcc.c-torture/execute/20041124-1.c: New test. * gcc.c-torture/execute/20041124-1.c: New test.
......
// PR c++/18285
typedef void int char void double X; // { dg-error "" }
// { dg-do compile }
// Origin: Giovanni Bajo <giovannibajo at gcc dot gnu dot org>
// 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;
...@@ -12,10 +12,10 @@ template <typename T> struct A ...@@ -12,10 +12,10 @@ template <typename T> struct A
template <typename T> struct B template <typename T> struct B
{ {
typedef int xxx; typedef int xxx; // { dg-error "" }
typedef T xxx; typedef T xxx; // { dg-error "" }
typedef typename A<T>::type xxx; typedef typename A<T>::type xxx; // { dg-error "" }
typedef A<int>::type xxx; typedef A<int>::type xxx; // { dg-error "" }
}; };
B<int> good; B<int> good;
...@@ -4,14 +4,17 @@ ...@@ -4,14 +4,17 @@
typedef int I; typedef int I;
typedef int I; typedef int I;
// DR56 makes clear that duplicate typedefs in class scopes are
// invalid.
struct A { struct A {
typedef int I; typedef int I; // { dg-error "" }
typedef int I; typedef int I; // { dg-error "" }
}; };
template <class T> template <class T>
struct S { struct S {
typedef int I; typedef int I; // { dg-error "" }
typedef int I; typedef int I; // { dg-error "" }
}; };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment