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

Clang frontend C++ crash when casting string to char[] #63758

Closed
brutalsavage opened this issue Jul 8, 2023 · 12 comments
Closed

Clang frontend C++ crash when casting string to char[] #63758

brutalsavage opened this issue Jul 8, 2023 · 12 comments
Assignees
Labels
c++ 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] obsolete Issues with old (unsupported) versions of LLVM regression release:backport

Comments

@brutalsavage
Copy link

To quickly reproduce: https://gcc.godbolt.org/z/ve4bK48nb (assertion-trunk)

#include <string>

int main() {
  int index = 0;
  auto words = (char[]) std::to_string(index); // forbids casting to array type according to ISO C++ standard
}

Compiling the above code crashes clang clang++ -x c++ --std=c++20 , crashes locally using clang-17.0 (a10019a), also on trunk with assertion (see godbolt link)

@brutalsavage
Copy link
Author

No Assertion

Backtrace:

successful failed overload
UNREACHABLE executed at /root/llvm-project/clang/lib/Sema/SemaCast.cpp:469!
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>:5:46: current parser token ';'
2.	<source>:3:12: parsing function body 'main'
3.	<source>:3:12: in compound statement ('{}')
 #0 0x00005602782da6af llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3c426af)
 #1 0x00005602782d841c llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3c4041c)
 #2 0x0000560278222a78 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x00007f674a698420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #4 0x00007f674a16500b raise (/lib/x86_64-linux-gnu/libc.so.6+0x4300b)
 #5 0x00007f674a144859 abort (/lib/x86_64-linux-gnu/libc.so.6+0x22859)
 #6 0x000056027822dfae (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3b95fae)
 #7 0x000056027ac398d8 tryDiagnoseOverloadedCast(clang::Sema&, CastType, clang::SourceRange, clang::Expr*, clang::QualType, bool) SemaCast.cpp:0:0
 #8 0x000056027ac41d36 diagnoseBadCast(clang::Sema&, unsigned int, CastType, clang::SourceRange, clang::Expr*, clang::QualType, bool) SemaCast.cpp:0:0
 #9 0x000056027ac4236e (anonymous namespace)::CastOperation::CheckCXXCStyleCast(bool, bool) SemaCast.cpp:0:0
#10 0x000056027ac42bb5 clang::Sema::BuildCStyleCastExpr(clang::SourceLocation, clang::TypeSourceInfo*, clang::SourceLocation, clang::Expr*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x65aabb5)
#11 0x000056027b052f22 clang::Sema::ActOnCastExpr(clang::Scope*, clang::SourceLocation, clang::Declarator&, clang::OpaquePtr<clang::QualType>&, clang::SourceLocation, clang::Expr*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x69baf22)
#12 0x000056027ab00364 clang::Parser::ParseParenExpression(clang::Parser::ParenParseOption&, bool, bool, clang::OpaquePtr<clang::QualType>&, clang::SourceLocation&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6468364)
#13 0x000056027aaf5016 clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, bool&, clang::Parser::TypeCastState, bool, bool*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x645d016)
#14 0x000056027aaf6efb clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, clang::Parser::TypeCastState, bool, bool*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x645eefb)
#15 0x000056027aaf6fad clang::Parser::ParseAssignmentExpression(clang::Parser::TypeCastState) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x645efad)
#16 0x000056027aab74fd clang::Parser::ParseDeclarationAfterDeclaratorAndAttributes(clang::Declarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::ForRangeInit*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x641f4fd)
#17 0x000056027aac48c8 clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::ParsedAttributes&, clang::SourceLocation*, clang::Parser::ForRangeInit*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x642c8c8)
#18 0x000056027aaccc39 clang::Parser::ParseSimpleDeclaration(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::ParsedAttributes&, bool, clang::Parser::ForRangeInit*, clang::SourceLocation*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6434c39)
#19 0x000056027aacd0b9 clang::Parser::ParseDeclaration(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::ParsedAttributes&, clang::SourceLocation*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x64350b9)
#20 0x000056027ab7014d 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+++0x64d814d)
#21 0x000056027ab70e91 clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x64d8e91)
#22 0x000056027ab71e89 clang::Parser::ParseCompoundStatementBody(bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x64d9e89)
#23 0x000056027ab7385a clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x64db85a)
#24 0x000056027aa9df41 clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::LateParsedAttrList*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6405f41)
#25 0x000056027aac4e20 clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::ParsedAttributes&, clang::SourceLocation*, clang::Parser::ForRangeInit*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x642ce20)
#26 0x000056027aa91d01 clang::Parser::ParseDeclOrFunctionDefInternal(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec&, clang::AccessSpecifier) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x63f9d01)
#27 0x000056027aa925bf clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*, clang::AccessSpecifier) (.part.0) Parser.cpp:0:0
#28 0x000056027aa983c1 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x64003c1)
#29 0x000056027aa993b6 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x64013b6)
#30 0x000056027aa8d68a clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x63f568a)
#31 0x00005602795624f8 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4eca4f8)
#32 0x0000560278da4939 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x470c939)
#33 0x0000560278d29c16 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4691c16)
#34 0x0000560278e89c86 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x47f1c86)
#35 0x00005602757aa8b4 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x11128b4)
#36 0x00005602757a65da ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#37 0x0000560278b839ad 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
#38 0x0000560278222f80 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3b8af80)
#39 0x0000560278b83fcf 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
#40 0x0000560278b4abac clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x44b2bac)
#41 0x0000560278b4b63d 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+++0x44b363d)
#42 0x0000560278b5371d clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x44bb71d)
#43 0x00005602757a8b2a clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x1110b2a)
#44 0x00005602756ae625 main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x1016625)
#45 0x00007f674a146083 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24083)
#46 0x00005602757a13be _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x11093be)
clang++: error: clang frontend command failed with exit code 134 (use -v to see invocation)
Compiler returned: 134

