lto-streamer-out.c (output_record_start): Use lto_output_enum
authorJan Hubicka <jh@suse.cz>
Wed, 25 May 2011 12:07:38 +0000 (14:07 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Wed, 25 May 2011 12:07:38 +0000 (12:07 +0000)
* 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.

From-SVN: r174186

gcc/ChangeLog
gcc/lto-section-in.c
gcc/lto-streamer-in.c
gcc/lto-streamer-out.c
gcc/lto-streamer.h

index b57b242724e6d4990e0f13b635a6e9f4f1738f54..1143fae8a9dd2ef38260d2b9397a035fdea24f88 100644 (file)
@@ -1,3 +1,15 @@
+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.
index 4b88fb10749104e119569d316fde4ee7a4f6d858..b6277a35532d9d0d6b450869f17719e0aa135ca8 100644 (file)
@@ -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);
 }
index d3a9dd2235b915caf5d8b690d51c8066c4cc4f9b..dd14c0cedf94874d33e710660e777bb918c8c006 100644 (file)
@@ -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
index da1983c8ca7535f9015ae6faf2c8545bd032976c..0cfe25a5d266bdf063b9bad393bf9f0017af4ba8 100644 (file)
@@ -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))
     {
index 3d87e18a825a84d4cd35f13d848a34fc3bc2e2ed..3389b5643741bbd7fc9427223f7da8d1f7c2cfe7 100644 (file)
@@ -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  */