This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PR21391: pruning unused debugging types (c++ bits)
> I think you want to unwrap both pointers and arrays.
>
> while (POINTER_TYPE_P (t) || TREE_TYPE (t) == ARRAY_TYPE)
> t = TREE_TYPE (t);
>
> And you may well want to also do
>
> t = TYPE_MAIN_VARIANT (t);
Perfect. Now we can use maybe_used_types_insert exclusively, even in
the C parser.
Preliminary tests show this patch to work. Full bootstrap in progress.
How does this look?
PR/21391
* c-parser.c (c_parser_cast_expression): Only insert casts into
hash table if pointer.
* function.c (maybe_used_types_insert): New.
(used_types_insert): Declare static.
* function.h (maybe_used_types_insert): Protoize.
(used_types_insert): Remove prototype.
* cp/typeck.c (build_static_cast_1): Save casted types in used types
hash table.
(build_reinterpret_cast_1): Same.
* cp/rtti.c (build_dynamic_cast_1): Same.
* testsuite/g++.dg/other/unused1.C: New.
Index: c-parser.c
===================================================================
--- c-parser.c (revision 113248)
+++ c-parser.c (working copy)
@@ -4662,8 +4662,7 @@ c_parser_cast_expression (c_parser *pars
}
/* Save casted types in the function's used types hash table. */
- if (debug_info_level > DINFO_LEVEL_NONE)
- used_types_insert (type_name->specs->type, cfun);
+ maybe_used_types_insert (type_name->specs->type);
if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
return c_parser_postfix_expression_after_paren_type (parser,
Index: function.c
===================================================================
--- function.c (revision 113248)
+++ function.c (working copy)
@@ -5590,23 +5590,35 @@ rest_of_handle_check_leaf_regs (void)
return 0;
}
-/* Insert a type into the used types hash table. */
-void
-used_types_insert (tree t, struct function *func)
+/* Insert a TYPE into the used types hash table of CFUN. */
+static void
+used_types_insert (tree type, struct function *func)
{
- if (t != NULL && func != NULL)
+ if (type != NULL && func != NULL)
{
void **slot;
if (func->used_types_hash == NULL)
func->used_types_hash = htab_create_ggc (37, htab_hash_pointer,
- htab_eq_pointer, NULL);
- slot = htab_find_slot (func->used_types_hash, t, INSERT);
+ htab_eq_pointer, NULL);
+ slot = htab_find_slot (func->used_types_hash, type, INSERT);
if (*slot == NULL)
- *slot = t;
+ *slot = type;
}
}
+/* Given a type, insert it into the used hash table in cfun, only if
+ the type is a pointer or reference type. */
+void
+maybe_used_types_insert (tree t)
+{
+ while (POINTER_TYPE_P (t) || TREE_CODE (t) == ARRAY_TYPE)
+ t = TREE_TYPE (t);
+ t = TYPE_MAIN_VARIANT (t);
+ if (t && debug_info_level > DINFO_LEVEL_NONE)
+ used_types_insert (t, cfun);
+}
+
struct tree_opt_pass pass_leaf_regs =
{
NULL, /* name */
Index: function.h
===================================================================
--- function.h (revision 113248)
+++ function.h (working copy)
@@ -576,6 +576,6 @@ extern bool pass_by_reference (CUMULATIV
extern bool reference_callee_copied (CUMULATIVE_ARGS *, enum machine_mode,
tree, bool);
-extern void used_types_insert (tree, struct function *);
+extern void maybe_used_types_insert (tree);
#endif /* GCC_FUNCTION_H */
Index: cp/typeck.c
===================================================================
--- cp/typeck.c (revision 113248)
+++ cp/typeck.c (working copy)
@@ -4759,6 +4759,9 @@ build_static_cast_1 (tree type, tree exp
intype = TREE_TYPE (expr);
+ /* Save casted types in the function's used types hash table. */
+ maybe_used_types_insert (type);
+
/* Determine what to do when casting away constness. */
if (c_cast_p)
{
@@ -5047,6 +5050,9 @@ build_reinterpret_cast_1 (tree type, tre
intype = TREE_TYPE (expr);
+ /* Save casted types in the function's used types hash table. */
+ maybe_used_types_insert (type);
+
/* [expr.reinterpret.cast]
An lvalue expression of type T1 can be cast to the type
"reference to T2" if an expression of type "pointer to T1" can be
@@ -5242,6 +5248,9 @@ build_const_cast_1 (tree dst_type, tree
return error_mark_node;
}
+ /* Save casted types in the function's used types hash table. */
+ maybe_used_types_insert (dst_type);
+
src_type = TREE_TYPE (expr);
/* Expressions do not really have reference types. */
if (TREE_CODE (src_type) == REFERENCE_TYPE)
Index: cp/rtti.c
===================================================================
--- cp/rtti.c (revision 113248)
+++ cp/rtti.c (working copy)
@@ -464,6 +464,9 @@ build_dynamic_cast_1 (tree type, tree ex
tree old_expr = expr;
const char *errstr = NULL;
+ /* Save casted types in the function's used types hash table. */
+ maybe_used_types_insert (type);
+
/* T shall be a pointer or reference to a complete class type, or
`pointer to cv void''. */
switch (tc)
Index: testsuite/g++.dg/other/unused1.C
===================================================================
--- testsuite/g++.dg/other/unused1.C (revision 0)
+++ testsuite/g++.dg/other/unused1.C (revision 0)
@@ -0,0 +1,47 @@
+/* { dg-do compile } */
+/* { dg-options "-g" } */
+
+/* Make sure we didn't eliminate casted types because we thought they were
+ unused. */
+
+void *voidp;
+
+struct foo { int i; };
+int bar (void)
+{
+ return ((struct foo *)0x1234)->i;
+}
+
+struct boo { int i; };
+int bar2 (void)
+{
+ return reinterpret_cast<struct boo *>(0xC0FFEE)->i;
+}
+
+struct cue { int i; };
+int bar3 (void)
+{
+ return static_cast<struct cue *>(voidp)->i;
+}
+
+class printer { public: int i; };
+const printer *dotmatrix;
+int bar4 (void)
+{
+ return const_cast<printer *>(dotmatrix)->i;
+}
+
+class class1 { virtual ~class1(); } *c1;
+class class2 : class1 { char j; };
+int bar5 (void)
+{
+ if (dynamic_cast <class2 *>(c1))
+ return 5;
+ else
+ return 6;
+}
+/* { dg-final { scan-assembler "foo" } } */
+/* { dg-final { scan-assembler "boo" } } */
+/* { dg-final { scan-assembler "cue" } } */
+/* { dg-final { scan-assembler "string\t\"class2\"" } } */
+/* { dg-final { scan-assembler "string\t\"printer\"" } } */