llvm-project/lldb/test/Shell/SymbolFile/DWARF/objcxx-forward-decls.test
Michael Buch a862225813
[lldb][DWARFASTParserClang] Don't complete conflicting Objective-C++ types (#156681)
This upstreams https://github.com/swiftlang/llvm-project/pull/10313.

If we detect a situation where a forward declaration is C++ and the
definition DIE is Objective-C, then just don't try to complete the type
(it would crash otherwise). In the long term we might want to add
support for completing such types.

We've seen real world crashes when debugging WebKit and wxWidgets
because of this. Both projects forward declare ObjC++ decls in the way
shown in the test.

rdar://145959981
2025-09-03 20:04:53 +01:00

71 lines
1.7 KiB
Plaintext

# REQUIRES: system-darwin
# In this test we have two CUs with conflicting forward declaration
# depending on the CU language (one is C++ and the other is Objective-C++).
# We are then stopped in the C++ CU and try to print the type, at which
# point LLDB will try to make it into an Clang AST node. If LLDB were to
# interpret the type as C++ instead of Objective-C, we'd violate Clang
# invariants and crash.
#
# RUN: split-file %s %t
# RUN: %clangxx_host -c -g -x objective-c++ %t/request.m -o %t/request_objc.o
# RUN: %clangxx_host -c -g %t/main.cpp -o %t/main.o
# RUN: %clangxx_host %t/main.o %t/request_objc.o -framework Foundation -o %t/a.out
#
# RUN: %lldb %t/a.out \
# RUN: -o "breakpoint set -p return -X main" \
# RUN: -o run \
# RUN: -o "frame variable r" \
# RUN: -o exit | FileCheck %s
#
# RUN: dsymutil %t/a.out
#
# RUN: %lldb %t/a.out \
# RUN: -o "breakpoint set -p return -X main" \
# RUN: -o run \
# RUN: -o "frame variable r" \
# RUN: -o exit | FileCheck %s --check-prefix=CHECK-DSYM
# CHECK: (lldb) frame variable r
# CHECK-NEXT: (Request) ::r = (m_request = "Hello, World!")
# CHECK-DSYM: (lldb) frame variable r
# CHECK-DSYM-NEXT: (Request) ::r = (m_request = "Hello, World!")
#--- lib.h
#ifndef LIB_H_IN
#define LIB_H_IN
#ifdef __OBJC__
@class NSString;
#else
class NSString;
#endif
struct Request {
NSString * m_request = nullptr;
};
#endif // _H_IN
#--- main.cpp
#include "lib.h"
void process(Request *);
Request r;
int main() {
process(&r);
return 0;
}
#--- request.m
#import <Foundation/Foundation.h>
#include "lib.h"
void process(Request * r) {
r->m_request = @"Hello, World!";
}