Commit 984ad2c6 by Per Bothner Committed by Per Bothner

Various patches to emit better messages on verification errors.

From-SVN: r39019
parent 150d3c00
2001-01-14 Per Bothner <per@bothner.com>
Various patches to emit better messages on verification errors.
* expr.c (push_type_0): Return error indication on stack overflow,
instead of callinfg fatal.
(push_type): Now just call push_type_0 (nd fatal on overflow).
(pop_type_0): Return detailed error message (in a char** argument).
(pop_type): If pop_type_0 fails, print error message.
(pop_argument_types): Moved to verify.c.
* verify.c (pop_argument_types): Moved from expr.c.
Return a (possible) error message, rather than void.
(POP_TYPE, POP_TYPE_CONV, PUSH_TYPE, PUSH_PENDING): New macros.
(verify_jvm_instruction): Use new macros, improving error messages.
For case OPCODE_astore use object_ptr_type_node.
* java-tree.h (TYPE_UNDERFLOW, TYPE_UNEXPECTED): New macros.
(pop_type_0, push_type_0, pop_argument_types): Update accordingly.
* parse.y (java_complete_lhs case EXPR_WITH_FILE_LOCATION): If body is
constant, return body without wrapper. (Improves constant folding.)
* lex.c (build_wfl_node): Clear TREE_TYPE from returned node.
......
......@@ -256,19 +256,31 @@ flush_quick_stack ()
}
}
void
push_type (type)
/* Push TYPE on the type stack.
Return true on success, 0 on overflow. */
int
push_type_0 (type)
tree type;
{
int n_words;
type = promote_type (type);
n_words = 1 + TYPE_IS_WIDE (type);
if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
fatal ("stack overflow");
return 0;
stack_type_map[stack_pointer++] = type;
n_words--;
while (--n_words >= 0)
stack_type_map[stack_pointer++] = TYPE_SECOND;
return 1;
}
void
push_type (type)
tree type;
{
if (! push_type_0 (type))
fatal ("stack overflow");
}
static void
......@@ -296,23 +308,32 @@ push_value (value)
/* Pop a type from the type stack.
TYPE is the expected type. Return the actual type, which must be
convertible to TYPE, otherwise NULL_TREE is returned. */
convertible to TYPE.
On an error, *MESSAGEP is set to a freshly malloc'd error message. */
tree
pop_type_0 (type)
pop_type_0 (type, messagep)
tree type;
char **messagep;
{
int n_words;
tree t;
*messagep = NULL;
if (TREE_CODE (type) == RECORD_TYPE)
type = promote_type (type);
n_words = 1 + TYPE_IS_WIDE (type);
if (stack_pointer < n_words)
fatal ("stack underflow");
{
*messagep = xstrdup ("stack underflow");
return type;
}
while (--n_words > 0)
{
if (stack_type_map[--stack_pointer] != void_type_node)
fatal ("Invalid multi-word value on type stack");
{
*messagep = xstrdup ("Invalid multi-word value on type stack");
return type;
}
}
t = stack_type_map[--stack_pointer];
if (type == NULL_TREE || t == type)
......@@ -334,7 +355,24 @@ pop_type_0 (type)
/* FIXME: this is worse than a kludge, probably. */
return object_ptr_type_node;
}
return NULL_TREE;
{
const char *str1 = "expected type '";
const char *str3 = "' but stack contains '";
const char *str5 = "'";
int len1 = strlen (str1);
int len2 = strlen (lang_printable_name (type, 0));
int len3 = strlen (str3);
int len4 = strlen (lang_printable_name (t, 0));
int len5 = strlen (str5);
char *msg = xmalloc (len1 + len2 + len3 + len4 + len5 + 1);
*messagep = msg;
strcpy (msg, str1); msg += len1;
strcpy (msg, lang_printable_name (type, 0)); msg += len2;
strcpy (msg, str3); msg += len3;
strcpy (msg, lang_printable_name (t, 0)); msg += len4;
strcpy (msg, str5);
return type;
}
}
/* Pop a type from the type stack.
......@@ -345,10 +383,13 @@ tree
pop_type (type)
tree type;
{
tree t = pop_type_0 (type);
if (t != NULL_TREE)
return t;
error ("unexpected type on stack");
char *message = NULL;
type = pop_type_0 (type, &message);
if (message != NULL)
{
error (message);
free (message);
}
return type;
}
......@@ -1576,23 +1617,6 @@ expand_java_ret (return_address)
}
#endif
/* Recursive helper function to pop argument types during verifiation. */
void
pop_argument_types (arg_types)
tree arg_types;
{
if (arg_types == end_params_node)
return;
if (TREE_CODE (arg_types) == TREE_LIST)
{
pop_argument_types (TREE_CHAIN (arg_types));
pop_type (TREE_VALUE (arg_types));
return;
}
abort ();
}
static tree
pop_arguments (arg_types)
tree arg_types;
......
......@@ -978,9 +978,8 @@ extern tree build_java_array_type PARAMS ((tree, HOST_WIDE_INT));
extern int is_compiled_class PARAMS ((tree));
extern tree mangled_classname PARAMS ((const char*, tree));
extern tree lookup_label PARAMS ((int));
extern tree pop_type_0 PARAMS ((tree));
extern tree pop_type_0 PARAMS ((tree, char**));
extern tree pop_type PARAMS ((tree));
extern void pop_argument_types PARAMS ((tree));
extern tree decode_newarray_type PARAMS ((int));
extern tree lookup_field PARAMS ((tree*, tree));
extern int is_array_type_p PARAMS ((tree));
......@@ -1057,6 +1056,7 @@ extern int process_jvm_instruction PARAMS ((int, const unsigned char *, long));
extern int maybe_adjust_start_pc PARAMS ((struct JCF *, int, int, int));
extern void set_local_type PARAMS ((int, tree));
extern int merge_type_state PARAMS ((tree));
extern int push_type_0 PARAMS ((tree));
extern void push_type PARAMS ((tree));
extern void load_type_state PARAMS ((tree));
extern void add_interface PARAMS ((tree, tree));
......@@ -1244,6 +1244,12 @@ extern int linenumber_count;
used nor set in the subroutine. */
#define TYPE_UNUSED error_mark_node
/* When returned from pop_type_0, indicates stack underflow. */
#define TYPE_UNDERFLOW integer_zero_node
/* When returned from pop_type_0, indicates a type mismatch. */
#define TYPE_UNEXPECTED NULL_TREE
/* A array mapping variable/stack slot index to the type current
in that variable/stack slot.
TYPE_UNKNOWN, TYPE_SECOND, and TYPE_NULL are special cases. */
......
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