Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assertion failed: (LIsBuiltins && RIsBuiltins && "Non-built-in locations must be rooted in the main file"), function isBeforeInTranslationUnit #22950

Closed
DimitryAndric opened this issue Feb 13, 2015 · 8 comments
Assignees
Labels
bugzilla Issues migrated from bugzilla clang:frontend Language frontend issues, e.g. anything involving "Sema" crash-on-invalid

Comments

@DimitryAndric
Copy link
Collaborator

Bugzilla Link 22576
Version trunk
OS All
CC @DougGregor,@echristo,@jsonn

Extended Description

This assertion was originally reported in a FreeBSD PR: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=197527

It reproduces with clang trunk r228967, and occurs during compilation of WebKit's LowLevelInterpreter.cpp, which is file containing quite a lot of generated inline assembly for the JavaScript engine.

I reduced the test case to just this two-liner:

#pragma clang diagnostic ignored "-Wmissing-noreturn"
__asm__(".Lfoo: movw r2, #:lower16:.Lbar - .Lfoo");

Compile this with:

clang -cc1 -triple armv6 -emit-obj bug197527-reduced.c

Results in:

Assertion failed: (LIsBuiltins && RIsBuiltins && "Non-built-in locations must be rooted in the main file"), function isBeforeInTranslationUnit, file /share/dim/src/llvm/trunk/tools/clang/lib/Basic/SourceManager.cpp, line 2091.
Abort trap
@DimitryAndric
Copy link
Collaborator Author

assigned to @DougGregor

@DimitryAndric
Copy link
Collaborator Author

Additional note: removing the #pragma makes the assertion disappear!

@DimitryAndric
Copy link
Collaborator Author

