Skip to content

[lldb] Initial value of static member is misinterpreted as DWARF opcodes #146

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

Closed
vangelists opened this issue Feb 22, 2020 · 2 comments
Closed
Assignees
Labels

Comments

@vangelists
Copy link

vangelists commented Feb 22, 2020

When debugging the following program in LLDB (both 106ae10 and Apple's lldb-1100.0.30.12):

void foo() {}

struct X {
    X() {
        static_member;
        foo();
    }
    static inline auto static_member = 0xBEEF;
};

int main() {
    X x;
    return 0;
}

At DWARFExpression::Evaluate() in DWARFExpression.cpp (line 943):

const uint8_t op = opcodes.GetU8(&offset);

The initial value of the static member from the DWARF (0xBEEF) is being misinterpreted as opcodes (0xEF, 0xBE, 0x00, 0x00) and thus the evaluation has unexpected results.

This problem seems to only arise when Variable::m_scope is eValueTypeVariableGlobal and Variable::m_static_member is true, but I didn't have time to dig deeper and verify this claim.


This issue leads to undefined behavior (as expected), e.g. when stopped into foo() and static_member has a value that translates "nicely" to opcodes, LLDB can find static_member without qualification and incorrectly read some value.

For example (static_member == 50):

(lldb) b foo
(lldb) r
(lldb) p static_member
(int) $0 = 2
(lldb) p X::static_member
(int) $1 = 50

However (static_member == 0xBEEF):

(lldb) b foo
(lldb) r
(lldb) p static_member
error: Couldn't materialize: couldn't get the value of variable X::static_member: Stack empty after evaluation.
error: errored out in DoExecute, couldn't PrepareToExecuteJITExpression
(lldb) p/x X::static_member
(int) $1 = 0xbeef

Also, removing any reference to static_member from the constructor (static_member == 50):

(lldb) b foo
(lldb) r
(lldb) p static_member
error: <user expression 0>:1:1: use of undeclared identifier 'static_member'
static_member
^
(lldb) p X::static_member
=================================================================
==84957==ERROR: AddressSanitizer: use-after-poison on address 0x621000e84500 at pc 0x0001152b2202 bp 0x7ffee95daa70 sp 0x7ffee95daa68
WRITE of size 8 at 0x621000e84500 thread T0
    #0 0x1152b2201 in llvm::itanium_demangle::Node::Node(llvm::itanium_demangle::Node::Kind, llvm::itanium_demangle::Node::Cache, llvm::itanium_demangle::Node::Cache, llvm::itanium_demangle::Node::Cache) ItaniumDemangle.h:146
    #1 0x1152bf959 in llvm::itanium_demangle::NameType::NameType(llvm::itanium_demangle::StringView) ItaniumDemangle.h:388
    #2 0x1152bf6f1 in llvm::itanium_demangle::NameType::NameType(llvm::itanium_demangle::StringView) ItaniumDemangle.h:388
    #3 0x115306503 in llvm::itanium_demangle::NameType* (anonymous namespace)::NodeAllocator::makeNode<llvm::itanium_demangle::NameType, llvm::itanium_demangle::StringView&>(llvm::itanium_demangle::StringView&) CPlusPlusLanguage.cpp:280
    #4 0x1152f97c6 in llvm::itanium_demangle::Node* llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::make<llvm::itanium_demangle::NameType, llvm::itanium_demangle::StringView&>(llvm::itanium_demangle::StringView&) ItaniumDemangle.h:2367
    #5 0x115327568 in llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::parseSourceName(llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::NameState*) ItaniumDemangle.h:2727
    #6 0x1152be8ae in llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::parseUnqualifiedName(llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::NameState*) ItaniumDemangle.h:2614
    #7 0x1152b8241 in llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::parseNestedName(llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::NameState*) ItaniumDemangle.h:3185
    #8 0x1152acdff in llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::parseName(llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::NameState*) ItaniumDemangle.h:2516
    #9 0x1152a8422 in llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::parseEncoding() ItaniumDemangle.h:5097
    #10 0x1152a616b in llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::parse() ItaniumDemangle.h:5505
    #11 0x1152a3f97 in (anonymous namespace)::ManglingSubstitutor<(anonymous namespace)::TypeSubstitutor>::substituteImpl(llvm::StringRef) CPlusPlusLanguage.cpp:316
    #12 0x1152993be in lldb_private::ConstString (anonymous namespace)::ManglingSubstitutor<(anonymous namespace)::TypeSubstitutor>::substitute<char const (&) [2], char const (&) [2]>(llvm::StringRef, char const (&) [2], char const (&) [2]) CPlusPlusLanguage.cpp:302
    #13 0x1152980ba in lldb_private::CPlusPlusLanguage::FindAlternateFunctionManglings(lldb_private::ConstString, std::__1::set<lldb_private::ConstString, std::__1::less<lldb_private::ConstString>, std::__1::allocator<lldb_private::ConstString> >&) CPlusPlusLanguage.cpp:430
    #14 0x11385998b in lldb_private::IRExecutionUnit::CollectCandidateCPlusPlusNames(std::__1::vector<lldb_private::IRExecutionUnit::SearchSpec, std::__1::allocator<lldb_private::IRExecutionUnit::SearchSpec> >&, std::__1::vector<lldb_private::IRExecutionUnit::SearchSpec, std::__1::allocator<lldb_private::IRExecutionUnit::SearchSpec> > const&, lldb_private::SymbolContext const&) IRExecutionUnit.cpp:730
    #15 0x113860dc1 in lldb_private::IRExecutionUnit::FindSymbol(lldb_private::ConstString, bool&) IRExecutionUnit.cpp:956
    #16 0x113864b28 in lldb_private::IRExecutionUnit::MemoryManager::GetSymbolAddressAndPresence(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool&) IRExecutionUnit.cpp:1044
    #17 0x1138644c6 in lldb_private::IRExecutionUnit::MemoryManager::findSymbol(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) IRExecutionUnit.cpp:1022
    #18 0x113865202 in non-virtual thunk to lldb_private::IRExecutionUnit::MemoryManager::findSymbol(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) IRExecutionUnit.cpp
    #19 0x118875c3a in llvm::LinkingSymbolResolver::findSymbol(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) MCJIT.cpp:676
    #20 0x11888033a in llvm::LegacyJITSymbolResolver::lookup(std::__1::set<llvm::StringRef, std::__1::less<llvm::StringRef>, std::__1::allocator<llvm::StringRef> > const&, llvm::unique_function<void (llvm::Expected<std::__1::map<llvm::StringRef, llvm::JITEvaluatedSymbol, std::__1::less<llvm::StringRef>, std::__1::allocator<std::__1::pair<llvm::StringRef const, llvm::JITEvaluatedSymbol> > > >)>) JITSymbol.cpp:87
    #21 0x1188821e0 in llvm::RuntimeDyldImpl::resolveExternalSymbols() RuntimeDyld.cpp:1165
    #22 0x118881889 in llvm::RuntimeDyldImpl::resolveRelocations() RuntimeDyld.cpp:131
    #23 0x1188736ed in llvm::MCJIT::finalizeObject() MCJIT.cpp:240
    #24 0x11384e307 in lldb_private::IRExecutionUnit::ReportAllocations(llvm::ExecutionEngine&) IRExecutionUnit.cpp:1191
    #25 0x113846a89 in lldb_private::IRExecutionUnit::GetRunnableInfo(lldb_private::Status&, unsigned long long&, unsigned long long&) IRExecutionUnit.cpp:355
    #26 0x118144122 in lldb_private::ClangExpressionParser::PrepareForExecution(unsigned long long&, unsigned long long&, std::__1::shared_ptr<lldb_private::IRExecutionUnit>&, lldb_private::ExecutionContext&, bool&, lldb_private::ExecutionPolicy) ClangExpressionParser.cpp:1337
    #27 0x118287aa9 in lldb_private::ClangUserExpression::Parse(lldb_private::DiagnosticManager&, lldb_private::ExecutionContext&, lldb_private::ExecutionPolicy, bool, bool) ClangUserExpression.cpp:639
    #28 0x11397394f in lldb_private::UserExpression::Evaluate(lldb_private::ExecutionContext&, lldb_private::EvaluateExpressionOptions const&, llvm::StringRef, llvm::StringRef, std::__1::shared_ptr<lldb_private::ValueObject>&, lldb_private::Status&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, lldb_private::ValueObject*) UserExpression.cpp:251
    #29 0x114781719 in lldb_private::Target::EvaluateExpression(llvm::StringRef, lldb_private::ExecutionContextScope*, std::__1::shared_ptr<lldb_private::ValueObject>&, lldb_private::EvaluateExpressionOptions const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, lldb_private::ValueObject*) Target.cpp:2369
    #30 0x117898e81 in lldb_private::CommandObjectExpression::EvaluateExpression(llvm::StringRef, lldb_private::Stream*, lldb_private::Stream*, lldb_private::CommandReturnObject*) CommandObjectExpression.cpp:419
    #31 0x11789dc37 in lldb_private::CommandObjectExpression::DoExecute(llvm::StringRef, lldb_private::CommandReturnObject&) CommandObjectExpression.cpp:649
    #32 0x113cec858 in lldb_private::CommandObjectRaw::Execute(char const*, lldb_private::CommandReturnObject&) CommandObject.cpp:1012
    #33 0x113c343d6 in lldb_private::CommandInterpreter::HandleCommand(char const*, lldb_private::LazyBool, lldb_private::CommandReturnObject&, lldb_private::ExecutionContext*, bool, bool) CommandInterpreter.cpp:1915
    #34 0x113c4939e in lldb_private::CommandInterpreter::IOHandlerInputComplete(lldb_private::IOHandler&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) CommandInterpreter.cpp:2913
    #35 0x11320c7eb in lldb_private::IOHandlerEditline::Run() IOHandler.cpp:549
    #36 0x11306af0b in lldb_private::Debugger::RunIOHandlers() Debugger.cpp:903
    #37 0x113c4e5c1 in lldb_private::CommandInterpreter::RunCommandInterpreter(bool, bool, lldb_private::CommandInterpreterRunOptions&) CommandInterpreter.cpp:3099
    #38 0x111a2496a in lldb::SBDebugger::RunCommandInterpreter(bool, bool) SBDebugger.cpp:1169
    #39 0x106629f9e in Driver::MainLoop() Driver.cpp:675
    #40 0x10662ee9b in main Driver.cpp:898
    #41 0x7fff6640b7fc in start (libdyld.dylib:x86_64+0x1a7fc)

0x621000e84500 is located 0 bytes inside of 4096-byte region [0x621000e84500,0x621000e85500)
allocated by thread T0 here:
    #0 0x1067b4793 in wrap_malloc (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x61793)
    #1 0x117122071 in llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, 4096ul, 4096ul, 128ul>::StartNewSlab() MemAlloc.h:26
    #2 0x117121fdc in llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, 4096ul, 4096ul, 128ul>::Allocate(unsigned long, llvm::Align) Allocator.h:188
    #3 0x114c67381 in llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, 4096ul, 4096ul, 128ul>::Allocate(unsigned long, unsigned long) Allocator.h:202
    #4 0x1153063ed in llvm::itanium_demangle::NameType* (anonymous namespace)::NodeAllocator::makeNode<llvm::itanium_demangle::NameType, llvm::itanium_demangle::StringView&>(llvm::itanium_demangle::StringView&) CPlusPlusLanguage.cpp:279
    #5 0x1152f97c6 in llvm::itanium_demangle::Node* llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::make<llvm::itanium_demangle::NameType, llvm::itanium_demangle::StringView&>(llvm::itanium_demangle::StringView&) ItaniumDemangle.h:2367
    #6 0x115327568 in llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::parseSourceName(llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::NameState*) ItaniumDemangle.h:2727
    #7 0x1152be8ae in llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::parseUnqualifiedName(llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::NameState*) ItaniumDemangle.h:2614
    #8 0x1152b8241 in llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::parseNestedName(llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::NameState*) ItaniumDemangle.h:3185
    #9 0x1152acdff in llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::parseName(llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::NameState*) ItaniumDemangle.h:2516
    #10 0x1152a8422 in llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::parseEncoding() ItaniumDemangle.h:5097
    #11 0x1152a616b in llvm::itanium_demangle::AbstractManglingParser<(anonymous namespace)::TypeSubstitutor, (anonymous namespace)::NodeAllocator>::parse() ItaniumDemangle.h:5505
    #12 0x1152a3f97 in (anonymous namespace)::ManglingSubstitutor<(anonymous namespace)::TypeSubstitutor>::substituteImpl(llvm::StringRef) CPlusPlusLanguage.cpp:316
    #13 0x1152993be in lldb_private::ConstString (anonymous namespace)::ManglingSubstitutor<(anonymous namespace)::TypeSubstitutor>::substitute<char const (&) [2], char const (&) [2]>(llvm::StringRef, char const (&) [2], char const (&) [2]) CPlusPlusLanguage.cpp:302
    #14 0x115297dec in lldb_private::CPlusPlusLanguage::FindAlternateFunctionManglings(lldb_private::ConstString, std::__1::set<lldb_private::ConstString, std::__1::less<lldb_private::ConstString>, std::__1::allocator<lldb_private::ConstString> >&) CPlusPlusLanguage.cpp:425
    #15 0x11385998b in lldb_private::IRExecutionUnit::CollectCandidateCPlusPlusNames(std::__1::vector<lldb_private::IRExecutionUnit::SearchSpec, std::__1::allocator<lldb_private::IRExecutionUnit::SearchSpec> >&, std::__1::vector<lldb_private::IRExecutionUnit::SearchSpec, std::__1::allocator<lldb_private::IRExecutionUnit::SearchSpec> > const&, lldb_private::SymbolContext const&) IRExecutionUnit.cpp:730
    #16 0x113860dc1 in lldb_private::IRExecutionUnit::FindSymbol(lldb_private::ConstString, bool&) IRExecutionUnit.cpp:956
    #17 0x113864b28 in lldb_private::IRExecutionUnit::MemoryManager::GetSymbolAddressAndPresence(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool&) IRExecutionUnit.cpp:1044
    #18 0x1138644c6 in lldb_private::IRExecutionUnit::MemoryManager::findSymbol(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) IRExecutionUnit.cpp:1022
    #19 0x113865202 in non-virtual thunk to lldb_private::IRExecutionUnit::MemoryManager::findSymbol(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) IRExecutionUnit.cpp
    #20 0x118875c3a in llvm::LinkingSymbolResolver::findSymbol(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) MCJIT.cpp:676
    #21 0x11888033a in llvm::LegacyJITSymbolResolver::lookup(std::__1::set<llvm::StringRef, std::__1::less<llvm::StringRef>, std::__1::allocator<llvm::StringRef> > const&, llvm::unique_function<void (llvm::Expected<std::__1::map<llvm::StringRef, llvm::JITEvaluatedSymbol, std::__1::less<llvm::StringRef>, std::__1::allocator<std::__1::pair<llvm::StringRef const, llvm::JITEvaluatedSymbol> > > >)>) JITSymbol.cpp:87
    #22 0x1188821e0 in llvm::RuntimeDyldImpl::resolveExternalSymbols() RuntimeDyld.cpp:1165
    #23 0x118881889 in llvm::RuntimeDyldImpl::resolveRelocations() RuntimeDyld.cpp:131
    #24 0x1188736ed in llvm::MCJIT::finalizeObject() MCJIT.cpp:240
    #25 0x11384e307 in lldb_private::IRExecutionUnit::ReportAllocations(llvm::ExecutionEngine&) IRExecutionUnit.cpp:1191
    #26 0x113846a89 in lldb_private::IRExecutionUnit::GetRunnableInfo(lldb_private::Status&, unsigned long long&, unsigned long long&) IRExecutionUnit.cpp:355
    #27 0x118144122 in lldb_private::ClangExpressionParser::PrepareForExecution(unsigned long long&, unsigned long long&, std::__1::shared_ptr<lldb_private::IRExecutionUnit>&, lldb_private::ExecutionContext&, bool&, lldb_private::ExecutionPolicy) ClangExpressionParser.cpp:1337
    #28 0x118287aa9 in lldb_private::ClangUserExpression::Parse(lldb_private::DiagnosticManager&, lldb_private::ExecutionContext&, lldb_private::ExecutionPolicy, bool, bool) ClangUserExpression.cpp:639
    #29 0x11397394f in lldb_private::UserExpression::Evaluate(lldb_private::ExecutionContext&, lldb_private::EvaluateExpressionOptions const&, llvm::StringRef, llvm::StringRef, std::__1::shared_ptr<lldb_private::ValueObject>&, lldb_private::Status&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, lldb_private::ValueObject*) UserExpression.cpp:251

SUMMARY: AddressSanitizer: use-after-poison ItaniumDemangle.h:146 in llvm::itanium_demangle::Node::Node(llvm::itanium_demangle::Node::Kind, llvm::itanium_demangle::Node::Cache, llvm::itanium_demangle::Node::Cache, llvm::itanium_demangle::Node::Cache)
Shadow bytes around the buggy address:
  0x1c42001d0850: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x1c42001d0860: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c42001d0870: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c42001d0880: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c42001d0890: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x1c42001d08a0:[f7]f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
  0x1c42001d08b0: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
  0x1c42001d08c0: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
  0x1c42001d08d0: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
  0x1c42001d08e0: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
  0x1c42001d08f0: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==84957==ABORTING

Backtrace:

#0  DWARFExpression::Evaluate(ExecutionContext*, RegisterContext*, std::__1::shared_ptr<Module>, DataExtractor const&, DWARFUnit const*, lldb::RegisterKind, Value const*, Value const*, Value&, Status*)
#1  DWARFExpression::Evaluate(ExecutionContext*, RegisterContext*, unsigned long long, Value const*, Value const*, Value&, Status*) const
#2  ValueObjectVariable::UpdateValue()
#3  ValueObject::UpdateValueIfNeeded(bool)
#4  ValueObject::GetData(DataExtractor&, Status&)

DWARF entry for static_member:

0x00000046:     DW_TAG_member
                  DW_AT_name	("static_member")
                  DW_AT_type	(0x0000000000000060 "int")
                  DW_AT_decl_file	("<redacted>/static_member.cpp")
                  DW_AT_decl_line	(8)
                  DW_AT_external	(true)
                  DW_AT_declaration	(true)
                  DW_AT_const_value	(48879) // 0xBEEF
@llvmbot
Copy link
Member

llvmbot commented Apr 12, 2022

@llvm/issue-subscribers-lldb

@labath
Copy link
Collaborator

labath commented Apr 12, 2022

The issue appears to be resolved now (I haven't used the exact clang version, but I've checked that the produced debug info is identical to that in the bug report.

@labath labath closed this as completed Apr 12, 2022
mjklemm pushed a commit to mjklemm/llvm-project that referenced this issue Aug 19, 2024
…vice (llvm#146)

Extends ROCm#112.

This PR extends support for `do concurrent` mapping to the device a bit
more. In particular, it handles localization of loop-local values on the
deive. Previously, this was only supported and tested on the host.

See docs for `looputils::collectLoopLocalValues` for the definition of
"loop-local" values.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants