+2011-05-25 Jan Hubicka <jh@suse.cz>
+
+ * 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 <ebotcazou@adacore.com>
* common.opt (flag_stack_usage_info): New variable.
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);
}
/* 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);
}
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
/* 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);
}
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))
{
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 *);
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 */