@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 8, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Jul 8, 2023

@llvm/issue-subscribers-clang-frontend

@AaronBallman AaronBallman added c++ confirmed Verified by a second party labels Jul 13, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Jul 13, 2023

@llvm/issue-subscribers-c-1

@AaronBallman
Copy link
Collaborator

Interestingly, the crash only occurs in C++20 mode or later: https://godbolt.org/z/saj9d8WbW

@AaronBallman
Copy link
Collaborator

A shorter reproducer is:

struct S {} s;
auto words = (char[])s;

https://godbolt.org/z/z1zYYedvq

@AaronBallman
Copy link
Collaborator

Crash started in Clang 16.0.0, does not reproduce in a 15.0.0 assertions build.

@AaronBallman
Copy link
Collaborator

When we attempt to perform the overload cast check, we fail with FK_ParenthesizedListInitFailed. Despite it not being an overload failure, we then go on to see why the overload failed but there were no overloads involved, and hence the unreachable is hit.

I think the issue is that this case statement should be removed:

case InitializationSequence::FK_ParenthesizedListInitFailed:

However, removing that caused several test failures:

Failed Tests (5):
  Clang :: CXX/class/class.compare/class.spaceship/p1.cpp
  Clang :: CXX/drs/dr2xx.cpp
  Clang :: CXX/drs/dr4xx.cpp
  Clang :: CXX/over/over.match/over.match.viable/p3.cpp
  Clang :: SemaCXX/paren-list-agg-init.cpp

That said, I still don't understand why paren init should assume there's a failed overload result like this.

CC @alanzhao1

@alanzhao1 alanzhao1 self-assigned this Jul 17, 2023
@alanzhao1
Copy link
Contributor

Patch: https://reviews.llvm.org/D155523

@alanzhao1
Copy link
Contributor

Reopening so this can be backported to the 16.x branch

@alanzhao1 alanzhao1 reopened this Jul 18, 2023
@EugeneZelenko EugeneZelenko added this to the LLVM 16.0.X Release milestone Jul 18, 2023
alanzhao1 added a commit to alanzhao1/llvm-project that referenced this issue Jul 18, 2023
In C++20, if Clang fails to perform constructor overload on a
RecordType, then Clang will try to perform parentesized aggregate
initialization. If that fails and the initialization was attempted as
part of a cast, then we should get the diagnostics from the failed
constructor overload attempt. However, we don't attempt constructor
overloading for arrays, so previously, if we try to diagnose an
overloaded cast for a parenthesized aggregate initialization of an
array, we crash. To fix this, we now exit tryDiagnoseOverloadedCast(...)
for failed parentesized list initialization if the destination type is
an array.

Fixes llvm#63758

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D155523
@alanzhao1
Copy link
Contributor

/branch alanzhao1/llvm-project/backport-63758

@llvmbot
Copy link
Collaborator

llvmbot commented Jul 18, 2023

/pull-request llvm/llvm-project-release-prs#478

jdoerfert pushed a commit to jdoerfert/llvm-project that referenced this issue Jul 24, 2023
In C++20, if Clang fails to perform constructor overload on a
RecordType, then Clang will try to perform parentesized aggregate
initialization. If that fails and the initialization was attempted as
part of a cast, then we should get the diagnostics from the failed
constructor overload attempt. However, we don't attempt constructor
overloading for arrays, so previously, if we try to diagnose an
overloaded cast for a parenthesized aggregate initialization of an
array, we crash. To fix this, we now exit tryDiagnoseOverloadedCast(...)
for failed parentesized list initialization if the destination type is
an array.

Fixes llvm#63758

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D155523
@maflcko
Copy link
Contributor

maflcko commented Jul 25, 2023

Can this be closed, given that the backport pull has been closed?

@EugeneZelenko EugeneZelenko closed this as not planned Won't fix, can't repro, duplicate, stale Jul 25, 2023
@EugeneZelenko EugeneZelenko added the obsolete Issues with old (unsupported) versions of LLVM label Jul 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ 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] obsolete Issues with old (unsupported) versions of LLVM regression release:backport
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants