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> 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 * parse.y (java_complete_lhs case EXPR_WITH_FILE_LOCATION): If body is
constant, return body without wrapper. (Improves constant folding.) constant, return body without wrapper. (Improves constant folding.)
* lex.c (build_wfl_node): Clear TREE_TYPE from returned node. * lex.c (build_wfl_node): Clear TREE_TYPE from returned node.
......
...@@ -256,19 +256,31 @@ flush_quick_stack () ...@@ -256,19 +256,31 @@ flush_quick_stack ()
} }
} }
void /* Push TYPE on the type stack.
push_type (type) Return true on success, 0 on overflow. */
int
push_type_0 (type)
tree type; tree type;
{ {
int n_words; int n_words;
type = promote_type (type); type = promote_type (type);
n_words = 1 + TYPE_IS_WIDE (type); n_words = 1 + TYPE_IS_WIDE (type);
if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl)) if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
fatal ("stack overflow"); return 0;
stack_type_map[stack_pointer++] = type; stack_type_map[stack_pointer++] = type;
n_words--; n_words--;
while (--n_words >= 0) while (--n_words >= 0)
stack_type_map[stack_pointer++] = TYPE_SECOND; 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 static void
...@@ -296,23 +308,32 @@ push_value (value) ...@@ -296,23 +308,32 @@ push_value (value)
/* Pop a type from the type stack. /* Pop a type from the type stack.
TYPE is the expected type. Return the actual type, which must be 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 tree
pop_type_0 (type) pop_type_0 (type, messagep)
tree type; tree type;
char **messagep;
{ {
int n_words; int n_words;
tree t; tree t;
*messagep = NULL;
if (TREE_CODE (type) == RECORD_TYPE) if (TREE_CODE (type) == RECORD_TYPE)
type = promote_type (type); type = promote_type (type);
n_words = 1 + TYPE_IS_WIDE (type); n_words = 1 + TYPE_IS_WIDE (type);
if (stack_pointer < n_words) if (stack_pointer < n_words)
fatal ("stack underflow"); {
*messagep = xstrdup ("stack underflow");
return type;
}
while (--n_words > 0) while (--n_words > 0)
{ {
if (stack_type_map[--stack_pointer] != void_type_node) 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]; t = stack_type_map[--stack_pointer];
if (type == NULL_TREE || t == type) if (type == NULL_TREE || t == type)
...@@ -334,7 +355,24 @@ pop_type_0 (type) ...@@ -334,7 +355,24 @@ pop_type_0 (type)
/* FIXME: this is worse than a kludge, probably. */ /* FIXME: this is worse than a kludge, probably. */
return object_ptr_type_node; 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. /* Pop a type from the type stack.
...@@ -345,10 +383,13 @@ tree ...@@ -345,10 +383,13 @@ tree
pop_type (type) pop_type (type)
tree type; tree type;
{ {
tree t = pop_type_0 (type); char *message = NULL;
if (t != NULL_TREE) type = pop_type_0 (type, &message);
return t; if (message != NULL)
error ("unexpected type on stack"); {
error (message);
free (message);
}
return type; return type;
} }
...@@ -1576,23 +1617,6 @@ expand_java_ret (return_address) ...@@ -1576,23 +1617,6 @@ expand_java_ret (return_address)
} }
#endif #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 static tree
pop_arguments (arg_types) pop_arguments (arg_types)
tree arg_types; tree arg_types;
......
...@@ -978,9 +978,8 @@ extern tree build_java_array_type PARAMS ((tree, HOST_WIDE_INT)); ...@@ -978,9 +978,8 @@ extern tree build_java_array_type PARAMS ((tree, HOST_WIDE_INT));
extern int is_compiled_class PARAMS ((tree)); extern int is_compiled_class PARAMS ((tree));
extern tree mangled_classname PARAMS ((const char*, tree)); extern tree mangled_classname PARAMS ((const char*, tree));
extern tree lookup_label PARAMS ((int)); 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 tree pop_type PARAMS ((tree));
extern void pop_argument_types PARAMS ((tree));
extern tree decode_newarray_type PARAMS ((int)); extern tree decode_newarray_type PARAMS ((int));
extern tree lookup_field PARAMS ((tree*, tree)); extern tree lookup_field PARAMS ((tree*, tree));
extern int is_array_type_p PARAMS ((tree)); extern int is_array_type_p PARAMS ((tree));
...@@ -1057,6 +1056,7 @@ extern int process_jvm_instruction PARAMS ((int, const unsigned char *, long)); ...@@ -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 int maybe_adjust_start_pc PARAMS ((struct JCF *, int, int, int));
extern void set_local_type PARAMS ((int, tree)); extern void set_local_type PARAMS ((int, tree));
extern int merge_type_state PARAMS ((tree)); extern int merge_type_state PARAMS ((tree));
extern int push_type_0 PARAMS ((tree));
extern void push_type PARAMS ((tree)); extern void push_type PARAMS ((tree));
extern void load_type_state PARAMS ((tree)); extern void load_type_state PARAMS ((tree));
extern void add_interface PARAMS ((tree, tree)); extern void add_interface PARAMS ((tree, tree));
...@@ -1244,6 +1244,12 @@ extern int linenumber_count; ...@@ -1244,6 +1244,12 @@ extern int linenumber_count;
used nor set in the subroutine. */ used nor set in the subroutine. */
#define TYPE_UNUSED error_mark_node #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 /* A array mapping variable/stack slot index to the type current
in that variable/stack slot. in that variable/stack slot.
TYPE_UNKNOWN, TYPE_SECOND, and TYPE_NULL are special cases. */ 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