still invalid relocations generated for debug info (C++)

Mark Mitchell mark@codesourcery.com
Sun Oct 31 23:03:00 GMT 1999


Fixed with this patch.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

1999-10-21  Mark Mitchell  <mark@codesourcery.com>

	* cp-tree.h (SCOPE_PARTIAL_P): New macro.
	(pushlevel_temporary): Remove.
	(add_scope_stmt): New function.
	* decl.c (pushlevel_temporary): Remove.
	(poplevel): Use add_scope_stmt.
	(start_decl_1): Likewise.
	* semantics.c (add_scope_stmt): New function.
	(do_pushlevel): Use it.
	(do_poplevel): Use it.
	(expand_stmt): Check SCOPE_PARTIAL_P.

Index: testsuite/g++.old-deja/g++.other/debug5.C
===================================================================
RCS file: debug5.C
diff -N debug5.C
*** /dev/null	Tue May  5 13:32:27 1998
--- debug5.C	Thu Oct 21 01:02:33 1999
***************
*** 0 ****
--- 1,15 ----
+ // Build don't link:
+ // Special g++ Options: -g
+ // Origin: Mark Mitchell <mark@codesourcery.com>
+ 
+ struct S
+ {
+   ~S ();
+ };
+ 
+ void f ()
+ {
+  t:
+   S s3;
+ }
+ 
Index: testsuite/g++.old-deja/g++.other/goto1.C
===================================================================
RCS file: goto1.C
diff -N goto1.C
*** /dev/null	Tue May  5 13:32:27 1998
--- goto1.C	Thu Oct 21 01:02:33 1999
***************
*** 0 ****
--- 1,21 ----
+ // Build don't link:
+ // Origin: Mark Mitchell <mark@codesourcery.com>
+ 
+ struct S
+ {
+   S ();
+   ~S ();
+ };
+ 
+ void f ()
+ {
+   {
+     S s1;
+   
+   t:
+     S s2;
+     ;
+   }
+ 
+   goto t; // ERROR - jump avoids initialization of `s1'
+ }
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.334
diff -c -p -r1.334 cp-tree.h
*** cp-tree.h	1999/10/20 07:02:30	1.334
--- cp-tree.h	1999/10/21 08:02:37
*************** Boston, MA 02111-1307, USA.  */
*** 69,74 ****
--- 69,75 ----
        TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR,
            or FIELD_DECL).
        NEED_TEMPORARY_P (in REF_BIND, BASE_CONV)
+       SCOPE_PARTIAL_P (in SCOPE_STMT)
     5: Not used.
     6: Not used.
  
*************** extern int flag_new_for_scope;
*** 2651,2656 ****
--- 2652,2672 ----
  #define SCOPE_NULLIFIED_P(NODE) \
    (TREE_LANG_FLAG_3 (SCOPE_STMT_CHECK (NODE)))
  
+ /* Nonzero for a SCOPE_STMT if this statement is for a partial scope.
+    For example, in:
+   
+      S s;
+      l:
+      S s2;
+      goto l;
+ 
+    there is (implicitly) a new scope after `l', even though there are
+    no curly braces.  In particular, when we hit the goto, we must
+    destroy s2 and then re-construct it.  For the implicit scope,
+    SCOPE_PARTIAL_P will be set.  */
+ #define SCOPE_PARTIAL_P(NODE) \
+   (TREE_LANG_FLAG_4 (SCOPE_STMT_CHECK (NODE)))
+ 
  /* Nonzero for an ASM_STMT if the assembly statement is volatile.  */
  #define ASM_VOLATILE_P(NODE)			\
    (ASM_CV_QUAL (ASM_STMT_CHECK (NODE)) != NULL_TREE)
