Skip to content

Commit 2087d5e

Browse files
incr.comp.: Do some verification on data decoded from incr. comp. cache.
1 parent de0317e commit 2087d5e

File tree

1 file changed

+62
-6
lines changed

1 file changed

+62
-6
lines changed

src/librustc/ty/maps/on_disk_cache.rs

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ use ty::codec::{self as ty_codec, TyDecoder};
3434
use ty::context::TyCtxt;
3535
use ty::subst::Substs;
3636

37+
// Some magic values used for verifying that encoding and decoding. These are
38+
// basically random numbers.
39+
const PREV_DIAGNOSTICS_TAG: u64 = 0x1234_5678_A1A1_A1A1;
40+
const DEF_PATH_TABLE_TAG: u64 = 0x1234_5678_B2B2_B2B2;
41+
3742
/// `OnDiskCache` provides an interface to incr. comp. data cached from the
3843
/// previous compilation session. This data will eventually include the results
3944
/// of a few selected queries (like `typeck_tables_of` and `mir_optimized`) and
@@ -91,15 +96,17 @@ impl<'sess> OnDiskCache<'sess> {
9196

9297
// Decode Diagnostics
9398
let prev_diagnostics: FxHashMap<_, _> = {
94-
let diagnostics = EncodedPrevDiagnostics::decode(&mut decoder)
95-
.expect("Error while trying to decode prev. diagnostics \
96-
from incr. comp. cache.");
99+
let diagnostics: EncodedPrevDiagnostics =
100+
decode_tagged(&mut decoder, PREV_DIAGNOSTICS_TAG)
101+
.expect("Error while trying to decode previous session \
102+
diagnostics from incr. comp. cache.");
103+
97104
diagnostics.into_iter().collect()
98105
};
99106

100107
// Decode DefPathTables
101108
let prev_def_path_tables: Vec<DefPathTable> =
102-
Decodable::decode(&mut decoder)
109+
decode_tagged(&mut decoder, DEF_PATH_TABLE_TAG)
103110
.expect("Error while trying to decode cached DefPathTables");
104111

105112
(prev_diagnostics, prev_def_path_tables)
@@ -176,7 +183,7 @@ impl<'sess> OnDiskCache<'sess> {
176183
.map(|(k, v)| (SerializedDepNodeIndex::new(k.index()), v.clone()))
177184
.collect();
178185

179-
diagnostics.encode(&mut encoder)?;
186+
encoder.encode_tagged(PREV_DIAGNOSTICS_TAG, &diagnostics)?;
180187

181188

182189
// Encode all DefPathTables
@@ -192,7 +199,7 @@ impl<'sess> OnDiskCache<'sess> {
192199
}
193200
}).collect();
194201

195-
def_path_tables.encode(&mut encoder)?;
202+
encoder.encode_tagged(DEF_PATH_TABLE_TAG, &def_path_tables)?;
196203

197204
return Ok(());
198205

@@ -342,6 +349,30 @@ impl<'a, 'tcx, 'x> Decoder for CacheDecoder<'a, 'tcx, 'x> {
342349
}
343350
}
344351

352+
// Decode something that was encoded with encode_tagged() and verify that the
353+
// tag matches and the correct amount of bytes was read.
354+
fn decode_tagged<'a, 'tcx, D, T, V>(decoder: &mut D,
355+
expected_tag: T)
356+
-> Result<V, D::Error>
357+
where T: Decodable + Eq + ::std::fmt::Debug,
358+
V: Decodable,
359+
D: Decoder + ty_codec::TyDecoder<'a, 'tcx>,
360+
'tcx: 'a,
361+
{
362+
let start_pos = decoder.position();
363+
364+
let actual_tag = T::decode(decoder)?;
365+
assert_eq!(actual_tag, expected_tag);
366+
let value = V::decode(decoder)?;
367+
let end_pos = decoder.position();
368+
369+
let expected_len: u64 = Decodable::decode(decoder)?;
370+
assert_eq!((end_pos - start_pos) as u64, expected_len);
371+
372+
Ok(value)
373+
}
374+
375+
345376
impl<'a, 'tcx: 'a, 'x> ty_codec::TyDecoder<'a, 'tcx> for CacheDecoder<'a, 'tcx, 'x> {
346377

347378
#[inline]
@@ -565,6 +596,30 @@ struct CacheEncoder<'enc, 'tcx, E>
565596
definitions: &'enc Definitions,
566597
}
567598

599+
impl<'enc, 'tcx, E> CacheEncoder<'enc, 'tcx, E>
600+
where E: 'enc + ty_codec::TyEncoder
601+
{
602+
/// Encode something with additional information that allows to do some
603+
/// sanity checks when decoding the data again. This method will first
604+
/// encode the specified tag, then the given value, then the number of
605+
/// bytes taken up by tag and value. On decoding, we can then verify that
606+
/// we get the expected tag and read the expected number of bytes.
607+
fn encode_tagged<T: Encodable, V: Encodable>(&mut self,
608+
tag: T,
609+
value: &V)
610+
-> Result<(), E::Error>
611+
{
612+
use ty::codec::TyEncoder;
613+
let start_pos = self.position();
614+
615+
tag.encode(self)?;
616+
value.encode(self)?;
617+
618+
let end_pos = self.position();
619+
((end_pos - start_pos) as u64).encode(self)
620+
}
621+
}
622+
568623
impl<'enc, 'tcx, E> ty_codec::TyEncoder for CacheEncoder<'enc, 'tcx, E>
569624
where E: 'enc + ty_codec::TyEncoder
570625
{
@@ -644,3 +699,4 @@ impl<'enc, 'tcx, E> Encoder for CacheEncoder<'enc, 'tcx, E>
644699
emit_str(&str);
645700
}
646701
}
702+

0 commit comments

Comments
 (0)