Skip to content

Clang ICE: unexpected rewritten operator form #64162

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

Closed
AMP999 opened this issue Jul 27, 2023 · 10 comments · Fixed by #66270
Closed

Clang ICE: unexpected rewritten operator form #64162

AMP999 opened this issue Jul 27, 2023 · 10 comments · Fixed by #66270
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party crash Prefer [crash-on-valid] or [crash-on-invalid]

Comments

@AMP999
Copy link
Contributor

AMP999 commented Jul 27, 2023

// 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)
[...]
@EugeneZelenko EugeneZelenko added clang:frontend Language frontend issues, e.g. anything involving "Sema" crash Prefer [crash-on-valid] or [crash-on-invalid] and removed new issue labels Jul 27, 2023
@llvmbot
Copy link
Member

llvmbot commented Jul 27, 2023

@llvm/issue-subscribers-clang-frontend

@shafik
Copy link
Collaborator

shafik commented Jul 27, 2023

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

@shafik shafik added the confirmed Verified by a second party label Jul 27, 2023
@shafik
Copy link
Collaborator

shafik commented Jul 27, 2023

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?

@shafik
Copy link
Collaborator

shafik commented Jul 27, 2023

@shafik
Copy link
Collaborator

shafik commented Jul 27, 2023

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

@zygoloid
Copy link
Collaborator

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.

@shafik
Copy link
Collaborator

shafik commented Jul 28, 2023

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.

@zygoloid
Copy link
Collaborator

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.

@shafik
Copy link
Collaborator

shafik commented Jul 28, 2023

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.

shafik added a commit to shafik/llvm-project that referenced this issue Sep 13, 2023
…ase when spaceship operator returns comparison category by reference

Currently CXXRewrittenBinaryOperator::getDecomposedForm(...) may crash if the
spaceship operator returns a comparison category by reference. This because
IgnoreImplicitAsWritten() does not look through CXXConstructExpr. The fix is to
use IgnoreUnlessSpelledInSource() which will look though CXXConstructExpr.

This fixes: llvm#64162
@shafik
Copy link
Collaborator

shafik commented Sep 14, 2023

PR: #66270

shafik added a commit to shafik/llvm-project that referenced this issue Sep 14, 2023
…ase when spaceship operator returns comparison category by reference

Currently CXXRewrittenBinaryOperator::getDecomposedForm(...) may crash if the
spaceship operator returns a comparison category by reference. This because
IgnoreImplicitAsWritten() does not look through CXXConstructExpr. The fix is to
use IgnoreUnlessSpelledInSource() which will look though CXXConstructExpr.

This fixes: llvm#64162
shafik added a commit to shafik/llvm-project that referenced this issue Sep 25, 2023
…ase when spaceship operator returns comparison category by reference

Currently CXXRewrittenBinaryOperator::getDecomposedForm(...) may crash if the
spaceship operator returns a comparison category by reference. This because
IgnoreImplicitAsWritten() does not look through CXXConstructExpr. The fix is to
use IgnoreUnlessSpelledInSource() which will look though CXXConstructExpr.

This fixes: llvm#64162
shafik added a commit that referenced this issue Sep 25, 2023
…ase when spaceship operator returns comparison category by reference (#66270)

Currently CXXRewrittenBinaryOperator::getDecomposedForm(...) may crash
if the spaceship operator returns a comparison category by reference. This
because IgnoreImplicitAsWritten() does not look through CXXConstructExpr. The
fix is to use IgnoreUnlessSpelledInSource() which will look though
CXXConstructExpr.

This fixes: #64162
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party crash Prefer [crash-on-valid] or [crash-on-invalid]
Projects
None yet
5 participants