llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.06k stars 11.59k forks source link

Crash on invalid use of `_Nonnull` attribute through an alias template #51223

Open chandlerc opened 3 years ago

chandlerc commented 3 years ago
Bugzilla Link 51881
Version trunk
OS All
CC @AaronBallman,@zygoloid,@rjmccall

Extended Description

https://compiler-explorer.com/z/EKfcebd97

template <typename T>
using Nonnull = T _Nonnull;

Nonnull<int> x;

From compiler explorer:

PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.  Program arguments: /opt/compiler-explorer/clang-trunk/bin/clang++ -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 -O2 -march=haswell -fsanitize=null -fno-inline <source>
1.  <source>:4:1: at annotation token
 #&#8203;0 0x000055ebf938a22f PrintStackTraceSignalHandler(void*) Signals.cpp:0:0
 #&#8203;1 0x000055ebf93880f0 llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-trunk/bin/clang+++0x35880f0)
 #&#8203;2 0x000055ebf92d8a68 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #&#8203;3 0x00007f02e24143c0 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x153c0)
 #&#8203;4 0x000055ebfb934947 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformAttributedType(clang::TypeLocBuilder&, clang::AttributedTypeLoc) SemaTemplateInstantiate.cpp:0:0
 #&#8203;5 0x000055ebfb9242cb clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformType(clang::TypeLocBuilder&, clang::TypeLoc) SemaTemplateInstantiate.cpp:0:0
 #&#8203;6 0x000055ebfb927a2a clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformType(clang::TypeSourceInfo*) SemaTemplateInstantiate.cpp:0:0
 #&#8203;7 0x000055ebfb927b38 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformType(clang::QualType) SemaTemplateInstantiate.cpp:0:0
 #&#8203;8 0x000055ebfb92894c clang::Sema::SubstType(clang::QualType, clang::MultiLevelTemplateArgumentList const&, clang::SourceLocation, clang::DeclarationName) (/opt/compiler-explorer/clang-trunk/bin/clang+++0x5b2894c)
 #&#8203;9 0x000055ebfb841180 clang::Sema::CheckTemplateIdType(clang::TemplateName, clang::SourceLocation, clang::TemplateArgumentListInfo&) (/opt/compiler-explorer/clang-trunk/bin/clang+++0x5a41180)
#&#8203;10 0x000055ebfb842baf clang::Sema::ActOnTemplateIdType(clang::Scope*, clang::CXXScopeSpec&, clang::SourceLocation, clang::OpaquePtr<clang::TemplateName>, clang::IdentifierInfo*, clang::SourceLocation, clang::SourceLocation, llvm::MutableArrayRef<clang::ParsedTemplateArgument>, clang::SourceLocation, bool, bool) (/opt/compiler-explorer/clang-trunk/bin/clang+++0x5a42baf)
#&#8203;11 0x000055ebfb21316d clang::Parser::AnnotateTemplateIdTokenAsType(clang::CXXScopeSpec&, bool) (/opt/compiler-explorer/clang-trunk/bin/clang+++0x541316d)
#&#8203;12 0x000055ebfb17c3c2 clang::Parser::ParseDeclarationSpecifiers(clang::DeclSpec&, clang::Parser::ParsedTemplateInfo const&, clang::AccessSpecifier, clang::Parser::DeclSpecContext, clang::Parser::LateParsedAttrList*) (/opt/compiler-explorer/clang-trunk/bin/clang+++0x537c3c2)
#&#8203;13 0x000055ebfb1515af clang::Parser::ParseDeclOrFunctionDefInternal(clang::ParsedAttributesWithRange&, clang::ParsingDeclSpec&, clang::AccessSpecifier) (/opt/compiler-explorer/clang-trunk/bin/clang+++0x53515af)
#&#8203;14 0x000055ebfb151e31 clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributesWithRange&, clang::ParsingDeclSpec*, clang::AccessSpecifier) (.part.280) Parser.cpp:0:0
#&#8203;15 0x000055ebfb157d59 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributesWithRange&, clang::ParsingDeclSpec*) (/opt/compiler-explorer/clang-trunk/bin/clang+++0x5357d59)
#&#8203;16 0x000055ebfb159179 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, bool) (/opt/compiler-explorer/clang-trunk/bin/clang+++0x5359179)
#&#8203;17 0x000055ebfb14c9d9 clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-trunk/bin/clang+++0x534c9d9)
#&#8203;18 0x000055ebfa2fa762 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-trunk/bin/clang+++0x44fa762)
#&#8203;19 0x000055ebf9c985e1 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-trunk/bin/clang+++0x3e985e1)
#&#8203;20 0x000055ebf9c35942 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-trunk/bin/clang+++0x3e35942)
#&#8203;21 0x000055ebf9d658e3 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-trunk/bin/clang+++0x3f658e3)
#&#8203;22 0x000055ebf70cf6dc cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/compiler-explorer/clang-trunk/bin/clang+++0x12cf6dc)
#&#8203;23 0x000055ebf70cb75d ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) driver.cpp:0:0
#&#8203;24 0x000055ebf9add095 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#&#8203;25 0x000055ebf92d9053 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-trunk/bin/clang+++0x34d9053)
#&#8203;26 0x000055ebf9adf14e clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, bool*) const (/opt/compiler-explorer/clang-trunk/bin/clang+++0x3cdf14e)
#&#8203;27 0x000055ebf9ab4b7a clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&) const (/opt/compiler-explorer/clang-trunk/bin/clang+++0x3cb4b7a)
#&#8203;28 0x000055ebf9ab56bf clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*> >&) const (/opt/compiler-explorer/clang-trunk/bin/clang+++0x3cb56bf)
#&#8203;29 0x000055ebf9abeaf5 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*> >&) (/opt/compiler-explorer/clang-trunk/bin/clang+++0x3cbeaf5)
#&#8203;30 0x000055ebf6fdfb8e main (/opt/compiler-explorer/clang-trunk/bin/clang+++0x11dfb8e)
#&#8203;31 0x00007f02e1ec40b3 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b3)
#&#8203;32 0x000055ebf70cb2da _start (/opt/compiler-explorer/clang-trunk/bin/clang+++0x12cb2da)
clang-14: error: clang frontend command failed with exit code 139 (use -v to see invocation)
Compiler returned: 139
rjmccall commented 2 years ago

I think we need the temporary 12 year old hack fixed because otherwise we have no location information for the attribute. We can get "close enough" by using one of the nearby locations to solve the immediate crashing problem, but better to solve this properly by not stripping the attribute from the type source information.

Right. The proper fix there is to remove TransformType(QualType) so that we only ever transform a TSI, which of course requires all the call sites to move to TransformType(TSI), which requires them to preserve a TSI down.

AaronBallman commented 2 years ago

The issue is that we lose the attribute due to a "temporary" measure in template instantiation that was added in 2009.

https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/TreeTransform.h#L4623 is the problematic line. Calling getTrivialTypeSourceInfo() gets a TypeSourceInfo object that does not track the Attr * for the attributed type. So when we go to diagnose on https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/TreeTransform.h#L6785 the modifiedType is a null pointer.

https://github.com/llvm/llvm-project/commit/550e0c2f0fd655d6946a2e2b6dbbbf2c473a513c is what introduced the temporary hack.

I think we need the temporary 12 year old hack fixed because otherwise we have no location information for the attribute. We can get "close enough" by using one of the nearby locations to solve the immediate crashing problem, but better to solve this properly by not stripping the attribute from the type source information.