diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2014-08-01 21:11:34 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2014-08-01 21:11:34 +0000 |
commit | 908d809b81dc0394b37ee4f2a407701f1e8d0945 (patch) | |
tree | 83e490b909942b73d83fbfd6e726383de57a4d2e /llvm/lib/Bitcode/Reader/BitcodeReader.h | |
parent | 2e7e989d715e514c9083a9d70416d8af99f7abec (diff) | |
download | bcm5719-llvm-908d809b81dc0394b37ee4f2a407701f1e8d0945.tar.gz bcm5719-llvm-908d809b81dc0394b37ee4f2a407701f1e8d0945.zip |
BitcodeReader: Fix some BlockAddress forward reference corner cases
`BlockAddress`es are interesting in that they can reference basic blocks
from *outside* the block's function. Since basic blocks are not global
values, this presents particular challenges for lazy parsing.
One corner case was found in PR11677 and fixed in r147425. In that
case, a global variable references a block address. It's necessary to
load the relevant function to resolve the forward reference before doing
anything with the module.
By inspection, I found (and have fixed here) two other cases:
- An instruction from one function references a block address from
another function, and only the first function is lazily loaded.
I fixed this the same way as PR11677: by eagerly loading the
referenced function.
- A function whose block address is taken is dematerialized, leaving
invalid references to it.
I fixed this by refusing to dematerialize functions whose block
addresses are taken (if you have to load it, you can't unload it).
llvm-svn: 214559
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.h')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.h | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.h b/llvm/lib/Bitcode/Reader/BitcodeReader.h index 40f8d134f6a..341e134302d 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.h +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.h @@ -193,20 +193,29 @@ class BitcodeReader : public GVMaterializer { /// not need this flag. bool UseRelativeIDs; + /// True if all functions will be materialized, negating the need to process + /// (e.g.) blockaddress forward references. + bool WillMaterializeAllForwardRefs; + + /// Functions that have block addresses taken. This is usually empty. + SmallPtrSet<const Function *, 4> BlockAddressesTaken; + public: std::error_code Error(BitcodeError E) { return make_error_code(E); } explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C) : Context(C), TheModule(nullptr), Buffer(buffer), LazyStreamer(nullptr), NextUnreadBit(0), SeenValueSymbolTable(false), ValueList(C), - MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false) {} + MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false), + WillMaterializeAllForwardRefs(false) {} explicit BitcodeReader(DataStreamer *streamer, LLVMContext &C) : Context(C), TheModule(nullptr), Buffer(nullptr), LazyStreamer(streamer), NextUnreadBit(0), SeenValueSymbolTable(false), ValueList(C), - MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false) {} + MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false), + WillMaterializeAllForwardRefs(false) {} ~BitcodeReader() { FreeState(); } - void materializeForwardReferencedFunctions(); + std::error_code materializeForwardReferencedFunctions(); void FreeState(); |