*************** extern int pseudo_global_level_p		PROTO(
*** 3336,3342 ****
  extern void set_class_shadows			PROTO((tree));
  extern void pushlevel				PROTO((int));
  extern void note_level_for_for			PROTO((void));
- extern void pushlevel_temporary			PROTO((int));
  extern void resume_level			PROTO((struct binding_level *));
  extern void delete_block			PROTO((tree));
  extern void insert_block			PROTO((tree));
--- 3352,3357 ----
*************** extern void expand_body                 
*** 3886,3891 ****
--- 3901,3907 ----
  extern void begin_stmt_tree                     PROTO((tree *));
  extern void finish_stmt_tree                    PROTO((tree *));
  extern void prep_stmt                           PROTO((tree));
+ extern void add_scope_stmt                      PROTO((int, int));
  extern void do_pushlevel                        PROTO((void));
  extern tree do_poplevel                         PROTO((void));
  /* Non-zero if we are presently building a statement tree, rather
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.484
diff -c -p -r1.484 decl.c
*** decl.c	1999/10/13 22:40:42	1.484
--- decl.c	1999/10/21 08:02:46
*************** note_level_for_for ()
*** 825,845 ****
    current_binding_level->is_for_scope = 1;
  }
  
- void
- pushlevel_temporary (tag_transparent)
-      int tag_transparent;
- {
-   pushlevel (tag_transparent);
-   current_binding_level->keep = 2;
-   clear_last_expr ();
- 
-   /* Note we don't call push_momentary() here.  Otherwise, it would cause
-      cleanups to be allocated on the momentary obstack, and they will be
-      overwritten by the next statement.  */
- 
-   expand_start_bindings (0);
- }
- 
  /* For a binding between a name and an entity at a block scope,
     this is the `struct binding_level' for the block.  */
  #define BINDING_LEVEL(NODE) \
--- 825,830 ----
*************** poplevel (keep, reverse, functionbody)
*** 1458,1470 ****
    /* Take care of compiler's internal binding structures.  */
    if (tmp == 2)
      {
!       expand_end_bindings (getdecls (), keep, 1);
        /* Each and every BLOCK node created here in `poplevel' is important
  	 (e.g. for proper debugging information) so if we created one
  	 earlier, mark it as "used".  */
        if (block)
  	TREE_USED (block) = 1;
!       block = poplevel (keep, reverse, real_functionbody);
      }
  
    /* Each and every BLOCK node created here in `poplevel' is important
--- 1443,1455 ----
    /* Take care of compiler's internal binding structures.  */
    if (tmp == 2)
      {
!       add_scope_stmt (/*begin_p=*/0, /*partial_p=*/1);
        /* Each and every BLOCK node created here in `poplevel' is important
  	 (e.g. for proper debugging information) so if we created one
  	 earlier, mark it as "used".  */
        if (block)
  	TREE_USED (block) = 1;
!       block = poplevel (keep, reverse, functionbody);
      }
  
    /* Each and every BLOCK node created here in `poplevel' is important
*************** start_decl_1 (decl)
*** 6874,6885 ****
    if (type == error_mark_node)
      return;
  
!   /* If this type of object needs a cleanup, and control may
!      jump past it, make a new binding level so that it is cleaned
!      up only when it is initialized first.  */
    if (TYPE_NEEDS_DESTRUCTOR (type)
        && current_binding_level->more_cleanups_ok == 0)
!     pushlevel_temporary (1);
  
    if (initialized)
      /* Is it valid for this decl to have an initializer at all?
--- 6859,6875 ----
    if (type == error_mark_node)
      return;
  
!   /* If this type of object needs a cleanup, but we're not allowed to
!      add any more objects with cleanups to the current scope, create a
!      new binding level.  */
    if (TYPE_NEEDS_DESTRUCTOR (type)
        && current_binding_level->more_cleanups_ok == 0)
