[clang] 4136405 - [clang][Interp] Not all record bases are of RecordType

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Sun Feb 18 09:08:00 PST 2024


Author: Timm Bäder
Date: 2024-02-18T18:07:29+01:00
New Revision: 41364051ac9380a6b62f61c794fc5978b2e703c9

URL: https://github.com/llvm/llvm-project/commit/41364051ac9380a6b62f61c794fc5978b2e703c9
DIFF: https://github.com/llvm/llvm-project/commit/41364051ac9380a6b62f61c794fc5978b2e703c9.diff

LOG: [clang][Interp] Not all record bases are of RecordType

See the attached test case.

Added: 
    clang/test/AST/Interp/crash-GH49103-2.cpp

Modified: 
    clang/lib/AST/Interp/Program.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/Program.cpp b/clang/lib/AST/Interp/Program.cpp
index 964c0377c6dc1f..5624d5955c042c 100644
--- a/clang/lib/AST/Interp/Program.cpp
+++ b/clang/lib/AST/Interp/Program.cpp
@@ -247,7 +247,8 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
   unsigned VirtSize = 0;
 
   // Helper to get a base descriptor.
-  auto GetBaseDesc = [this](const RecordDecl *BD, Record *BR) -> Descriptor * {
+  auto GetBaseDesc = [this](const RecordDecl *BD,
+                            const Record *BR) -> Descriptor * {
     if (!BR)
       return nullptr;
     return allocateDescriptor(BD, BR, std::nullopt, /*isConst=*/false,
@@ -258,31 +259,39 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
   // Reserve space for base classes.
   Record::BaseList Bases;
   Record::VirtualBaseList VirtBases;
-  if (auto *CD = dyn_cast<CXXRecordDecl>(RD)) {
+  if (const auto *CD = dyn_cast<CXXRecordDecl>(RD)) {
+
     for (const CXXBaseSpecifier &Spec : CD->bases()) {
       if (Spec.isVirtual())
         continue;
 
-      const RecordDecl *BD = Spec.getType()->castAs<RecordType>()->getDecl();
-      Record *BR = getOrCreateRecord(BD);
-      if (Descriptor *Desc = GetBaseDesc(BD, BR)) {
-        BaseSize += align(sizeof(InlineDescriptor));
-        Bases.push_back({BD, BaseSize, Desc, BR});
-        BaseSize += align(BR->getSize());
-        continue;
+      // In error cases, the base might not be a RecordType.
+      if (const auto *RT = Spec.getType()->getAs<RecordType>()) {
+        const RecordDecl *BD = RT->getDecl();
+
+        Record *BR = getOrCreateRecord(BD);
+        if (Descriptor *Desc = GetBaseDesc(BD, BR)) {
+          BaseSize += align(sizeof(InlineDescriptor));
+          Bases.push_back({BD, BaseSize, Desc, BR});
+          BaseSize += align(BR->getSize());
+          continue;
+        }
       }
       return nullptr;
     }
 
     for (const CXXBaseSpecifier &Spec : CD->vbases()) {
-      const RecordDecl *BD = Spec.getType()->castAs<RecordType>()->getDecl();
-      Record *BR = getOrCreateRecord(BD);
 
-      if (Descriptor *Desc = GetBaseDesc(BD, BR)) {
-        VirtSize += align(sizeof(InlineDescriptor));
-        VirtBases.push_back({BD, VirtSize, Desc, BR});
-        VirtSize += align(BR->getSize());
-        continue;
+      if (const auto *RT = Spec.getType()->getAs<RecordType>()) {
+        const RecordDecl *BD = RT->getDecl();
+        Record *BR = getOrCreateRecord(BD);
+
+        if (Descriptor *Desc = GetBaseDesc(BD, BR)) {
+          VirtSize += align(sizeof(InlineDescriptor));
+          VirtBases.push_back({BD, VirtSize, Desc, BR});
+          VirtSize += align(BR->getSize());
+          continue;
+        }
       }
       return nullptr;
     }

diff  --git a/clang/test/AST/Interp/crash-GH49103-2.cpp b/clang/test/AST/Interp/crash-GH49103-2.cpp
new file mode 100644
index 00000000000000..82d78e2aeab0cc
--- /dev/null
+++ b/clang/test/AST/Interp/crash-GH49103-2.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -verify -std=c++98 %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -verify -std=c++11 %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -verify -std=c++14 %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -verify -std=c++17 %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -verify -std=c++20 %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -verify -std=c++23 %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -verify -std=c++2c %s -fexperimental-new-constant-interpreter
+
+// https://github.com/llvm/llvm-project/issues/49103
+
+template<class> struct A; // expected-note 0+ {{}}
+struct S : __make_integer_seq<A, int, 42> { }; // expected-error 0+ {{}}
+S s;


        


More information about the cfe-commits mailing list