Skip to content

Clang ICE: unexpected rewritten operator form #64162

Closed

Description

@AMP999

// https://godbolt.org/z/sfGncMs96

#include <compare>
struct S {
    const std::strong_ordering& operator<=>(const S&) const = default;
};
bool test(S s) {
    return s < s;
}

Clang crashes:

unexpected rewritten operator form
UNREACHABLE executed at /root/llvm-project/clang/lib/AST/ExprCXX.cpp:126!
[...]
 #5 0x00007feebd4f9859 abort (/lib/x86_64-linux-gnu/libc.so.6+0x22859)
 #6 0x00000000035e131a (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x35e131a)
 #7 0x0000000006efd280 clang::CXXRewrittenBinaryOperator::getDecomposedForm() const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6efd280)
 #8 0x00000000070919c1 clang::Stmt::getBeginLoc() const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x70919c1)
 #9 0x00000000064d8aec clang::Sema::PerformCopyInitialization(clang::InitializedEntity const&, clang::SourceLocation, clang::ActionResult<clang::Expr*, true>, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x64d8aec)
#10 0x000000000669b171 clang::Sema::PerformMoveOrCopyInitialization(clang::InitializedEntity const&, clang::Sema::NamedReturnInfo const&, clang::Expr*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x669b171)
#11 0x00000000066c8a07 clang::Sema::BuildReturnStmt(clang::SourceLocation, clang::Expr*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x66c8a07)
#12 0x00000000066ca69f clang::Sema::ActOnReturnStmt(clang::SourceLocation, clang::Expr*, clang::Scope*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x66ca69f)
#13 0x0000000005e60dd7 clang::Parser::ParseReturnStatement() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e60dd7)
[...]

