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 ICE: invalid parameter index on some attributes with invalid indices applied to varargs functions #61635

Open
langston-barrett opened this issue Mar 22, 2023 · 17 comments
Labels
awaiting-review Has pending Phabricator review clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party crash-on-invalid good first issue https://github.com/llvm/llvm-project/contribute

Comments

@langston-barrett
Copy link
Contributor

langston-barrett commented Mar 22, 2023

This is a fuzzer-generated bug. Feel free to close if you're not interested in such reports. If you would like more reports of fuzzer-generated bugs, let me know and I can post them. I read the bug report guidelines, and did not find information on whether or not fuzzer-generated bugs were welcome.

Clang crashes on this program:

__attribute__ ((__format_arg__(2)))
void test (int i, ...) { }

with this message (Godbolt):

clang++: /root/llvm-project/clang/include/clang/AST/Type.h:4249: clang::QualType clang::FunctionProtoType::getParamType(unsigned int) const: Assertion `i < getNumParams() && "invalid parameter index"' failed.
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 -c -O0 <source>
1.	<source>:2:24: current parser token '{'
 #0 0x000055767e07d78f llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x400478f)
 #1 0x000055767e07b4cc llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x40024cc)
 #2 0x000055767dfc8b38 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x00007f6519e42420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #4 0x00007f651990f00b raise (/lib/x86_64-linux-gnu/libc.so.6+0x4300b)
 #5 0x00007f65198ee859 abort (/lib/x86_64-linux-gnu/libc.so.6+0x22859)
 #6 0x00007f65198ee729 (/lib/x86_64-linux-gnu/libc.so.6+0x22729)
 #7 0x00007f65198fffd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
 #8 0x0000557680ac32d5 getFunctionOrMethodParamType(clang::Decl const*, unsigned int) SemaDeclAttr.cpp:0:0
 #9 0x0000557680af2357 handleFormatArgAttr(clang::Sema&, clang::Decl*, clang::ParsedAttr const&) SemaDeclAttr.cpp:0:0
#10 0x0000557680b1dcee ProcessDeclAttribute(clang::Sema&, clang::Scope*, clang::Decl*, clang::ParsedAttr const&, clang::Sema::ProcessDeclAttributeOptions const&) (.isra.0) SemaDeclAttr.cpp:0:0
#11 0x0000557680b1ebeb clang::Sema::ProcessDeclAttributes(clang::Scope*, clang::Decl*, clang::Declarator const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6aa5beb)
#12 0x0000557680ab5470 clang::Sema::ActOnFunctionDeclarator(clang::Scope*, clang::Declarator&, clang::DeclContext*, clang::TypeSourceInfo*, clang::LookupResult&, llvm::MutableArrayRef<clang::TemplateParameterList*>, bool&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6a3c470)
#13 0x0000557680abb0cf clang::Sema::HandleDeclarator(clang::Scope*, clang::Declarator&, llvm::MutableArrayRef<clang::TemplateParameterList*>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6a420cf)
#14 0x0000557680abbc13 clang::Sema::ActOnStartOfFunctionDef(clang::Scope*, clang::Declarator&, llvm::MutableArrayRef<clang::TemplateParameterList*>, clang::Sema::SkipBodyInfo*, clang::Sema::FnBodyKind) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6a42c13)
#15 0x0000557680754792 clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::LateParsedAttrList*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x66db792)
#16 0x00005576807805a0 clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::ParsedAttributes&, clang::SourceLocation*, clang::Parser::ForRangeInit*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x67075a0)
#17 0x00005576807486f2 clang::Parser::ParseDeclOrFunctionDefInternal(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec&, clang::AccessSpecifier) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x66cf6f2)
#18 0x0000557680748faf clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*, clang::AccessSpecifier) (.part.0) Parser.cpp:0:0
#19 0x000055768074fa39 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x66d6a39)
#20 0x000055768075038d clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x66d738d)
#21 0x0000557680750854 clang::Parser::ParseFirstTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x66d7854)
#22 0x000055768074422a clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x66cb22a)
#23 0x000055767f2a4798 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x522b798)
#24 0x000055767eb09979 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4a90979)
#25 0x000055767ea8dea6 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4a14ea6)
#26 0x000055767ebedb37 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b74b37)
#27 0x000055767b608ef6 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x158fef6)
#28 0x000055767b604d1a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#29 0x000055767e8eeb0d 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
#30 0x000055767dfc9020 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3f50020)
#31 0x000055767e8ef3cf 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
#32 0x000055767e8b6c0c clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x483dc0c)
#33 0x000055767e8b76ad 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+++0x483e6ad)
#34 0x000055767e8bf35d clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x484635d)
#35 0x000055767b6073a0 clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x158e3a0)
#36 0x000055767b5134b5 main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x149a4b5)
#37 0x00007f65198f0083 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24083)
#38 0x000055767b5ffa2e _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x1586a2e)
clang++: error: clang frontend command failed with exit code 134 (use -v to see invocation)
Compiler returned: 134

This looks like a Clang problem, because it still happens with -emit-llvm -Xclang -disable-llvm-passes.

I searched like so for duplicates, but didn't find any:

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

llvmbot commented Mar 22, 2023

@llvm/issue-subscribers-clang-frontend

@shafik
Copy link
Collaborator

shafik commented Mar 23, 2023

This is a good bug report while the code is invalid we should generate a proper diagnostic like gcc does: https://godbolt.org/z/PrEvnfKK8

This is probably an easy mistake for someone to make if they are using the attribute the first time or typo the index etc

On the other hand we don't have the bandwidth for mass submission of fuzzer bugs but carefully curated bug submissions are definitely welcome @AaronBallman do you have additional feedback on this?

@shafik shafik added confirmed Verified by a second party crash-on-invalid clang:diagnostics New/improved warning or error message in Clang, but not in clang-tidy or static analyzer and removed crash Prefer [crash-on-valid] or [crash-on-invalid] labels Mar 23, 2023
@tbaederr
Copy link
Contributor

Should be an easy fix, just compare the Idx with getFunctionOrMethodNumParams(D).

@tbaederr tbaederr added the good first issue https://github.com/llvm/llvm-project/contribute label Mar 23, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Mar 23, 2023

@llvm/issue-subscribers-good-first-issue

@AaronBallman
Copy link
Collaborator

This is a good bug report while the code is invalid we should generate a proper diagnostic like gcc does: https://godbolt.org/z/PrEvnfKK8

This is probably an easy mistake for someone to make if they are using the attribute the first time or typo the index etc

Agreed, this is a good issue to fix (and shouldn't be too challenging).

On the other hand we don't have the bandwidth for mass submission of fuzzer bugs but carefully curated bug submissions are definitely welcome @AaronBallman do you have additional feedback on this?

You nailed it -- if the fuzzer produces code that could be reasonably plausible for a user to write (like this one), then it's a great bug report to file. For implausible code, we'd be fine accepting a patch to fix the issue if it's a crash but would probably not prioritize the bug too highly otherwise. (If the code is borderline, I'd say go ahead and add an issue for it.)

@langston-barrett
Copy link
Contributor Author

Thanks for the feedback @shafik, @AaronBallman! I'll endeavor to post useful bugs as I find them, feel free to let me know if they're straying outside of the realm of reports you want.

This test case exhibits a similar issue; not sure whether to file a separate bug or just note it here.

void __attribute__ ((alloc_size (2, 3))) *test(int i, ...);

@AaronBallman
Copy link
Collaborator

AaronBallman commented Mar 24, 2023

Eh, let's note it here -- it's a semi-distinct issue, but it's the same kind of problem between both attributes (so the fix for one might fix the other, depending on how we decide to address it).

Would you mind editing the summary and title though, so it's clear there's two-ish issues here?

@langston-barrett langston-barrett changed the title Clang ICE: invalid parameter index on __format_arg__ with invalid index applied to varargs function Clang ICE: invalid parameter index on some attributes with invalid indices applied to varargs functions Mar 24, 2023
@samuelmaina
Copy link
Contributor

samuelmaina commented Mar 26, 2023

Hello @tbaederr , what does this mean >Should be an easy fix, just compare the Idx with getFunctionOrMethodNumParams(D).I am able to track to the function where the error is emerging which is this

static QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx) {
  if (const FunctionType *FnTy = D->getFunctionType())
    return cast<FunctionProtoType>(FnTy)->getParamType(Idx);
  if (const auto *BD = dyn_cast<BlockDecl>(D))
    return BD->getParamDecl(Idx)->getType();

  return cast<ObjCMethodDecl>(D)->parameters()[Idx]->getType();
}

What changes should I make for the comparison?

@tbaederr
Copy link
Contributor

That is not the function where the error is reported though. You need to find the place where that happens and check if the given index is greater than the number of parameters.

@samuelmaina
Copy link
Contributor

samuelmaina commented Mar 26, 2023

The crash emerges from the assertion failing in the getParamType after being called in the above function.

QualType getParamType(unsigned i) const {
    assert(i < getNumParams() && "invalid parameter index");
    return param_type_begin()[i];
  }

I guess my task is to return a nice warning or error message maybe > attribute argument value '2' exceeds the number of function parameters 1 .

@samuelmaina
Copy link
Contributor

Where can I find classes and function for creating Warmng or Error messages?
I am a begginer that why I may ask very basic questions. Bare with me.

@samuelmaina
Copy link
Contributor

Even if I compare the Idx and the result of getFunctionOrMethodNumParams(D) in the getFunctionOrMethodParamType function above , I still can't use an assertion since it will cause a crush.

@tbaederr
Copy link
Contributor

Yes, you need to do that before the assertion is reached, and from the function that calls getFunctionOrMethodParamType

@ipriyanshi1708
Copy link
Contributor

Even if I compare the Idx and the result of getFunctionOrMethodNumParams(D) in the getFunctionOrMethodParamType function above , I still can't use an assertion since it will cause a crush.

I am also working on this issue. Can we collaborate?

@samuelmaina
Copy link
Contributor

Sure.

@SamTebbs33
Copy link
Collaborator

SamTebbs33 commented Mar 28, 2023

From brief investigation it looks like we want the bad function here to produce the same error message as GCC: https://godbolt.org/z/761MhbPYP

@xgupta xgupta added the awaiting-review Has pending Phabricator review label May 6, 2023
@xgupta
Copy link
Contributor

xgupta commented May 6, 2023

Adding posted patch link - https://reviews.llvm.org/D147037

@Endilll Endilll removed the clang:diagnostics New/improved warning or error message in Clang, but not in clang-tidy or static analyzer label Jan 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting-review Has pending Phabricator review clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party crash-on-invalid good first issue https://github.com/llvm/llvm-project/contribute
Projects
None yet
Development

No branches or pull requests