Commit ea1763b1 by Nathan Sidwell Committed by Nathan Sidwell

re PR c++/18143 (Duplicated thunk with a huge member in the hierarchy)

.:	* tree.c (tree_check_failed): Emit general error if the list of
	node types is empty.
cp:
	PR c++/18143
	* cp-tree.h (NON_THUNK_FUNCTION_CHECK, THUNK_FUNCTION_CHECK): New.
	(struct lang_decl_flags): Add thunk_p flag.
	(struct lang_decl): Remove separate fixed_offset. Place
	cloned_function and fixed_offset into union.
	(DECL_CLONED_FUNCTION_P, DECL_CLONED_FUNCTION): Adjust.
	(DECL_THUNK_P, SET_DECL_THUNK_P): Adjust.
	(THUNK_FIXED_OFFSET): Adjust.
	* method.c (make_thunk): Adjust.

From-SVN: r90399
parent 22d8d627
2004-11-10 Nathan Sidwell <nathan@codesourcery.com>
* tree.c (tree_check_failed): Emit general error if the list of
node types is empty.
2004-11-10 Eric Botcazou <ebotcazou@libertysurf.fr> 2004-11-10 Eric Botcazou <ebotcazou@libertysurf.fr>
* config/sparc/sparc.c (function_arg_union_value): New 'slotno' * config/sparc/sparc.c (function_arg_union_value): New 'slotno'
......
2004-11-10 Nathan Sidwell <nathan@codesourcery.com>
PR c++/18143
* cp-tree.h (NON_THUNK_FUNCTION_CHECK, THUNK_FUNCTION_CHECK): New.
(struct lang_decl_flags): Add thunk_p flag.
(struct lang_decl): Remove separate fixed_offset. Place
cloned_function and fixed_offset into union.
(DECL_CLONED_FUNCTION_P, DECL_CLONED_FUNCTION): Adjust.
(DECL_THUNK_P, SET_DECL_THUNK_P): Adjust.
(THUNK_FIXED_OFFSET): Adjust.
* method.c (make_thunk): Adjust.
2004-11-09 Mark Mitchell <mark@codesourcery.com> 2004-11-09 Mark Mitchell <mark@codesourcery.com>
PR c++/18369 PR c++/18369
......
...@@ -163,6 +163,24 @@ struct diagnostic_context; ...@@ -163,6 +163,24 @@ struct diagnostic_context;
#define BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK(NODE) \ #define BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK(NODE) \
TREE_CHECK(NODE,BOUND_TEMPLATE_TEMPLATE_PARM) TREE_CHECK(NODE,BOUND_TEMPLATE_TEMPLATE_PARM)
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
#define NON_THUNK_FUNCTION_CHECK(NODE) __extension__ \
({ const tree __t = (NODE); \
if (TREE_CODE (__t) != FUNCTION_DECL && \
TREE_CODE (__t) != TEMPLATE_DECL && __t->decl.lang_specific \
&& __t->decl.lang_specific->decl_flags.thunk_p) \
tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, 0); \
__t; })
#define THUNK_FUNCTION_CHECK(NODE) __extension__ \
({ const tree __t = (NODE); \
if (TREE_CODE (__t) != FUNCTION_DECL || !__t->decl.lang_specific \
|| !__t->decl.lang_specific->decl_flags.thunk_p) \
tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, 0); \
__t; })
#else
#define NON_THUNK_FUNCTION_CHECK(NODE) (NODE)
#define THUNK_FUNCTION_CHECK(NODE) (NODE)
#endif
/* Language-dependent contents of an identifier. */ /* Language-dependent contents of an identifier. */
...@@ -1496,9 +1514,10 @@ struct lang_decl_flags GTY(()) ...@@ -1496,9 +1514,10 @@ struct lang_decl_flags GTY(())
unsigned u2sel : 1; unsigned u2sel : 1;
unsigned can_be_full : 1; unsigned can_be_full : 1;
unsigned thunk_p : 1;
unsigned this_thunk_p : 1; unsigned this_thunk_p : 1;
unsigned repo_available_p : 1; unsigned repo_available_p : 1;
unsigned dummy : 4; unsigned dummy : 3;
union lang_decl_u { union lang_decl_u {
/* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is /* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is
...@@ -1540,15 +1559,8 @@ struct lang_decl GTY(()) ...@@ -1540,15 +1559,8 @@ struct lang_decl GTY(())
unsigned u3sel : 1; unsigned u3sel : 1;
unsigned pending_inline_p : 1; unsigned pending_inline_p : 1;
unsigned spare : 3; unsigned spare : 22;
/* In a FUNCTION_DECL for which THUNK_P holds this is the
THUNK_FIXED_OFFSET. The largest object that can be
thunked is thus 262144, which is what is required [limits].
We have to store a signed value as for regular thunks this
is <= 0, and for covariant thunks it is >= 0. */
signed fixed_offset : 19;
/* For a non-thunk function decl, this is a tree list of /* For a non-thunk function decl, this is a tree list of
friendly classes. For a thunk function decl, it is the friendly classes. For a thunk function decl, it is the
thunked to function decl. */ thunked to function decl. */
...@@ -1562,9 +1574,17 @@ struct lang_decl GTY(()) ...@@ -1562,9 +1574,17 @@ struct lang_decl GTY(())
will be chained on the return pointer thunk. */ will be chained on the return pointer thunk. */
tree context; tree context;
/* In a FUNCTION_DECL, this is DECL_CLONED_FUNCTION. */ union lang_decl_u5
tree cloned_function; {
/* In a non-thunk FUNCTION_DECL or TEMPLATE_DECL, this is
DECL_CLONED_FUNCTION. */
tree GTY ((tag ("0"))) cloned_function;
/* In a FUNCTION_DECL for which THUNK_P holds this is the
THUNK_FIXED_OFFSET. */
HOST_WIDE_INT GTY ((tag ("1"))) fixed_offset;
} GTY ((desc ("%0.decl_flags.thunk_p"))) u5;
union lang_decl_u3 union lang_decl_u3
{ {
struct sorted_fields_type * GTY ((tag ("0"), reorder ("resort_sorted_fields"))) struct sorted_fields_type * GTY ((tag ("0"), reorder ("resort_sorted_fields")))
...@@ -1667,16 +1687,17 @@ struct lang_decl GTY(()) ...@@ -1667,16 +1687,17 @@ struct lang_decl GTY(())
/* Nonzero if NODE (a FUNCTION_DECL) is a cloned constructor or /* Nonzero if NODE (a FUNCTION_DECL) is a cloned constructor or
destructor. */ destructor. */
#define DECL_CLONED_FUNCTION_P(NODE) \ #define DECL_CLONED_FUNCTION_P(NODE) \
((TREE_CODE (NODE) == FUNCTION_DECL \ ((TREE_CODE (NODE) == FUNCTION_DECL \
|| TREE_CODE (NODE) == TEMPLATE_DECL) \ || TREE_CODE (NODE) == TEMPLATE_DECL) \
&& DECL_LANG_SPECIFIC (NODE) \ && DECL_LANG_SPECIFIC (NODE) \
&& !DECL_LANG_SPECIFIC (NODE)->decl_flags.thunk_p \
&& DECL_CLONED_FUNCTION (NODE) != NULL_TREE) && DECL_CLONED_FUNCTION (NODE) != NULL_TREE)
/* If DECL_CLONED_FUNCTION_P holds, this is the function that was /* If DECL_CLONED_FUNCTION_P holds, this is the function that was
cloned. */ cloned. */
#define DECL_CLONED_FUNCTION(NODE) \ #define DECL_CLONED_FUNCTION(NODE) \
(DECL_LANG_SPECIFIC (NODE)->u.f.cloned_function) (DECL_LANG_SPECIFIC (NON_THUNK_FUNCTION_CHECK(NODE))->u.f.u5.cloned_function)
/* Perform an action for each clone of FN, if FN is a function with /* Perform an action for each clone of FN, if FN is a function with
clones. This macro should be used like: clones. This macro should be used like:
...@@ -1868,7 +1889,14 @@ struct lang_decl GTY(()) ...@@ -1868,7 +1889,14 @@ struct lang_decl GTY(())
/* Nonzero if NODE is a thunk, rather than an ordinary function. */ /* Nonzero if NODE is a thunk, rather than an ordinary function. */
#define DECL_THUNK_P(NODE) \ #define DECL_THUNK_P(NODE) \
(TREE_CODE (NODE) == FUNCTION_DECL \ (TREE_CODE (NODE) == FUNCTION_DECL \
&& DECL_LANG_FLAG_7 (NODE)) && DECL_LANG_SPECIFIC (NODE) \
&& DECL_LANG_SPECIFIC (NODE)->decl_flags.thunk_p)
/* Set DECL_THUNK_P for node. */
#define SET_DECL_THUNK_P(NODE, THIS_ADJUSTING) \
(DECL_LANG_SPECIFIC (NODE)->decl_flags.thunk_p = 1, \
DECL_LANG_SPECIFIC (NODE)->u.f.u3sel = 1, \
DECL_LANG_SPECIFIC (NODE)->decl_flags.this_thunk_p = (THIS_ADJUSTING))
/* Nonzero if NODE is a this pointer adjusting thunk. */ /* Nonzero if NODE is a this pointer adjusting thunk. */
#define DECL_THIS_THUNK_P(NODE) \ #define DECL_THIS_THUNK_P(NODE) \
...@@ -1890,12 +1918,6 @@ struct lang_decl GTY(()) ...@@ -1890,12 +1918,6 @@ struct lang_decl GTY(())
#define DECL_EXTERN_C_FUNCTION_P(NODE) \ #define DECL_EXTERN_C_FUNCTION_P(NODE) \
(DECL_NON_THUNK_FUNCTION_P (NODE) && DECL_EXTERN_C_P (NODE)) (DECL_NON_THUNK_FUNCTION_P (NODE) && DECL_EXTERN_C_P (NODE))
/* Set DECL_THUNK_P for node. */
#define SET_DECL_THUNK_P(NODE, THIS_ADJUSTING) \
(DECL_LANG_FLAG_7 (NODE) = 1, \
DECL_LANG_SPECIFIC (NODE)->u.f.u3sel = 1, \
DECL_LANG_SPECIFIC (NODE)->decl_flags.this_thunk_p = (THIS_ADJUSTING))
/* True iff DECL is an entity with vague linkage whose definition is /* True iff DECL is an entity with vague linkage whose definition is
available in this translation unit. */ available in this translation unit. */
#define DECL_REPO_AVAILABLE_P(NODE) \ #define DECL_REPO_AVAILABLE_P(NODE) \
...@@ -2818,7 +2840,7 @@ struct lang_decl GTY(()) ...@@ -2818,7 +2840,7 @@ struct lang_decl GTY(())
/* An integer indicating how many bytes should be subtracted from the /* An integer indicating how many bytes should be subtracted from the
this or result pointer when this function is called. */ this or result pointer when this function is called. */
#define THUNK_FIXED_OFFSET(DECL) \ #define THUNK_FIXED_OFFSET(DECL) \
(DECL_LANG_SPECIFIC (VAR_OR_FUNCTION_DECL_CHECK (DECL))->u.f.fixed_offset) (DECL_LANG_SPECIFIC (THUNK_FUNCTION_CHECK (DECL))->u.f.u5.fixed_offset)
/* A tree indicating how to perform the virtual adjustment. For a this /* A tree indicating how to perform the virtual adjustment. For a this
adjusting thunk it is the number of bytes to be added to the vtable adjusting thunk it is the number of bytes to be added to the vtable
......
...@@ -150,8 +150,6 @@ make_thunk (tree function, bool this_adjusting, ...@@ -150,8 +150,6 @@ make_thunk (tree function, bool this_adjusting,
DECL_SAVED_FUNCTION_DATA (thunk) = NULL; DECL_SAVED_FUNCTION_DATA (thunk) = NULL;
DECL_DESTRUCTOR_P (thunk) = 0; DECL_DESTRUCTOR_P (thunk) = 0;
DECL_CONSTRUCTOR_P (thunk) = 0; DECL_CONSTRUCTOR_P (thunk) = 0;
/* And neither is it a clone. */
DECL_CLONED_FUNCTION (thunk) = NULL_TREE;
DECL_EXTERNAL (thunk) = 1; DECL_EXTERNAL (thunk) = 1;
DECL_ARTIFICIAL (thunk) = 1; DECL_ARTIFICIAL (thunk) = 1;
/* Even if this thunk is a member of a local class, we don't /* Even if this thunk is a member of a local class, we don't
......
...@@ -5402,8 +5402,9 @@ get_set_constructor_bytes (tree init, unsigned char *buffer, int wd_size) ...@@ -5402,8 +5402,9 @@ get_set_constructor_bytes (tree init, unsigned char *buffer, int wd_size)
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
/* Complain that the tree code of NODE does not match the expected 0 /* Complain that the tree code of NODE does not match the expected 0
terminated list of trailing codes. FILE, LINE, and FUNCTION are of terminated list of trailing codes. The trailing code list can be
the caller. */ empty, for a more vague error message. FILE, LINE, and FUNCTION
are of the caller. */
void void
tree_check_failed (const tree node, const char *file, tree_check_failed (const tree node, const char *file,
...@@ -5418,22 +5419,27 @@ tree_check_failed (const tree node, const char *file, ...@@ -5418,22 +5419,27 @@ tree_check_failed (const tree node, const char *file,
while ((code = va_arg (args, int))) while ((code = va_arg (args, int)))
length += 4 + strlen (tree_code_name[code]); length += 4 + strlen (tree_code_name[code]);
va_end (args); va_end (args);
va_start (args, function); if (length)
buffer = alloca (length);
length = 0;
while ((code = va_arg (args, int)))
{ {
if (length) va_start (args, function);
length += strlen ("expected ");
buffer = alloca (length);
length = 0;
while ((code = va_arg (args, int)))
{ {
strcpy (buffer + length, " or "); const char *prefix = length ? " or " : "expected ";
length += 4;
strcpy (buffer + length, prefix);
length += strlen (prefix);
strcpy (buffer + length, tree_code_name[code]);
length += strlen (tree_code_name[code]);
} }
strcpy (buffer + length, tree_code_name[code]); va_end (args);
length += strlen (tree_code_name[code]);
} }
va_end (args); else
buffer = (char *)"unexpected node";
internal_error ("tree check: expected %s, have %s in %s, at %s:%d", internal_error ("tree check: %s, have %s in %s, at %s:%d",
buffer, tree_code_name[TREE_CODE (node)], buffer, tree_code_name[TREE_CODE (node)],
function, trim_filename (file), line); function, trim_filename (file), line);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment