jfb added a comment. In D63518#1550827 <https://reviews.llvm.org/D63518#1550827>, @bruno wrote:
> Hi JF. Thanks for working on this, nice improvement to error handling! > > The overall approach is pretty solid and should prevent a lot of red herring > while investigating hard to reproduce crashes in clang, specially when > implicit clang modules is involved. Dropping the errors on the floor for > previous code that didn't handle errors at all is a fair tradeoff for > introducing the functionality. Thanks! > I have omitted any format comments but I noticed several of 80 cols > violations. More specific reviews inline. Yeah I've been avoiding `clang-format` because it's sometimes easier to manage merge conflicts without reformatting. I'll absolutely run format when the patch is further along. ================ Comment at: clang/lib/Frontend/SerializedDiagnosticReader.cpp:59 + } else + return SDError::InvalidDiagnostics; // FIXME propagate the error details. ---------------- bruno wrote: > Can this be simplified as below? > > ``` > Expected<unsigned> Res = Stream.ReadCode(); > if (!Res || Res.get() != llvm::bitc::ENTER_SUBBLOCK) > return SDError::InvalidDiagnostics; // FIXME propagate the error details. > ``` Yeah, but I think we'll want to propagate errors in a follow-up so we'll end up re-separating them. I'd rather have the right structure here. ================ Comment at: clang/lib/Serialization/ASTReader.cpp:1158 StringRef Blob; - unsigned Code = Cursor.ReadCode(); - unsigned RecCode = Cursor.readRecord(Code, Record, &Blob); + Expected<unsigned> MaybeCode = Cursor.ReadCode(); + if (!MaybeCode) { ---------------- bruno wrote: > Not necessarily needed as part of this patch, but I wonder how many of > repetitive access patterns (readCode + readRecord, and maybe other patterns) > we have that would take advantage of refactoring all these checks out into > their own methods. Yeah I noticed that too, probably worth adding a helper for. I'll note it in a bug: https://bugs.llvm.org/show_bug.cgi?id=42335 ================ Comment at: clang/lib/Serialization/ASTReader.cpp:4283 + return llvm::createStringError(std::errc::illegal_byte_sequence, "file too small to contain AST file magic"); + for (unsigned C : {'C','P','C','H'}) + if (Expected<llvm::SimpleBitstreamCursor::word_t> Res = Stream.Read(8)) { ---------------- bruno wrote: > Very similar to SerializedDiagnosticReader.cpp:44, does it deserve a common > helper? It would be nice, but they don't have the same error handling :( I'll add a FIXME. ================ Comment at: clang/lib/Serialization/ASTReader.cpp:4559 + // FIXME this drops the error. + return Failure; + } ---------------- bruno wrote: > This is a good example of a real issue this patch solves. Sometimes we get > signature mismatch problems in implicit modules builds because we read > garbage. Having this check and failure here prevents the misleading error > message. 🎉 ================ Comment at: clang/lib/Serialization/ASTReaderDecl.cpp:3695 + if (!MaybeDeclCode) + llvm::report_fatal_error("ASTReader::ReadDeclRecord failed readung decl code: " + toString(MaybeDeclCode.takeError())); + switch ((DeclCode)MaybeDeclCode.get()) { ---------------- bruno wrote: > typo on `readung` lol dung ================ Comment at: clang/lib/Serialization/ASTReaderDecl.cpp:4036 + if (llvm::Error JumpFailed = Cursor.JumpToBit(Offset)) + // FIXME don't do a fatal error. + llvm::report_fatal_error("ASTReader::loadDeclUpdateRecords failed jumping: " + toString(std::move(JumpFailed))); ---------------- bruno wrote: > Why? What's a better alternative? Anything that can be used as a clang API needs to return errors instead of using `report_fatal_error`, so that the API can't just `abort` your process. We should propagate this error, but it's getting tedious here and I think better in a follow-up. ================ Comment at: clang/lib/Serialization/ASTReaderDecl.cpp:4119 + if (Expected<unsigned> MaybeRecCode = Cursor.readRecord(Code, Record)) + assert(MaybeRecCode.get() == LOCAL_REDECLARATIONS && "expected LOCAL_REDECLARATIONS record!"); + else ---------------- bruno wrote: > Does this builds fine without assertions? It should, why? The variable is used on both sides of the `if`. ================ Comment at: clang/lib/Serialization/GlobalModuleIndex.cpp:266 // Sniff for the signature. - if (Cursor.Read(8) != 'B' || - Cursor.Read(8) != 'C' || - Cursor.Read(8) != 'G' || - Cursor.Read(8) != 'I') { - return std::make_pair(nullptr, EC_IOError); + for (unsigned char C : {'B', 'C', 'G', 'I'}) { + if (Expected<llvm::SimpleBitstreamCursor::word_t> Res = Cursor.Read(8)) { ---------------- bruno wrote: > Very similar to SerializedDiagnosticReader.cpp:44, does it deserve a common > helper? Left a FIXME in ASTReader.cpp for this. ================ Comment at: llvm/include/llvm/Bitcode/BitstreamReader.h:230 + uint32_t Piece; + if (Expected<unsigned> Res = Read(NumBits)) + Piece = Res.get(); ---------------- bruno wrote: > Alternatively, you can go early return mode for this and other error checking > in BitstreamReader.h > > ``` > Expected<unsigned> Res = Read(NumBits); > if (!Res) > return Res; > Piece = Res.get(); > ``` Yeah that's the first code I fixed, and later moved to what you suggest. Updated here. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63518/new/ https://reviews.llvm.org/D63518 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits