[cfe-dev] Clang 3.2 assertion failure writing AST files: RecordIdx == Vals.size() && "Not all record operands emitted!"

Argyrios Kyrtzidis akyrtzi at gmail.com
Mon Mar 18 15:26:00 PDT 2013


Fixed in r177330, thanks for the report and the investigation!

-Argyrios

On Feb 26, 2013, at 7:16 PM, Tom Honermann <thonermann at coverity.com> wrote:

> The following code causes Clang (3.2 on Linux) to fail an assertion test when serializing an AST to an AST file.
> 
> template<typename T>
> void f() {
>  enum E {
>    enumerator
>  };
> 
>  T t = enumerator;
> }
> 
> template void f<int>();
> 
> $ clang -c t.cpp
> <no error, object file is generated successfully>
> 
> $ clang -emit-ast t.cpp
> clang: /nfs/thonermann/clang-3.2/llvm-3.2/include/llvm/Bitcode/BitstreamWriter.h:398: void llvm::BitstreamWriter::EmitRecordWithAbbrevImpl(unsigned int, llvm::SmallVectorImpl<T>&, llvm::StringRef) [with uintty = long unsigned int]: Assertion `RecordIdx == Vals.size() && "Not all record operands emitted!"' failed.
> clang: error: unable to execute command: Segmentation fault (core dumped)
> clang: error: clang frontend command failed due to signal (use -v to see invocation)
> clang version 3.2 (tags/RELEASE_32/final)
> Target: x86_64-unknown-linux-gnu
> Thread model: posix
> clang: note: diagnostic msg: PLEASE submit a bug report to http://llvm.org/bugs/ and include the crash backtrace, preprocessed source, and associated run script.
> clang: note: diagnostic msg:
> ********************
> 
> PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
> Preprocessed source(s) and associated run script(s) are located at:
> clang: note: diagnostic msg: /tmp/t-dqKSIG.cpp
> clang: note: diagnostic msg: /tmp/t-dqKSIG.sh
> clang: note: diagnostic msg:
> 
> ********************
> 
> /tmp/t-dqKSIG.cpp contains the sample code above.
> /tmp/t-dqKSIG.sh contains:
> /path/to/clang -cc1 -triple x86_64-unknown-linux-gnu -emit-pch -disable-free -main-file-name t.cpp -mrelocation-model static -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-linker-version 2.22 -momit-leaf-frame-pointer -fdeprecated-macro -ferror-limit 19 -fmessage-length 197 -mstackrealign -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -x c++ t-dqKSIG.cpp
> 
> This assertion failure (with a different test case) was previously reported here:
>  http://llvm.org/bugs/show_bug.cgi?id=13020
>  Bug 13020 - Clang 3.1 assertion failures reading and writing AST files
> 
> The assertion failure occurs at line 398 below:
> 
> include/llvm/Bitcode/BitstreamWriter.h:
> 25 class BitstreamWriter {
> ...
> 313   template<typename uintty>
> 314   void EmitRecordWithAbbrevImpl(unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
> 315                                 StringRef Blob) {
> ...
> 398     assert(RecordIdx == Vals.size() && "Not all record operands emitted!");
> 399     assert(BlobData == 0 &&
> 400            "Blob data specified for record that doesn't use it!");
> 401   }
> 
> The problem is that ASTDeclWriter::VisitEnumDecl() in lib/Serialization/ASTWriterDecl.cpp incorrectly determines that the abbreviated form of the EnumDecl bit stream can be used when serializing the enum member declaration of the f<int> specialization and ends up passing more operands than are expected for the abbreviation.
> 
> The problematic code is here:
> 
> lib/Serialization/ASTWriterDecl.cpp:
> 224 void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
> ...
> 235   if (MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo()) {
> 236     Writer.AddDeclRef(MemberInfo->getInstantiatedFrom(), Record);
> 237     Record.push_back(MemberInfo->getTemplateSpecializationKind());
> 238 Writer.AddSourceLocation(MemberInfo->getPointOfInstantiation(), Record);
> 239   } else {
> 240     Writer.AddDeclRef(0, Record);
> 241   }
> 242
> 243   if (!D->hasAttrs() &&
> 244       !D->isImplicit() &&
> 245       !D->isUsed(false) &&
> 246       !D->hasExtInfo() &&
> 247       D->getFirstDeclaration() == D->getMostRecentDecl() &&
> 248       !D->isInvalidDecl() &&
> 249       !D->isReferenced() &&
> 250       !D->isTopLevelDeclInObjCContainer() &&
> 251       D->getAccess() == AS_none &&
> 252       !D->isModulePrivate() &&
> 253       !CXXRecordDecl::classofKind(D->getKind()) &&
> 254       !D->getIntegerTypeSourceInfo() &&
> 255       D->getDeclName().getNameKind() == DeclarationName::Identifier &&
> 256       !D->getMemberSpecializationInfo())
> 257     AbbrevToUse = Writer.getDeclEnumAbbrev();
> 258
> 259   Code = serialization::DECL_ENUM;
> 260 }
> 
> Lines 235-241 will queue a conditional number of record operands depending on whether the declaration has member specialization info. The abbreviated bit stream expects just one (matching the else body). Adding a check for '!D->getMemberSpecializationInfo()' to the if conditions at lines 243-256 above appears to correct this problem:
> 
> @@ -252,7 +252,8 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
>       !D->isModulePrivate() &&
>       !CXXRecordDecl::classofKind(D->getKind()) &&
>       !D->getIntegerTypeSourceInfo() &&
> -      D->getDeclName().getNameKind() == DeclarationName::Identifier)
> +      D->getDeclName().getNameKind() == DeclarationName::Identifier &&
> +      !D->getMemberSpecializationInfo())
>     AbbrevToUse = Writer.getDeclEnumAbbrev();
> 
> For reference, here is the corresponding code to build the enum declaration abbreviation that matches the else body at line 240 above.
> 
> lib/Serialization/ASTWriterDecl.cpp:
> 1300 void ASTWriter::WriteDeclsBlockAbbrevs() {
> ....
> 1372   // Abbreviation for DECL_ENUM
> 1373   Abv = new BitCodeAbbrev();
> ....
> 1413   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // InstantiatedMembEnum
> ....
> 1650 }
> 
> Tom.
> 
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130318/35b52856/attachment.html>


More information about the cfe-dev mailing list