llvm / llvm/llvm-project

[clang][constexpr] ICE in constexpr evaluator when parsing malformed unique_ptr constructor

Open
#204,757 1 comment 0 reactions 0 assignees View on GitHub
c++23 clang:frontend constexpr crash-on-invalid generated by fuzzer
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

This input is generated by a fuzzer.
```cxx
template < class _Tp > using __remove_extent_t = _Tp);
template < class > struct unique_ptr {
template < class _Tag, class _Ptr >
constexpr unique_ptr(_Tag, _Ptr , unsigned) : {}
}constexpr unique_ptr< int> make_unique(decltype(sizeof(int)) __n) {
unique_ptr< int>(int(), new __remove_extent_t< int >[__n](5), __n}
auto p1 = make_unique(5)
```

https://godbolt.org/z/vo1564Mqo

It needs -std=c++23 and above to trigger.

It looks a bit like https://github.com/llvm/llvm-project/issues/200602, and it is also introduced since clang 19. But the assertion is different.
Besides, it can be triggered in the plain trunk version.
```
:1:53: error: expected ';' after alias declaration
1 | template < class _Tp > using __remove_extent_t = _Tp);
| ^
| ;
:4:49: error: expected class member or base class name
4 | constexpr unique_ptr(_Tag, _Ptr , unsigned) : {}
| ^
:5:2: error: expected ';' after struct
5 | }constexpr unique_ptr< int> make_unique(decltype(sizeof(int)) __n) {
| ^
| ;
:6:68: error: expected ')'
6 | unique_ptr< int>(int(), new __remove_extent_t< int >[__n](5), __n}
| ^
:6:19: note: to match this '('
6 | unique_ptr< int>(int(), new __remove_extent_t< int >[__n](5), __n}
| ^
:6:68: error: expected ';' after expression
6 | unique_ptr< int>(int(), new __remove_extent_t< int >[__n](5), __n}
| ^
| ;
clang++: /root/llvm-project/llvm/include/llvm/Support/Casting.h:572: decltype(auto) llvm::cast(From*) [with To = clang::InitListExpr; From = const clang::Expr]: Assertion `isa(Val) && "cast() argument of incompatible type!"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace and dumped files.
Stack dump:
0. Program arguments: /opt/compiler-explorer/clang-assertions-trunk/bin/clang++ -g -o /app/output.s -mllvm --x86-asm-syntax=intel -fno-verbose-asm -S --gcc-toolchain=/opt/compiler-explorer/gcc-snapshot -fcolor-diagnostics -fno-crash-diagnostics -std=c++23
1. parser at end of file
#0 0x0000000004353728 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4353728)
#1 0x0000000004350664 llvm::sys::RunSignalHandlers() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4350664)
#2 0x0000000004350c84 llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4350c84)
#3 0x000000000428e1c8 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
#4 0x00007ad91b845330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
#5 0x00007ad91b89eb2c pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x9eb2c)
#6 0x00007ad91b84527e raise (/lib/x86_64-linux-gnu/libc.so.6+0x4527e)
#7 0x00007ad91b8288ff abort (/lib/x86_64-linux-gnu/libc.so.6+0x288ff)
#8 0x00007ad91b82881b (/lib/x86_64-linux-gnu/libc.so.6+0x2881b)
#9 0x00007ad91b83b517 (/lib/x86_64-linux-gnu/libc.so.6+0x3b517)
#10 0x00000000080504f4 (anonymous namespace)::PointerExprEvaluator::VisitCXXNewExpr(clang::CXXNewExpr const*) ExprConstant.cpp:0:0
#11 0x000000000802acb3 clang::StmtVisitorBase::Visit(clang::Stmt const*) ExprConstant.cpp:0:0
#12 0x000000000802c307 EvaluatePointer(clang::Expr const*, (anonymous namespace)::LValue&, (anonymous namespace)::EvalInfo&, bool) ExprConstant.cpp:0:0
#13 0x0000000008016915 Evaluate(clang::APValue&, (anonymous namespace)::EvalInfo&, clang::Expr const*) ExprConstant.cpp:0:0
#14 0x00000000080099ab EvaluateInPlace(clang::APValue&, (anonymous namespace)::EvalInfo&, (anonymous namespace)::LValue const&, clang::Expr const*, bool) (.part.0) ExprConstant.cpp:0:0
#15 0x0000000008009cfc EvaluateCallArg(clang::ParmVarDecl const*, clang::Expr const*, (anonymous namespace)::CallRef, (anonymous namespace)::EvalInfo&, bool, clang::APValue**) ExprConstant.cpp:0:0
#16 0x000000000800a055 EvaluateArgs(llvm::ArrayRef, (anonymous namespace)::CallRef, (anonymous namespace)::EvalInfo&, clang::FunctionDecl const*, bool, (anonymous namespace)::LValue*) ExprConstant.cpp:0:0
#17 0x0000000008036d90 HandleConstructorCall(clang::Expr const*, (anonymous namespace)::LValue const&, llvm::ArrayRef, clang::CXXConstructorDecl const*, (anonymous namespace)::EvalInfo&, clang::APValue&) ExprConstant.cpp:0:0
#18 0x0000000008007472 (anonymous namespace)::RecordExprEvaluator::VisitCXXConstructExpr(clang::CXXConstructExpr const*, clang::QualType) ExprConstant.cpp:0:0
#19 0x0000000008004ff6 clang::StmtVisitorBase::Visit(clang::Stmt const*) ExprConstant.cpp:0:0
#20 0x0000000008007256 EvaluateRecord(clang::Expr const*, (anonymous namespace)::LValue const&, clang::APValue&, (anonymous namespace)::EvalInfo&) ExprConstant.cpp:0:0
#21 0x000000000801702e Evaluate(clang::APValue&, (anonymous namespace)::EvalInfo&, clang::Expr const*) ExprConstant.cpp:0:0
#22 0x0000000008020b62 EvaluateIgnoredValue((anonymous namespace)::EvalInfo&, clang::Expr const*) ExprConstant.cpp:0:0
#23 0x000000000800e9e8 EvaluateStmt((anonymous namespace)::StmtResult&, (anonymous namespace)::EvalInfo&, clang::Stmt const*, clang::SwitchCase const*) (.part.0) ExprConstant.cpp:0:0
#24 0x000000000800ef28 EvaluateStmt((anonymous namespace)::StmtResult&, (anonymous namespace)::EvalInfo&, clang::Stmt const*, clang::SwitchCase const*) (.part.0) ExprConstant.cpp:0:0
#25 0x000000000801448b HandleFunctionCall(clang::SourceLocation, clang::FunctionDecl const*, (anonymous namespace)::LValue const*, clang::Expr const*, llvm::ArrayRef, (anonymous namespace)::CallRef, clang::Stmt const*, (anonymous namespace)::EvalInfo&, clang::APValue&, (anonymous namespace)::LValue const*) ExprConstant.cpp:0:0
#26 0x000000000803ade3 (anonymous namespace)::ExprEvaluatorBase<(anonymous namespace)::RecordExprEvaluator>::handleCallExpr(clang::CallExpr const*, clang::APValue&, (anonymous namespace)::LValue const*) ExprConstant.cpp:0:0
#27 0x0000000008004d73 clang::StmtVisitorBase::Visit(clang::Stmt const*) ExprConstant.cpp:0:0
#28 0x0000000008007256 EvaluateRecord(clang::Expr const*, (anonymous namespace)::LValue const&, clang::APValue&, (anonymous namespace)::EvalInfo&) ExprConstant.cpp:0:0
#29 0x0000000008009987 EvaluateInPlace(clang::APValue&, (anonymous namespace)::EvalInfo&, (anonymous namespace)::LValue const&, clang::Expr const*, bool) (.part.0) ExprConstant.cpp:0:0
#30 0x00000000080650b9 clang::Expr::EvaluateAsInitializer(clang::ASTContext const&, clang::VarDecl const*, clang::Expr::EvalResult&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x80650b9)
#31 0x0000000007e49b37 clang::VarDecl::evaluateValueImpl(llvm::SmallVectorImpl>*, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x7e49b37)
#32 0x0000000007e49d21 clang::VarDecl::checkForConstantInitialization(llvm::SmallVectorImpl>&) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x7e49d21)
#33 0x0000000007023ce2 clang::Sema::CheckCompleteVariableDeclaration(clang::VarDecl*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x7023ce2)
#34 0x000000000703aeea clang::Sema::AddInitializerToDecl(clang::Decl*, clang::Expr*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x703aeea)
#35 0x0000000006c7ebf1 clang::Parser::ParseDeclarationAfterDeclaratorAndAttributes(clang::Declarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::ForRangeInit*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6c7ebf1)
#36 0x0000000006c8bd6a clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::ParsedAttributes&, clang::Parser::ParsedTemplateInfo&, clang::SourceLocation*, clang::Parser::ForRangeInit*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6c8bd6a)
#37 0x0000000006c48b2b clang::Parser::ParseDeclOrFunctionDefInternal(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec&, clang::AccessSpecifier) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6c48b2b)
#38 0x0000000006c4932f clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*, clang::AccessSpecifier) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6c4932f)
#39 0x0000000006c50de1 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6c50de1)
#40 0x0000000006c51cf5 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6c51cf5)
#41 0x0000000006c32bda clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6c32bda)
#42 0x0000000004e4e328 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4e4e328)
#43 0x0000000005186ee8 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5186ee8)
#44 0x0000000005102aed clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5102aed)
#45 0x0000000005285a0d clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5285a0d)
#46 0x0000000000dccc5c cc1_main(llvm::ArrayRef, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xdccc5c)
#47 0x0000000000dc393a ExecuteCC1Tool(llvm::SmallVectorImpl&, llvm::ToolContext const&, llvm::IntrusiveRefCntPtr) driver.cpp:0:0
#48 0x0000000000dc3abd int llvm::function_ref&)>::callback_fn&)>(long, llvm::SmallVectorImpl&) driver.cpp:0:0
#49 0x0000000004ec1329 void llvm::function_ref::callback_fn>, std::__cxx11::basic_string, std::allocator>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#50 0x000000000428e604 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x428e604)
#51 0x0000000004ec1976 clang::driver::CC1Command::Execute(llvm::ArrayRef>, std::__cxx11::basic_string, std::allocator>*, bool*) const (.part.0) Job.cpp:0:0
#52 0x0000000004e7e312 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4e7e312)
#53 0x0000000004e7f2be clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl>&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4e7f2be)
#54 0x0000000004e86af5 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4e86af5)
#55 0x0000000000dc91d2 clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xdc91d2)
#56 0x0000000000cc8e4a main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xcc8e4a)
#57 0x00007ad91b82a1ca (/lib/x86_64-linux-gnu/libc.so.6+0x2a1ca)
#58 0x00007ad91b82a28b __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28b)
#59 0x0000000000dc32e5 _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xdc32e5)
clang++: error: clang frontend command failed due to signal (use -v to see invocation)
Compiler returned: 134
```

Contributor guide

Open the contributing guide

Research direction

Reproduce the crash with the supplied malformed C++ input using clang++ in -std=c++23 mode. Start in ExprConstant.cpp at PointerExprEvaluator::VisitCXXNewExpr, identified in the assertion stack, and trace the constexpr evaluation of the malformed new expression. Done means this input reports diagnostics without triggering the incompatible InitListExpr cast assertion.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.