Backtrace (didn't have debug symbols on this build, so will have to do with just function names):

#​0 0x2ae3a50b in thr_kill () from /lib/libc.so.7
#​1 0x2ae3a4bc in raise () from /lib/libc.so.7
#​2 0x2ae38b53 in abort () from /lib/libc.so.7
#​3 0x2ae18e78 in __assert () from /lib/libc.so.7
#​4 0x0944b068 in clang::SourceManager::isBeforeInTranslationUnit(clang::SourceLocation, clang::SourceLocation) const ()
#​5 0x09442de7 in clang::FullSourceLoc::isBeforeInTranslationUnitThan(clang::SourceLocation) const ()
#​6 0x09427847 in clang::DiagnosticsEngine::GetDiagStatePointForLoc(clang::SourceLocation) const ()
#​7 0x0942df16 in clang::DiagnosticIDs::getDiagnosticSeverity(unsigned int, clang::SourceLocation, clang::DiagnosticsEngine const&) const ()
#​8 0x0942de29 in clang::DiagnosticIDs::getDiagnosticLevel(unsigned int, clang::SourceLocation, clang::DiagnosticsEngine const&) const ()
#​9 0x0942e702 in clang::DiagnosticIDs::ProcessDiag(clang::DiagnosticsEngine&) const ()
#​10 0x09428ca0 in clang::DiagnosticsEngine::EmitCurrentDiagnostic(bool) ()
#​11 0x08549745 in clang::BackendConsumer::InlineAsmDiagHandler2(llvm::SMDiagnostic const&, clang::SourceLocation) ()
#​12 0x0854d0d7 in clang::BackendConsumer::InlineAsmDiagHandler(llvm::SMDiagnostic const&, void*, unsigned int) ()
#​13 0x09e497b3 in srcMgrDiagHandler(llvm::SMDiagnostic const&, void*) ()
#​14 0x0a40d4d7 in (anonymous namespace)::AsmParser::DiagHandler(llvm::SMDiagnostic const&, void*) ()
#​15 0x0a656101 in llvm::SourceMgr::PrintMessage(llvm::raw_ostream&, llvm::SMDiagnostic const&, bool) const ()
#​16 0x0a656ff5 in llvm::SourceMgr::PrintMessage(llvm::raw_ostream&, llvm::SMLoc, llvm::SourceMgr::DiagKind, llvm::Twine const&, llvm::ArrayRefllvm::SMRange, llvm::ArrayRefllvm::SMFixIt, bool) const ()
#​17 0x0a65712d in llvm::SourceMgr::PrintMessage(llvm::SMLoc, llvm::SourceMgr::DiagKind, llvm::Twine const&, llvm::ArrayRefllvm::SMRange, llvm::ArrayRefllvm::SMFixIt, bool) const ()
#​18 0x0a40ff81 in (anonymous namespace)::AsmParser::Error(llvm::SMLoc, llvm::Twine const&, llvm::ArrayRefllvm::SMRange) ()
#​19 0x098568ba in (anonymous namespace)::ARMAsmParser::MatchAndEmitInstruction(llvm::SMLoc, unsigned int&, llvm::SmallVectorImpl<std::__1::unique_ptr<llvm::MCParsedAsmOperand, std::__1::default_deletellvm::MCParsedAsmOperand > >&, llvm::MCStreamer&, unsigned long long&, bool) ()
#​20 0x0a414374 in (anonymous namespace)::AsmParser::parseStatement((anonymous namespace)::ParseStatementInfo&, llvm::MCAsmParserSemaCallback*) ()
#​21 0x0a40de13 in (anonymous namespace)::AsmParser::Run(bool, bool) ()
#​22 0x09e49513 in llvm::AsmPrinter::EmitInlineAsm(llvm::StringRef, llvm::MDNode const*, llvm::InlineAsm::AsmDialect) const ()
#​23 0x09e3c58f in llvm::AsmPrinter::doInitialization(llvm::Module&) ()
#​24 0x0a5c804b in llvm::FPPassManager::doInitialization(llvm::Module&) ()
#​25 0x0a5c837c in llvm::legacy::PassManagerImpl::run(llvm::Module&) ()
#​26 0x0a5c8c08 in llvm::legacy::PassManager::run(llvm::Module&) ()
#​27 0x0855aee4 in clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::raw_ostream*) ()
#​28 0x0854cbff in clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) ()
#​29 0x08763085 in clang::ParseAST(clang::Sema&, bool, bool) ()
#​30 0x0833ab97 in clang::ASTFrontendAction::ExecuteAction() ()
#​31 0x0854b821 in clang::CodeGenAction::ExecuteAction() ()
#​32 0x0833a499 in clang::FrontendAction::Execute() ()
#​33 0x0830a593 in clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) ()
#​34 0x082ed9aa in clang::ExecuteCompilerInvocation(clang::CompilerInstance*) ()
#​35 0x082e3869 in cc1_main(llvm::ArrayRef<char const*>, char const*, void*) ()
#​36 0x082eb885 in main ()

@DimitryAndric
Copy link
Collaborator Author

Actually, the assembly itself is rather misleading, it does not have anything to do with ARM or the target CPU whatsoever. It is some unexpected case in the diagnostics engine, since this also triggers it:

#pragma clang diagnostic ignored "-Wmissing-noreturn"
asm("0");

E.g., just the fact that any warning is triggered for a top-level asm construct causes the assertion. The key word is "top-level", since obviously this does not happen when the asm construct is within a function.

@llvmbot
Copy link
Collaborator

llvmbot commented Feb 17, 2015

This happens because the LHS is "" which is a string that is created in llvm MC, the RHS is "name_of_the_file.c". Then the LOffs is {first = {ID = 3}, second = 1} while the ROffs is {first = {ID = 1}, second = 14}. Ie. the method thinks those two are from different files.

I dont know if thats expected (the buffer is independent of the file but there seems to be some translation in clang::BackendConsumer::InlineAsmDiagHandler2()) or not. In case this is expected there's some code to handle (I think) similar situation with "" which we handle specially.

In either case, this patch (probably wrong) makes clang not crash on this and emit reasonable error:

Index: ../tools/clang/lib/Basic/SourceManager.cpp

--- ../tools/clang/lib/Basic/SourceManager.cpp (revision 229486)
+++ ../tools/clang/lib/Basic/SourceManager.cpp (working copy)
@@ -2084,9 +2084,15 @@
getBuffer(LOffs.first)->getBufferIdentifier()) == 0;
bool RIsBuiltins = strcmp("",
getBuffer(ROffs.first)->getBufferIdentifier()) == 0;

  • bool LIsInlineAsm = strcmp("",
  •                        getBuffer(LOffs.first)->getBufferIdentifier()) == 0;
    
  • bool RIsInlineAsm = strcmp("",
  •                        getBuffer(ROffs.first)->getBufferIdentifier()) == 0;
    
    // built-in is before non-built-in
    if (LIsBuiltins != RIsBuiltins)
    return LIsBuiltins;
  • if (LIsInlineAsm != RIsInlineAsm)
  • return LIsInlineAsm;
    assert(LIsBuiltins && RIsBuiltins &&
    "Non-built-in locations must be rooted in the main file");
    // Both are in built-in buffers, but from different files. We just claim that

the output:

./bin/clang crash.c
:1:2: error: unexpected token at start of statement
0
^
1 error generated.

Doug, as you seem to be the person who commited this... can you comment and/or fix this?

@jsonn
Copy link
Contributor

jsonn commented Mar 13, 2015

The central issue seems to be that a module's global inline assembler doesn't have a location attached. It would be possible to extend llvm::Module::appendModuleInlineAsm to also pass a location field in or alternatively, keep track of it the location on the clang side before extending it. I'm not sure such a change can be done non-intrusive for merging into 3.6.
As such, I believe Roman's approach is the right step forward. Open questions for me are:
(1) How to best identify the problematic buffers. I think we want to restrict this to the global module context, in-function asm doesn't have this problem.
(2) Which order is desirable?

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 9, 2021
@Endilll
Copy link
Contributor

Endilll commented Jul 8, 2023

Both test cases appear to be fixed in Clang 3.7:
https://godbolt.org/z/aEoPWKa37
https://godbolt.org/z/j4Gca1KTM

@Endilll Endilll closed this as completed Jul 8, 2023
@Endilll Endilll added clang:frontend Language frontend issues, e.g. anything involving "Sema" crash-on-invalid labels Jul 8, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Jul 8, 2023

@llvm/issue-subscribers-clang-frontend

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla clang:frontend Language frontend issues, e.g. anything involving "Sema" crash-on-invalid
Projects
None yet
Development

No branches or pull requests

4 participants