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