Skip to content

Commit 0ac1051

Browse files
author
git apple-llvm automerger
committed
Merge commit '6c474d2fcfa8' from apple/stable/20200714 into swift/main
2 parents f920543 + 6c474d2 commit 0ac1051

File tree

10 files changed

+126
-10
lines changed

10 files changed

+126
-10
lines changed

clang/lib/AST/ASTImporter.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,12 +1743,28 @@ ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
17431743
Decl *ImportedDecl = *ImportedOrErr;
17441744
FieldDecl *FieldTo = dyn_cast_or_null<FieldDecl>(ImportedDecl);
17451745
if (FieldFrom && FieldTo) {
1746-
const RecordType *RecordFrom = FieldFrom->getType()->getAs<RecordType>();
1747-
const RecordType *RecordTo = FieldTo->getType()->getAs<RecordType>();
1748-
if (RecordFrom && RecordTo) {
1749-
RecordDecl *FromRecordDecl = RecordFrom->getDecl();
1750-
RecordDecl *ToRecordDecl = RecordTo->getDecl();
1746+
RecordDecl *FromRecordDecl = nullptr;
1747+
RecordDecl *ToRecordDecl = nullptr;
1748+
// If we have a field that is an ArrayType we need to check if the array
1749+
// element is a RecordDecl and if so we need to import the defintion.
1750+
if (FieldFrom->getType()->isArrayType()) {
1751+
// getBaseElementTypeUnsafe(...) handles multi-dimensonal arrays for us.
1752+
FromRecordDecl = FieldFrom->getType()->getBaseElementTypeUnsafe()->getAsRecordDecl();
1753+
ToRecordDecl = FieldTo->getType()->getBaseElementTypeUnsafe()->getAsRecordDecl();
1754+
}
1755+
1756+
if (!FromRecordDecl || !ToRecordDecl) {
1757+
const RecordType *RecordFrom =
1758+
FieldFrom->getType()->getAs<RecordType>();
1759+
const RecordType *RecordTo = FieldTo->getType()->getAs<RecordType>();
1760+
1761+
if (RecordFrom && RecordTo) {
1762+
FromRecordDecl = RecordFrom->getDecl();
1763+
ToRecordDecl = RecordTo->getDecl();
1764+
}
1765+
}
17511766

1767+
if (FromRecordDecl && ToRecordDecl) {
17521768
if (FromRecordDecl->isCompleteDefinition() &&
17531769
!ToRecordDecl->isCompleteDefinition()) {
17541770
Error Err = ImportDefinition(FromRecordDecl, ToRecordDecl);

lldb/source/Commands/Options.td

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,8 @@ let Command = "breakpoint set" in {
214214
Desc<"Move breakpoints to nearest code. If not set the "
215215
"target.move-to-nearest-codesetting is used.">;
216216
def breakpoint_set_file_colon_line : Option<"joint-specifier", "y">, Group<12>, Arg<"FileLineColumn">,
217-
Required, Completion<"SourceFile">,
218-
Desc<"A specifier in the form filename:line[:column] for setting file & line breakpoints.">;
217+
Required, Completion<"SourceFile">,
218+
Desc<"A specifier in the form filename:line[:column] for setting file & line breakpoints.">;
219219
/* Don't add this option till it actually does something useful...
220220
def breakpoint_set_exception_typename : Option<"exception-typename", "O">,
221221
Arg<"TypeName">, Desc<"The breakpoint will only stop if an "
@@ -339,7 +339,7 @@ let Command = "disassemble" in {
339339
def disassemble_options_pc : Option<"pc", "p">, Group<5>,
340340
Desc<"Disassemble around the current pc.">;
341341
def disassemble_options_line : Option<"line", "l">, Group<6>,
342-
Desc<"Disassemble the current frame's current source line instructions if"
342+
Desc<"Disassemble the current frame's current source line instructions if "
343343
"there is debug line table information, else disassemble around the pc.">;
344344
def disassemble_options_address : Option<"address", "a">, Group<7>,
345345
Arg<"AddressOrExpression">,
@@ -774,7 +774,7 @@ let Command = "source list" in {
774774
def source_list_reverse : Option<"reverse", "r">, Group<4>, Desc<"Reverse the"
775775
" listing to look backwards from the last displayed block of source.">;
776776
def source_list_file_colon_line : Option<"joint-specifier", "y">, Group<5>,
777-
Arg<"FileLineColumn">, Completion<"SourceFile">,
777+
Arg<"FileLineColumn">, Completion<"SourceFile">,
778778
Desc<"A specifier in the form filename:line[:column] from which to display"
779779
" source.">;
780780
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CXX_SOURCES := main.cpp
2+
3+
include Makefile.rules
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import lldb
2+
from lldbsuite.test.decorators import *
3+
from lldbsuite.test.lldbtest import *
4+
from lldbsuite.test import lldbutil
5+
6+
class TestImportDefinitionArrayType(TestBase):
7+
8+
mydir = TestBase.compute_mydir(__file__)
9+
10+
def test(self):
11+
self.build()
12+
lldbutil.run_to_source_breakpoint(self, "// break here", lldb.SBFileSpec("main.cpp"))
13+
14+
self.expect_expr("__private->o", result_type="char", result_value="'A'")
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// This is a reproducer for a crash during codegen. The base issue is when we
2+
// Import the DeclContext we force FieldDecl that are RecordType to be defined
3+
// since we need these to be defined in order to layout the class.
4+
// This case involves an array member whose ElementType are records. In this
5+
// case we need to check the ElementType of an ArrayType and if it is a record
6+
// we need to import the definition.
7+
struct A {
8+
int x;
9+
};
10+
11+
struct B {
12+
// When we import the all the FieldDecl we need to check if we have an
13+
// ArrayType and then check if the ElementType is a RecordDecl and if so
14+
// import the defintion. Otherwise during codegen we will attempt to layout A
15+
// but won't be able to.
16+
A s1[2];
17+
A s2[2][2][3];
18+
char o;
19+
};
20+
21+
class FB {
22+
public:
23+
union {
24+
struct {
25+
unsigned char *_s;
26+
} t;
27+
char *tt[1];
28+
} U;
29+
30+
FB(B *p) : __private(p) {}
31+
32+
// We import A but we don't import the definition.
33+
void f(A **bounds) {}
34+
35+
void init();
36+
37+
private:
38+
B *__private;
39+
};
40+
41+
void FB::init() {
42+
return; // break here
43+
}
44+
45+
int main() {
46+
B b;
47+
FB fb(&b);
48+
49+
b.o = 'A';
50+
51+
fb.init();
52+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
$ cat private_extern.c
2+
__attribute__((visibility("hidden")))
3+
int* foo() {
4+
int i = 10;
5+
volatile int* j = &i;
6+
return j;
7+
}
8+
9+
int* bar() {
10+
return foo();
11+
}
12+
13+
$ cat main.c
14+
int* bar();
15+
int main() {
16+
return *bar();
17+
}
18+
19+
$ cat alias_list
20+
_foo _baz
21+
22+
$ xcrun --sdk iphoneos clang -g private_extern.c -c -o private_extern.o -target arm64-apple-ios14.0
23+
$ xcrun --sdk iphoneos clang -g main.c -c -o main.o -target arm64-apple-ios14.0
24+
$ xcrun --sdk iphoneos clang private_extern.o main.o -target arm64-apple-ios14.0 -o private_extern.out -Xlinker -alias_list -Xlinker alias_list
25+
26+
RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/private_extern/private_extern.out -o %t.dSYM --verbose 2>&1 | FileCheck %s
27+
CHECK-NOT: could not find object file symbol for symbol _baz
28+
CHECK: { sym: _foo, objAddr: 0x0000000000000000, binAddr: 0x0000000100007F58, size: 0x00000020 }
29+
CHECK: { sym: _baz, objAddr: 0x0000000000000000, binAddr: 0x0000000100007F58, size: 0x00000000 }
Binary file not shown.
Binary file not shown.
Binary file not shown.

llvm/tools/dsymutil/MachODebugMapParser.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,9 @@ void MachODebugMapParser::loadMainBinarySymbols(
562562
continue;
563563
}
564564
Section = *SectionOrErr;
565-
if (Section == MainBinary.section_end() || Section->isText())
565+
if ((Section == MainBinary.section_end() || Section->isText()) &&
566+
!(SymType &
567+
MachO::N_PEXT)) // Alias to non-external (was a private external)
566568
continue;
567569
uint64_t Addr = cantFail(Sym.getValue());
568570
Expected<StringRef> NameOrErr = Sym.getName();

0 commit comments

Comments
 (0)