From 5f8d4adf262a569ffe265df9fe29020259e29bdd Mon Sep 17 00:00:00 2001 From: hubicka Date: Wed, 25 May 2011 12:07:38 +0000 Subject: [PATCH] * lto-streamer-out.c (output_record_start): Use lto_output_enum (lto_output_tree): Use output_record_start. * lto-streamer-in.c (input_record_start): Use lto_input_enum (lto_get_pickled_tree): Use input_record_start. * lto-section-in.c (lto_section_overrun): Turn into fatal error. (lto_value_range_error): New function. * lto-streamer.h (lto_value_range_error): Declare. (lto_output_int_in_range, lto_input_int_in_range): New functions. (lto_output_enum, lto_input_enum): New macros. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@174186 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 12 ++++++++++ gcc/lto-section-in.c | 14 +++++++++-- gcc/lto-streamer-in.c | 7 +++--- gcc/lto-streamer-out.c | 9 ++++--- gcc/lto-streamer.h | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 96 insertions(+), 11 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b57b242..1143fae 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2011-05-25 Jan Hubicka + + * lto-streamer-out.c (output_record_start): Use lto_output_enum + (lto_output_tree): Use output_record_start. + * lto-streamer-in.c (input_record_start): Use lto_input_enum + (lto_get_pickled_tree): Use input_record_start. + * lto-section-in.c (lto_section_overrun): Turn into fatal error. + (lto_value_range_error): New function. + * lto-streamer.h (lto_value_range_error): Declare. + (lto_output_int_in_range, lto_input_int_in_range): New functions. + (lto_output_enum, lto_input_enum): New macros. + 2011-05-25 Eric Botcazou * common.opt (flag_stack_usage_info): New variable. diff --git a/gcc/lto-section-in.c b/gcc/lto-section-in.c index 4b88fb1..b6277a3 100644 --- a/gcc/lto-section-in.c +++ b/gcc/lto-section-in.c @@ -483,6 +483,16 @@ lto_get_function_in_decl_state (struct lto_file_decl_data *file_data, void lto_section_overrun (struct lto_input_block *ib) { - internal_error ("bytecode stream: trying to read %d bytes " - "after the end of the input buffer", ib->p - ib->len); + fatal_error ("bytecode stream: trying to read %d bytes " + "after the end of the input buffer", ib->p - ib->len); +} + +/* Report out of range value. */ + +void +lto_value_range_error (const char *purpose, HOST_WIDE_INT val, + HOST_WIDE_INT min, HOST_WIDE_INT max) +{ + fatal_error ("%s out of range: Range is %i to %i, value is %i", + purpose, (int)min, (int)max, (int)val); } diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index d3a9dd2..dd14c0c 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -231,11 +231,10 @@ lto_input_string (struct data_in *data_in, struct lto_input_block *ib) /* Return the next tag in the input block IB. */ -static enum LTO_tags +static inline enum LTO_tags input_record_start (struct lto_input_block *ib) { - enum LTO_tags tag = (enum LTO_tags) lto_input_uleb128 (ib); - return tag; + return lto_input_enum (ib, LTO_tags, LTO_NUM_TAGS); } @@ -2558,7 +2557,7 @@ lto_get_pickled_tree (struct lto_input_block *ib, struct data_in *data_in) enum LTO_tags expected_tag; ix = lto_input_uleb128 (ib); - expected_tag = (enum LTO_tags) lto_input_uleb128 (ib); + expected_tag = lto_input_enum (ib, LTO_tags, LTO_NUM_TAGS); result = lto_streamer_cache_get (data_in->reader_cache, ix); gcc_assert (result diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index da1983c..0cfe25a 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -270,12 +270,10 @@ output_sleb128 (struct output_block *ob, HOST_WIDE_INT work) /* Output the start of a record with TAG to output block OB. */ -static void +static inline void output_record_start (struct output_block *ob, enum LTO_tags tag) { - /* Make sure TAG fits inside an unsigned int. */ - gcc_assert (tag == (enum LTO_tags) (unsigned) tag); - output_uleb128 (ob, tag); + lto_output_enum (ob->main_stream, LTO_tags, LTO_NUM_TAGS, tag); } @@ -1401,7 +1399,8 @@ lto_output_tree (struct output_block *ob, tree expr, bool ref_p) will instantiate two different nodes for the same object. */ output_record_start (ob, LTO_tree_pickle_reference); output_uleb128 (ob, ix); - output_uleb128 (ob, lto_tree_code_to_tag (TREE_CODE (expr))); + lto_output_enum (ob->main_stream, LTO_tags, LTO_NUM_TAGS, + lto_tree_code_to_tag (TREE_CODE (expr))); } else if (lto_stream_as_builtin_p (expr)) { diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index 3d87e18..3389b56 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -771,6 +771,9 @@ extern int lto_eq_in_decl_state (const void *, const void *); extern struct lto_in_decl_state *lto_get_function_in_decl_state ( struct lto_file_decl_data *, tree); extern void lto_section_overrun (struct lto_input_block *) ATTRIBUTE_NORETURN; +extern void lto_value_range_error (const char *, + HOST_WIDE_INT, HOST_WIDE_INT, + HOST_WIDE_INT) ATTRIBUTE_NORETURN; /* In lto-section-out.c */ extern hashval_t lto_hash_decl_slot_node (const void *); @@ -1199,4 +1202,66 @@ lto_input_1_unsigned (struct lto_input_block *ib) return (ib->data[ib->p++]); } +/* Output VAL into OBS and verify it is in range MIN...MAX that is supposed + to be compile time constant. + Be host independent, limit range to 31bits. */ + +static inline void +lto_output_int_in_range (struct lto_output_stream *obs, + HOST_WIDE_INT min, + HOST_WIDE_INT max, + HOST_WIDE_INT val) +{ + HOST_WIDE_INT range = max - min; + + gcc_checking_assert (val >= min && val <= max && range > 0 + && range < 0x7fffffff); + + val -= min; + lto_output_1_stream (obs, val & 255); + if (range >= 0xff) + lto_output_1_stream (obs, (val << 8) & 255); + if (range >= 0xffff) + lto_output_1_stream (obs, (val << 16) & 255); + if (range >= 0xffffff) + lto_output_1_stream (obs, (val << 24) & 255); +} + +/* Input VAL into OBS and verify it is in range MIN...MAX that is supposed + to be compile time constant. PURPOSE is used for error reporting. */ + +static inline HOST_WIDE_INT +lto_input_int_in_range (struct lto_input_block *ib, + const char *purpose, + HOST_WIDE_INT min, + HOST_WIDE_INT max) +{ + HOST_WIDE_INT range = max - min; + HOST_WIDE_INT val = lto_input_1_unsigned (ib); + + gcc_checking_assert (range > 0 && range < 0x7fffffff); + + if (range >= 0xff) + val |= ((HOST_WIDE_INT)lto_input_1_unsigned (ib)) << 8; + if (range >= 0xffff) + val |= ((HOST_WIDE_INT)lto_input_1_unsigned (ib)) << 16; + if (range >= 0xffffff) + val |= ((HOST_WIDE_INT)lto_input_1_unsigned (ib)) << 24; + val += min; + if (val < min || val > max) + lto_value_range_error (purpose, val, min, max); + return val; +} + +/* Output VAL of type "enum enum_name" into OBS. + Assume range 0...ENUM_LAST - 1. */ +#define lto_output_enum(obs,enum_name,enum_last,val) \ + lto_output_int_in_range ((obs), 0, (int)(enum_last) - 1, (int)(val)) + +/* Input enum of type "enum enum_name" from IB. + Assume range 0...ENUM_LAST - 1. */ +#define lto_input_enum(ib,enum_name,enum_last) \ + (enum enum_name)lto_input_int_in_range ((ib), #enum_name, 0, \ + (int)(enum_last) - 1) + #endif /* GCC_LTO_STREAMER_H */ -- 2.7.4