<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/83671>83671</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[Clang] 19.0.0 SIGSEGV due to NULL Pointer dereference caused by receiving an NULL `BaseDecl` at EmptySubobjectMap::ComputeEmptySubobjectSizes()
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
bjrjk
</td>
</tr>
</table>
<pre>
Note: This is related to dump record layout feature with option `-Xclang -fdump-record-layouts-complete`.
When I want to use that option to dump `class` and `struct`'s layout, the clang crashes with SIGSEGV signal.
Crashsite Screenshot:
![crashsite](https://github.com/llvm/llvm-project/assets/6657270/7a8a9354-e84c-4f73-82f6-4657852b89bd)
Through my simple debugging, I found the problem might related to `EmptySubobjectMap::ComputeEmptySubobjectSizes()` in `clang/lib/AST/RecordLayoutBuilder.cpp`.
```cpp
void EmptySubobjectMap::ComputeEmptySubobjectSizes() {
// Check the bases.
for (const CXXBaseSpecifier &Base : Class->bases()) {
const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); // [!]
CharUnits EmptySize;
const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl); // [1]
if (BaseDecl->isEmpty()) {
// If the class decl is empty, get its size.
EmptySize = Layout.getSize();
} else {
// Otherwise, we get the largest empty subobject for the decl.
EmptySize = Layout.getSizeOfLargestEmptySubobject();
}
if (EmptySize > SizeOfLargestEmptySubobject)
SizeOfLargestEmptySubobject = EmptySize;
}
// Check the fields.
for (const FieldDecl *FD : Class->fields()) {
const RecordType *RT =
Context.getBaseElementType(FD->getType())->getAs<RecordType>();
// We only care about record types.
if (!RT)
continue;
CharUnits EmptySize;
const CXXRecordDecl *MemberDecl = RT->getAsCXXRecordDecl();
const ASTRecordLayout &Layout = Context.getASTRecordLayout(MemberDecl);
if (MemberDecl->isEmpty()) {
// If the class decl is empty, get its size.
EmptySize = Layout.getSize();
} else {
// Otherwise, we get the largest empty subobject for the decl.
EmptySize = Layout.getSizeOfLargestEmptySubobject();
}
if (EmptySize > SizeOfLargestEmptySubobject)
SizeOfLargestEmptySubobject = EmptySize;
}
}
```
At position `[!]`, `Base.getType()->getAsCXXRecordDecl()` will return a NULL pointer then causes crash in `Context.getASTRecordLayout(BaseDecl)` at position `[1]`.
Nullptr Introduce Site Screenshot:
![nullptr-introduce](https://github.com/llvm/llvm-project/assets/6657270/662d7379-819c-405d-978b-e68dc8f9a266)
This is crash site, including the crash backtrace, preprocessed source, and associated run script.
[crashsite.zip](https://github.com/llvm/llvm-project/files/14469084/crashsite.zip)
Thanks!
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsV8tu2zgXfhp6cyBDomRJXnjh2HERIG1_xO7fbinqyGJDiwJJNeM8_YCiFF-Sdtqiq8EEQSLpXPidG_mRGSP2DeKCzG7IbD1hna2VXhRf9dfHSaHK4-KDskjiJexqYUAY0CiZxRKsgrI7tKCRK12CZEfVWaiQ2U4jPAlbg2qtUA2QNAy-cMmaPQSVswm8TeBtTMDVoZVokaThlIRrEi793881NnAHT6yxbrnOINia2dHviICkIZfMGJKGwJrSvRurO25JGhKamQEboSuwNYJHwjUzNRoPdHv3bnv77v_gcsHkBYaV0zPCImy5RmxMrSyJByGhEZnd8FGFzNaE5rW1rXEqdEPoZi9s3RVTrg6EbqT8Nv4LWq2-IreEbpgxaA2hmzSdZTQLCd1kLGfzeJYEmCc8SKosDnJapUGSzrJ8Rot8XpSEzs-B7mqtun0NhyMY4fIJJRbdfi-avYv8DirVNWWfgVarQuIBDmJf2_OCkjS8PbT2uO0KVTh071nrIomXK3VoO4uX0q14RkNo7pCkIYhmKIVbcSNFQehmud0Runno633fl-GmE7JEPeVte11vV6_-18n6L9-UKOE3IQHJbrwXAF8LWNXIH_sUFMygmY7iSmkgNOeqMRZWX77cMIPbFrmoBDpJ6j6Am4KVa7SAxLe9gyH2i7VenPig18glELp0HvxzvAb3Mt2j3R1b9D6cyz3apbkwHPzHN2MAbkpdz63P0wYAsKqZ_tQIa4ZsiWck8c1J7lEtt7vzUrjIxqd4DSvVWPzLOmBXioTmI_5XeE5o3DqigjNlF5UwPaK3UtX_DJ7uqnE4jYHSJUoYQG-5gj1acMEZ8YzTc-uXaPsIPFoXQJ-AMXsnA5KtAaWr5ZsgPtoa9ZMw6NZ8wn5Zh0oyvUdjPR4wY7P1fePkDu9Pw_pY3Xt3l537NtrrOvv8nru_hR86nZ_D-oFmD_St3nkF4tUsVQJl-Z1h2jjZOAOb9eUMecPvdIa3913o5sQ5eNg5mIPOWbu6fruVeMBmHKnNepio04idTxmJVyfPJL69Sv5ZCXywnxFUI4_AmUZghZuY4dyzx_ZsIxkLRGj0sLtKPleNFU2H16v83Oi-2lDe46FA_bKlPOz-YQv5g3vBaelr1z76k_y_DeDftAG8PIzn9Dm4pYVWGTEyvtNJ5UjYyn36xVMvDeFJSAkabacbYPDh0_09tEo0FvusN8BZZ9B4LjfQj58-xBxZfAV5AHzBSj50UrZWw11jtSo7jrD9IR1svH4gRv0_RwvTlJZZnM2DPJrzIAlnZTDP8iLANC95Xs0ZTdNXtNDTdp-jnqXSFYiGy64Uzd7PXC8rGH-0mvFeodXYasXRGCzBqE77z45eM2MUFz1l1F0DhmvR2jFjZ2x4-iza3wy9EtKRq02UJOk8zBNCN5dur2NkzaMhNJqUi7icx3M2wUWUhfM4mydpNKkXOUZpWpVRSjOMacKSiMVVGGdZFGMe8nQiFjSkSRiHNIriLImmeZyHPIniWZXSrIpDkoR4YEJOHdSp0vuJMKbDRR6nWTSRrEBp-ksUpQMDpu4-pRd9aEW3NyQJpTDWnDxYYWV_81r1FrM1RPNpOA1f7iNlh46W943_v6HxS9RYocaGo-__EoqjO41QfHMFZY3XHwaub3ff67_JoyedlotfLmGfHVfDPkF_BwAA___ZMGdf">