llvm / llvm/llvm-project

Clang trunk: unreachable/crash in Sema::BuildBinOp during parsing of enum initializer with | and __builtin_goacc_parlevel_size

Open
#173,619 4 comments 0 reactions 0 assignees View on GitHub
clang:frontend confirmed crash generated by fuzzer regression:21
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

## Compiler Explorer: https://godbolt.org/z/n838cP37x

- clang start crashing on `Trunk`
- generated by fuzzer

## Console
```console
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 -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
1. :12:49: current parser token ')'
#0 0x00000000042ecab8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x42ecab8)
#1 0x00000000042e9ee4 llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x42e9ee4)
#2 0x000000000422ec88 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
#3 0x000076953ee42520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
#4 0x000076953ee969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
#5 0x000076953ee42476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
#6 0x000076953ee287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
#7 0x000076953ee2871b (/lib/x86_64-linux-gnu/libc.so.6+0x2871b)
#8 0x000076953ee39e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
#9 0x0000000006f98a56 clang::Sema::BuildBinOp(clang::Scope*, clang::SourceLocation, clang::BinaryOperatorKind, clang::Expr*, clang::Expr*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x6f98a56)
#10 0x0000000006f98dd6 clang::Sema::ActOnBinOp(clang::Scope*, clang::SourceLocation, clang::tok::TokenKind, clang::Expr*, clang::Expr*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x6f98dd6)
#11 0x0000000006a9b950 clang::Parser::ParseRHSOfBinaryExpression(clang::ActionResult, clang::prec::Level) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x6a9b950)
#12 0x0000000006a9ede9 clang::Parser::ParseExpression(clang::TypoCorrectionTypeBehavior) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x6a9ede9)
#13 0x0000000006aa2bc4 clang::Parser::ParseParenExpression(clang::ParenParseOption&, bool, clang::ParenExprKind, clang::TypoCorrectionTypeBehavior, clang::OpaquePtr&, clang::SourceLocation&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x6aa2bc4)
#14 0x0000000006a99408 clang::Parser::ParseCastExpression(clang::CastParseKind, bool, bool&, clang::TypoCorrectionTypeBehavior, bool, bool*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x6a99408)
#15 0x0000000006aa572e clang::Parser::ParseConstantExpressionInExprEvalContext(clang::TypoCorrectionTypeBehavior) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x6aa572e)
#16 0x0000000006a5fb9d clang::Parser::ParseEnumBody(clang::SourceLocation, clang::Decl*, clang::SkipBodyInfo*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x6a5fb9d)
#17 0x0000000006a67f44 clang::Parser::ParseEnumSpecifier(clang::SourceLocation, clang::DeclSpec&, clang::Parser::ParsedTemplateInfo const&, clang::AccessSpecifier, clang::Parser::DeclSpecContext) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x6a67f44)
#18 0x0000000006a6401a clang::Parser::ParseDeclarationSpecifiers(clang::DeclSpec&, clang::Parser::ParsedTemplateInfo&, clang::AccessSpecifier, clang::Parser::DeclSpecContext, clang::Parser::LateParsedAttrList*, clang::ImplicitTypenameContext) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x6a6401a)
#19 0x0000000006a1e507 clang::Parser::ParseDeclOrFunctionDefInternal(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec&, clang::AccessSpecifier) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x6a1e507)
#20 0x0000000006a1ef7f clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*, clang::AccessSpecifier) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x6a1ef7f)
#21 0x0000000006a26daa clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x6a26daa)
#22 0x0000000006a27d45 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x6a27d45)
#23 0x0000000006a281f0 clang::Parser::ParseFirstTopLevelDecl(clang::OpaquePtr&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x6a281f0)
#24 0x0000000006a08d93 clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x6a08d93)
#25 0x0000000004c4dde8 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x4c4dde8)
#26 0x0000000004f446e5 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x4f446e5)
#27 0x0000000004ec497e clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x4ec497e)
#28 0x000000000503ea6d clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x503ea6d)
#29 0x0000000000de5b4c cc1_main(llvm::ArrayRef, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0xde5b4c)
#30 0x0000000000ddc59a ExecuteCC1Tool(llvm::SmallVectorImpl&, llvm::ToolContext const&, llvm::IntrusiveRefCntPtr) driver.cpp:0:0
#31 0x0000000000ddc71d int llvm::function_ref&)>::callback_fn&)>(long, llvm::SmallVectorImpl&) driver.cpp:0:0
#32 0x0000000004cc0739 void llvm::function_ref::callback_fn>, std::__cxx11::basic_string, std::allocator>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#33 0x000000000422f124 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x422f124)
#34 0x0000000004cc0d4f clang::driver::CC1Command::Execute(llvm::ArrayRef>, std::__cxx11::basic_string, std::allocator>*, bool*) const (.part.0) Job.cpp:0:0
#35 0x0000000004c81832 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x4c81832)
#36 0x0000000004c827de clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl>&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x4c827de)
#37 0x0000000004c89c35 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0x4c89c35)
#38 0x0000000000de1f41 clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0xde1f41)
#39 0x0000000000c8cf94 main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0xc8cf94)
#40 0x000076953ee29d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#41 0x000076953ee29e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#42 0x0000000000ddc035 _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+0xddc035)
clang: error: clang frontend command failed with exit code 134 (use -v to see invocation)
Compiler returned: 134
```

## Code
```c
#ifndef GOMP_CONSTANTS_H
#define GOMP_CONSTANTS_H 1

enum gomp_map_kind {
/* If not already present, allocate. */
GOMP_MAP_ALLOC = 0,
/* ..., and copy to device. */
GOMP_MAP_TO = (GOMP_MAP_ALLOC | GOMP_MAP_FLAG_TO),
/* ..., and copy from device. */
GOMP_MAP_FROM = __builtin_goacc_parlevel_size(GOMP_DIM_GANG),
/* ..., and copy to and from device. */
GOMP_MAP_TOFROM = (GOMP_MAP_TO | GOMP_MAP_FROM),
}
```

Contributor guide

Open the contributing guide

Research direction

Reproduce the crash using the C snippet and the Compiler Explorer link, then start at clang::Sema::BuildBinOp in the stack trace and follow the parser path through ParseRHSOfBinaryExpression and ParseEnumBody. Done means Clang no longer aborts while parsing this enum initializer and instead handles the input safely.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.