!     {
!       keep_next_level (2);
!       pushlevel (1);
!       clear_last_expr ();
!       add_scope_stmt (/*begin_p=*/1, /*partial_p=*/1);
!     }
  
    if (initialized)
      /* Is it valid for this decl to have an initializer at all?
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/semantics.c,v
retrieving revision 1.97
diff -c -p -r1.97 semantics.c
*** semantics.c	1999/10/09 21:06:03	1.97
--- semantics.c	1999/10/21 08:02:47
*************** setup_vtbl_ptr ()
*** 1248,1253 ****
--- 1248,1290 ----
    vtbls_set_up_p = 1;
  }
  
+ /* Add a scope-statement to the statement-tree.  BEGIN_P indicates
+    whether this statements opens or closes a scope.  PARTIAL_P is true
+    for a partial scope, i.e, the scope that begins after a label when
+    an object that needs a cleanup is created.  */
+ 
+ void
+ add_scope_stmt (begin_p, partial_p)
+      int begin_p;
+      int partial_p;
+ {
+   tree ss;
+ 
+   /* Build the statement.  */
+   ss = build_min_nt (SCOPE_STMT);
+   SCOPE_BEGIN_P (ss) = begin_p;
+   SCOPE_PARTIAL_P (ss) = partial_p;
+ 
+   /* If we're finishing a scope, figure out whether the scope was
+      really necessary.  */
+   if (!begin_p)
+     {
+       SCOPE_NULLIFIED_P (ss) = !kept_level_p ();
+       SCOPE_NULLIFIED_P (TREE_VALUE (current_scope_stmt_stack))
+ 	= SCOPE_NULLIFIED_P (ss);
+     }
+ 
+   /* Keep the scope stack up to date.  */
+   if (begin_p)
+     current_scope_stmt_stack 
+       = tree_cons (NULL_TREE, ss, current_scope_stmt_stack);
+   else
+     current_scope_stmt_stack = TREE_CHAIN (current_scope_stmt_stack);
+ 
+   /* Add the new statement to the statement-tree.  */
+   add_tree (ss);
+ }
+ 
  /* Begin a new scope.  */
  
  void
*************** do_pushlevel ()
*** 1266,1278 ****
  	  && !current_function->x_whole_function_mode_p)
  	expand_start_bindings (0);
        else if (building_stmt_tree () && !processing_template_decl)
! 	{
! 	  tree ss = build_min_nt (SCOPE_STMT);
! 	  SCOPE_BEGIN_P (ss) = 1;
! 	  add_tree (ss);
! 	  current_scope_stmt_stack 
! 	    = tree_cons (NULL_TREE, ss, current_scope_stmt_stack);
! 	}
      }
  }
  
--- 1303,1309 ----
  	  && !current_function->x_whole_function_mode_p)
  	expand_start_bindings (0);
        else if (building_stmt_tree () && !processing_template_decl)
! 	add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
      }
  }
  
*************** do_poplevel ()
*** 1290,1301 ****
  	expand_end_bindings (getdecls (), kept_level_p (), 0);
        else if (building_stmt_tree () && !processing_template_decl)
  	{
! 	  tree ss = build_min_nt (SCOPE_STMT);
! 	  SCOPE_NULLIFIED_P (ss) = !kept_level_p ();
! 	  SCOPE_NULLIFIED_P (TREE_VALUE (current_scope_stmt_stack))
! 	    = SCOPE_NULLIFIED_P (ss);
! 	  add_tree (ss);
! 	  current_scope_stmt_stack = TREE_CHAIN (current_scope_stmt_stack);
  
  	  /* When not in function-at-a-time mode, expand_end_bindings
  	     will warn about unused variables.  But, in
--- 1321,1327 ----
  	expand_end_bindings (getdecls (), kept_level_p (), 0);
        else if (building_stmt_tree () && !processing_template_decl)
  	{
! 	  add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
  
  	  /* When not in function-at-a-time mode, expand_end_bindings
  	     will warn about unused variables.  But, in
*************** expand_stmt (t)
*** 2455,2461 ****
  	  if (SCOPE_BEGIN_P (t))
  	    expand_start_bindings (2 * SCOPE_NULLIFIED_P (t));
  	  else if (SCOPE_END_P (t))
! 	    expand_end_bindings (NULL_TREE, !SCOPE_NULLIFIED_P (t), 0);
  	  break;
  
  	case RETURN_INIT:
--- 2481,2488 ----
  	  if (SCOPE_BEGIN_P (t))
  	    expand_start_bindings (2 * SCOPE_NULLIFIED_P (t));
  	  else if (SCOPE_END_P (t))
! 	    expand_end_bindings (NULL_TREE, !SCOPE_NULLIFIED_P (t), 
! 				 SCOPE_PARTIAL_P (t));
  	  break;
  
  	case RETURN_INIT:



More information about the Gcc-bugs mailing list