Activity

  1. added
    clang:frontendLanguage frontend issues, e.g. anything involving "Sema"
    crashPrefer [crash-on-valid] or [crash-on-invalid]
    and removed on Jul 27, 2023
  2. llvmbot commented on Jul 27, 2023

    @llvmbot
    Member

    @llvm/issue-subscribers-clang-frontend

  3. shafik commented on Jul 27, 2023

    @shafik
    Contributor

    Confirmed

    Backtrace:

    unexpected rewritten operator form
    UNREACHABLE executed at /root/llvm-project/clang/lib/AST/ExprCXX.cpp:126!
    PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
    Stack dump:
    0.	Program arguments: /opt/compiler-explorer/clang-assertions-trunk/bin/clang++ -gdwarf-4 -g -o /app/output.s -mllvm --x86-asm-syntax=intel -S --gcc-toolchain=/opt/compiler-explorer/gcc-snapshot -fcolor-diagnostics -fno-crash-diagnostics -std=c++20 <source>
    1.	<source>:6:17: current parser token ';'
    2.	<source>:5:16: parsing function body 'test'
    3.	<source>:5:16: in compound statement ('{}')
     #0 0x000000000368a738 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x368a738)
     #1 0x00000000036885bc llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x36885bc)
     #2 0x00000000035d6068 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
     #3 0x00007ff5d9bf2420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
     #4 0x00007ff5d96b500b raise (/lib/x86_64-linux-gnu/libc.so.6+0x4300b)
     #5 0x00007ff5d9694859 abort (/lib/x86_64-linux-gnu/libc.so.6+0x22859)
     #6 0x00000000035e131a (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x35e131a)
     #7 0x0000000006efd280 clang::CXXRewrittenBinaryOperator::getDecomposedForm() const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6efd280)
     #8 0x00000000070919c1 clang::Stmt::getBeginLoc() const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x70919c1)
     #9 0x00000000064d8aec clang::Sema::PerformCopyInitialization(clang::InitializedEntity const&, clang::SourceLocation, clang::ActionResult<clang::Expr*, true>, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x64d8aec)
    #10 0x000000000669b171 clang::Sema::PerformMoveOrCopyInitialization(clang::InitializedEntity const&, clang::Sema::NamedReturnInfo const&, clang::Expr*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x669b171)
    #11 0x00000000066c8a07 clang::Sema::BuildReturnStmt(clang::SourceLocation, clang::Expr*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x66c8a07)
    #12 0x00000000066ca69f clang::Sema::ActOnReturnStmt(clang::SourceLocation, clang::Expr*, clang::Scope*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x66ca69f)
    #13 0x0000000005e60dd7 clang::Parser::ParseReturnStatement() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e60dd7)
    #14 0x0000000005e64049 clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*, clang::ParsedAttributes&, clang::ParsedAttributes&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e64049)
    #15 0x0000000005e65681 clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e65681)
    #16 0x0000000005e665d9 clang::Parser::ParseCompoundStatementBody(bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e665d9)
    #17 0x0000000005e67eaa clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e67eaa)
    #18 0x0000000005d960a1 clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::LateParsedAttrList*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5d960a1)
    #19 0x0000000005dbc868 clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::ParsedAttributes&, clang::SourceLocation*, clang::Parser::ForRangeInit*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5dbc868)
    #20 0x0000000005d89e6a clang::Parser::ParseDeclOrFunctionDefInternal(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec&, clang::AccessSpecifier) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5d89e6a)
    #21 0x0000000005d8a6ff clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*, clang::AccessSpecifier) (.part.0) Parser.cpp:0:0
    #22 0x0000000005d90d71 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5d90d71)
    #23 0x0000000005d91672 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5d91672)
    #24 0x0000000005d8598a clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5d8598a)
    #25 0x00000000048d6f48 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x48d6f48)
    #26 0x000000000413fe59 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x413fe59)
    #27 0x00000000040c598e clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x40c598e)
    #28 0x000000000421ffe6 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x421ffe6)
    #29 0x0000000000bc7532 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbc7532)
    #30 0x0000000000bbfd1a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
    #31 0x0000000003f268b9 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
    #32 0x00000000035d6514 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x35d6514)
    #33 0x0000000003f26eaf clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (.part.0) Job.cpp:0:0
    #34 0x0000000003eeeba5 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3eeeba5)
    #35 0x0000000003eef60d clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3eef60d)
    #36 0x0000000003ef713d clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3ef713d)
    #37 0x0000000000bc57e7 clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbc57e7)
    #38 0x0000000000abfea1 main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xabfea1)
    #39 0x00007ff5d9696083 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24083)
    #40 0x0000000000bbf7fe _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbbf7fe)
    clang++: error: clang frontend command failed with exit code 134 (use -v to see invocation)
    Compiler returned: 134
  4. shafik commented on Jul 27, 2023

    @shafik
    Contributor

    It looks like the result of E = Result.LHS->IgnoreImplicitAsWritten();

    from:

    E = Result.LHS->IgnoreImplicitAsWritten();

    is

    CXXConstructExpr 0x1411e8ed8 'strong_ordering':'class std::strong_ordering' 'void (const strong_ordering &) noexcept'
    `-CXXOperatorCallExpr 0x1411e8430 'const std::strong_ordering':'const class std::strong_ordering' lvalue '<=>'
      |-ImplicitCastExpr 0x1411e8418 'const std::strong_ordering &(*)(const S &) const noexcept' <FunctionToPointerDecay>
      | `-DeclRefExpr 0x1411e8298 'const std::strong_ordering &(const S &) const noexcept' lvalue CXXMethod 0x1411e7cd8 'operator<=>' 'const std::strong_ordering &(const S &) const noexcept'
      |-ImplicitCastExpr 0x1411e8280 'const struct S' lvalue <NoOp>
      | `-DeclRefExpr 0x1411e8228 'S':'struct S' lvalue ParmVar 0x1411e8050 's' 'S':'struct S'
      `-ImplicitCastExpr 0x1411e8268 'const S':'const struct S' lvalue <NoOp>
        `-DeclRefExpr 0x1411e8248 'S':'struct S' lvalue ParmVar 0x1411e8050 's' 'S':'struct S'

    perhaps we actually need to do Result.LHS->IgnoreUnlessSpelledInSource() instead?

  5. shafik commented on Jul 27, 2023

    @shafik
    Contributor
  6. shafik commented on Jul 27, 2023

    @shafik
    Contributor

    I just verified that making that change does not break any test when running check-clang

  7. zygoloid commented on Jul 28, 2023

    @zygoloid
    Contributor

    Hm, yeah, we're not prepared for operator<=> to return a comparison category by reference. (I think we'd get the same failure if operator<=> returned some other class type that implicitly converts to a comparison category. That'd be worth testing too.)

    It's a bit ironic to call IgnoreUnlessSpelledInSource to find an implicitly generated use of the <=> operator that was not spelled in the source, but I think that it would do the right thing in this case.

  8. shafik commented on Jul 28, 2023

    @shafik
    Contributor

    I think we'd get the same failure if operator<=> returned some other class type that implicitly converts to a comparison category. That'd be worth testing too.)

    Do you have an example of this? I was trying to put one together but could not get one that was valid with any implementation.

  9. zygoloid commented on Jul 28, 2023

    @zygoloid
    Contributor

    I think we'd get the same failure if operator<=> returned some other class type that implicitly converts to a comparison category. That'd be worth testing too.)

    Do you have an example of this? I was trying to put one together but could not get one that was valid with any implementation.

    Sure, here: https://godbolt.org/z/xjK4b8Gve -- though it doesn't crash, unlike the seemingly similar case where we require a constructor call rather than a conversion function call, and I'm not sure why.

  10. shafik commented on Jul 28, 2023

    @shafik
    Contributor

    Sure, here: https://godbolt.org/z/xjK4b8Gve -- though it doesn't crash, unlike the seemingly similar case where we require a constructor call rather than a conversion function call, and I'm not sure why.

    I think b/c it has a MaterializeTemporaryExpr which IgnoreImplicitAsWritten() will skip through.

  11. shafik commented on Sep 14, 2023

    @shafik
    Contributor

    PR: #66270

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:frontendLanguage frontend issues, e.g. anything involving "Sema"confirmedVerified by a second partycrashPrefer [crash-on-valid] or [crash-on-invalid]

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions