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]
Other format: [Raw text]

C++ PATCH: 17473 and 18285


This patch fixes two C++ regression.

PR 17473 is a PR about the fact that DR56 makes clear that redundant
typedefs are not permitted in class scopes.  We had various tests for
and against this behavior littered around the testsuite; fixing this
PR made that clear, and I removed some of the redundancy.

PR 18285 regarding a case where the new parser allowed nonsensical
typedefs like "typedef void int X".

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

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

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  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.

Index: cp/name-lookup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/name-lookup.c,v
retrieving revision 1.92
diff -c -5 -p -r1.92 name-lookup.c
*** cp/name-lookup.c	15 Nov 2004 10:33:49 -0000	1.92
--- cp/name-lookup.c	24 Nov 2004 23:16:46 -0000
*************** supplement_binding (cxx_binding *binding
*** 529,551 ****
        binding->value_is_inherited = false;
      }
    else if (TREE_CODE (bval) == TYPE_DECL
  	   && TREE_CODE (decl) == TYPE_DECL
  	   && DECL_NAME (decl) == DECL_NAME (bval)
  	   && (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:
  
           [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.  */
      ok = false;
    /* There can be two block-scope declarations of the same variable,
       so long as they are `extern' declarations.  However, there cannot
       be two declarations of the same static data member:
  
--- 529,556 ----
        binding->value_is_inherited = false;
      }
    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.  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.  
! 
!        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
       be two declarations of the same static data member:
  
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.280
diff -c -5 -p -r1.280 parser.c
*** cp/parser.c	24 Nov 2004 18:10:13 -0000	1.280
--- cp/parser.c	24 Nov 2004 23:16:46 -0000
*************** cp_parser_set_decl_spec_type (cp_decl_sp
*** 15341,15356 ****
  			      tree type_spec,
  			      bool user_defined_p)
  {
    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
       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
        && (decl_specs->type
  	  || decl_specs->specs[(int) ds_long]
  	  || decl_specs->specs[(int) ds_short]
  	  || decl_specs->specs[(int) ds_unsigned]
  	  || decl_specs->specs[(int) ds_signed]))
--- 15341,15358 ----
  			      tree type_spec,
  			      bool user_defined_p)
  {
    decl_specs->any_specifiers_p = true;
  
!   /* 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]
  	  || decl_specs->specs[(int) ds_unsigned]
  	  || decl_specs->specs[(int) ds_signed]))
Index: testsuite/g++.dg/tc1/dr56.C
===================================================================
RCS file: testsuite/g++.dg/tc1/dr56.C
diff -N testsuite/g++.dg/tc1/dr56.C
*** testsuite/g++.dg/tc1/dr56.C	17 Feb 2004 15:33:49 -0000	1.2
--- /dev/null	1 Jan 1970 00:00:00 -0000
***************
*** 1,12 ****
- // { 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;
--- 0 ----
Index: testsuite/g++.dg/template/typedef1.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/template/typedef1.C,v
retrieving revision 1.1
diff -c -5 -p -r1.1 typedef1.C
*** testsuite/g++.dg/template/typedef1.C	10 Dec 2001 22:49:13 -0000	1.1
--- testsuite/g++.dg/template/typedef1.C	24 Nov 2004 23:16:46 -0000
*************** template <typename T> struct A
*** 10,21 ****
    typedef T type;
  };
  
  template <typename T> struct B
  {
!   typedef int xxx;
!   typedef T xxx;
!   typedef typename A<T>::type xxx;
!   typedef A<int>::type xxx;
  };
  
  B<int> good;
--- 10,21 ----
    typedef T type;
  };
  
  template <typename T> struct B
  {
!   typedef int xxx; // { dg-error "" }
!   typedef T xxx; // { dg-error "" }
!   typedef typename A<T>::type xxx; // { dg-error "" }
!   typedef A<int>::type xxx; // { dg-error "" }
  };
  
  B<int> good;
Index: testsuite/g++.old-deja/g++.other/typedef7.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.other/typedef7.C,v
retrieving revision 1.3
diff -c -5 -p -r1.3 typedef7.C
*** testsuite/g++.old-deja/g++.other/typedef7.C	1 May 2003 02:02:52 -0000	1.3
--- testsuite/g++.old-deja/g++.other/typedef7.C	24 Nov 2004 23:16:46 -0000
***************
*** 2,17 ****
  // Origin: Mark Mitchell <mark@codesourcery.com>
  
  typedef int I;
  typedef int I;
  
  struct A {
!   typedef int I;
!   typedef int I;
  };
  
  template <class T>
  struct S {
!   typedef int I;
!   typedef int I;
  };
  
--- 2,20 ----
  // Origin: Mark Mitchell <mark@codesourcery.com>
  
  typedef int I;
  typedef int I;
  
+ // DR56 makes clear that duplicate typedefs in class scopes are
+ // invalid.
+ 
  struct A {
!   typedef int I; // { dg-error "" }
!   typedef int I; // { dg-error "" }
  };
  
  template <class T>
  struct S {
!   typedef int I;  // { dg-error "" }
!   typedef int I;  // { dg-error "" }
  };
  
Index: testsuite/g++.dg/parse/typedef7.C
===================================================================
RCS file: testsuite/g++.dg/parse/typedef7.C
diff -N testsuite/g++.dg/parse/typedef7.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/parse/typedef7.C	24 Nov 2004 23:16:46 -0000
***************
*** 0 ****
--- 1,2 ----
+ // PR c++/18285
+ typedef void int char void double X; // { dg-error "" } 


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