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 [3.3.3] PR 13544


This is my proposed fix for PR C++/13544, a latent bug that was
uncovered by my backporting a fix for C++/12862 to gcc-3_3-branch.

When pushing an enumerator at namespace-scope, pushdecl() uses
DECL_NAMESPACE_SCOPE_P  to test whether there already is a declaration
for that name at namespace-scope; then we proceed on looking up that
putative other declaration (and  later erroneously error()).

That is not right, for at least two reasons (Mark already warned that
3.3.x was not setting DECL_CONTEXT properly):
  (1) DECL_NAMESPACE_SCOPE_P does not actually test whether a decl has
      a namespace scope -- because if teh DECL_CONTEXT is absent then
      it defaults to the global_namespace;

  (2) when declaring an enumarator, there is no way to explicitly
      qualify that enumerator.

This patch makes us use a more correct logic for testing whether a
decl has a namespace-scope in pushdecl(), and defer setting
DECL_CONTEXT after pushdecl().

Bootstrapped and regression tested.  Mark, Jason, do you have comments?
 

-- Gaby
Index: cp/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/ChangeLog,v
retrieving revision 1.3076.2.235
diff -p -r1.3076.2.235 ChangeLog
*** cp/ChangeLog	2 Jan 2004 11:15:01 -0000	1.3076.2.235
--- cp/ChangeLog	11 Jan 2004 00:32:29 -0000
***************
*** 1,3 ****
--- 1,11 ----
+ 2004-01-11  Gabriel Dos Reis <gdr@integrable-solutions.net>
+ 
+ 	PR c++/13544
+ 	* decl.c (build_enumerator): Set DECL_CONTEXT after the enumerator
+ 	has been pushed.
+ 	(pushdecl): Don't use DECL_NAMESPACE_SCOPE_P to test whether a
+ 	decl has a namespace-scope; that isn't really what it means.
+ 
  2004-01-02  Matthias Klose  <doko@debian.org>
  
  	Backport from mainline:
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.965.2.70
diff -p -r1.965.2.70 decl.c
*** cp/decl.c	2 Jan 2004 11:15:00 -0000	1.965.2.70
--- cp/decl.c	11 Jan 2004 00:32:36 -0000
*************** pushdecl (x)
*** 4142,4149 ****
  
        /* In case this decl was explicitly namespace-qualified, look it
  	 up in its namespace context.  */
!       if (DECL_NAMESPACE_SCOPE_P (x) && namespace_bindings_p ())
! 	t = namespace_binding (name, DECL_CONTEXT (x));
        else
  	t = lookup_name_current_level (name);
  
--- 4142,4150 ----
  
        /* In case this decl was explicitly namespace-qualified, look it
  	 up in its namespace context.  */
!       if ((DECL_CONTEXT (x) && TREE_CODE (DECL_CONTEXT (x)) == NAMESPACE_DECL)
!           && namespace_bindings_p ())
!         t = namespace_binding (name, DECL_CONTEXT (x));
        else
  	t = lookup_name_current_level (name);
  
*************** build_enumerator (name, value, enumtype)
*** 14185,14191 ****
        a function could mean local to a class method.  */
      decl = build_decl (CONST_DECL, name, type);
  
-   DECL_CONTEXT (decl) = FROB_CONTEXT (context);
    DECL_INITIAL (decl) = value;
    TREE_READONLY (decl) = 1;
  
--- 14186,14191 ----
*************** build_enumerator (name, value, enumtype)
*** 14195,14201 ****
        things like `S::i' later.)  */
      finish_member_declaration (decl);
    else
!     pushdecl (decl);
  
    /* Add this enumeration constant to the list for this type.  */
    TYPE_VALUES (enumtype) = tree_cons (name, decl, TYPE_VALUES (enumtype));
--- 14195,14208 ----
        things like `S::i' later.)  */
      finish_member_declaration (decl);
    else
!     {
!       pushdecl (decl);
!       /* Contrary to finish_member_declaration, pushdecl does not properly
!          set the DECL_CONTEXT.  Do that now here.  Doing that before calling
!          pushdecl will confuse the logic used in that function.  Hopefully,
!          future versions will implement a more straight logic.  */
!       DECL_CONTEXT (decl) = FROB_CONTEXT (context);
!     }
  
    /* Add this enumeration constant to the list for this type.  */
    TYPE_VALUES (enumtype) = tree_cons (name, decl, TYPE_VALUES (enumtype));
Index: testsuite/g++.dg/lookup/enum1.C
===================================================================
RCS file: testsuite/g++.dg/lookup/enum1.C
diff -N testsuite/g++.dg/lookup/enum1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/lookup/enum1.C	11 Jan 2004 00:32:37 -0000
***************
*** 0 ****
--- 1,9 ----
+ enum Enum1 { None };
+ 
+ namespace Test {
+    enum Enum2 { None };
+ }
+ 
+ namespace a {
+    enum { a } ;
+ };


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