Skip to content

Commit 4136405

Browse files
committed
[clang][Interp] Not all record bases are of RecordType
See the attached test case.
1 parent 54daf6a commit 4136405

File tree

2 files changed

+38
-16
lines changed

2 files changed

+38
-16
lines changed

clang/lib/AST/Interp/Program.cpp

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,8 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
247247
unsigned VirtSize = 0;
248248

249249
// Helper to get a base descriptor.
250-
auto GetBaseDesc = [this](const RecordDecl *BD, Record *BR) -> Descriptor * {
250+
auto GetBaseDesc = [this](const RecordDecl *BD,
251+
const Record *BR) -> Descriptor * {
251252
if (!BR)
252253
return nullptr;
253254
return allocateDescriptor(BD, BR, std::nullopt, /*isConst=*/false,
@@ -258,31 +259,39 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
258259
// Reserve space for base classes.
259260
Record::BaseList Bases;
260261
Record::VirtualBaseList VirtBases;
261-
if (auto *CD = dyn_cast<CXXRecordDecl>(RD)) {
262+
if (const auto *CD = dyn_cast<CXXRecordDecl>(RD)) {
263+
262264
for (const CXXBaseSpecifier &Spec : CD->bases()) {
263265
if (Spec.isVirtual())
264266
continue;
265267

266-
const RecordDecl *BD = Spec.getType()->castAs<RecordType>()->getDecl();
267-
Record *BR = getOrCreateRecord(BD);
268-
if (Descriptor *Desc = GetBaseDesc(BD, BR)) {
269-
BaseSize += align(sizeof(InlineDescriptor));
270-
Bases.push_back({BD, BaseSize, Desc, BR});
271-
BaseSize += align(BR->getSize());
272-
continue;
268+
// In error cases, the base might not be a RecordType.
269+
if (const auto *RT = Spec.getType()->getAs<RecordType>()) {
270+
const RecordDecl *BD = RT->getDecl();
271+
272+
Record *BR = getOrCreateRecord(BD);
273+
if (Descriptor *Desc = GetBaseDesc(BD, BR)) {
274+
BaseSize += align(sizeof(InlineDescriptor));
275+
Bases.push_back({BD, BaseSize, Desc, BR});
276+
BaseSize += align(BR->getSize());
277+
continue;
278+
}
273279
}
274280
return nullptr;
275281
}
276282

277283
for (const CXXBaseSpecifier &Spec : CD->vbases()) {
278-
const RecordDecl *BD = Spec.getType()->castAs<RecordType>()->getDecl();
279-
Record *BR = getOrCreateRecord(BD);
280284

281-
if (Descriptor *Desc = GetBaseDesc(BD, BR)) {
282-
VirtSize += align(sizeof(InlineDescriptor));
283-
VirtBases.push_back({BD, VirtSize, Desc, BR});
284-
VirtSize += align(BR->getSize());
285-
continue;
285+
if (const auto *RT = Spec.getType()->getAs<RecordType>()) {
286+
const RecordDecl *BD = RT->getDecl();
287+
Record *BR = getOrCreateRecord(BD);
288+
289+
if (Descriptor *Desc = GetBaseDesc(BD, BR)) {
290+
VirtSize += align(sizeof(InlineDescriptor));
291+
VirtBases.push_back({BD, VirtSize, Desc, BR});
292+
VirtSize += align(BR->getSize());
293+
continue;
294+
}
286295
}
287296
return nullptr;
288297
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %clang_cc1 -verify -std=c++98 %s -fexperimental-new-constant-interpreter
2+
// RUN: %clang_cc1 -verify -std=c++11 %s -fexperimental-new-constant-interpreter
3+
// RUN: %clang_cc1 -verify -std=c++14 %s -fexperimental-new-constant-interpreter
4+
// RUN: %clang_cc1 -verify -std=c++17 %s -fexperimental-new-constant-interpreter
5+
// RUN: %clang_cc1 -verify -std=c++20 %s -fexperimental-new-constant-interpreter
6+
// RUN: %clang_cc1 -verify -std=c++23 %s -fexperimental-new-constant-interpreter
7+
// RUN: %clang_cc1 -verify -std=c++2c %s -fexperimental-new-constant-interpreter
8+
9+
// https://github.com/llvm/llvm-project/issues/49103
10+
11+
template<class> struct A; // expected-note 0+ {{}}
12+
struct S : __make_integer_seq<A, int, 42> { }; // expected-error 0+ {{}}
13+
S s;

0 commit comments

Comments
 (0)