[PATCH] D136831: [clang][Interp] Protect Record creation against infinite recusion
Timm Bäder via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 27 03:09:07 PDT 2022
tbaeder created this revision.
tbaeder added reviewers: aaron.ballman, erichkeane, tahonermann, shafik.
Herald added a project: All.
tbaeder requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
This only happens in error cases as far as I know, e.g. the attached test case.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D136831
Files:
clang/lib/AST/Interp/ByteCodeStmtGen.cpp
clang/lib/AST/Interp/Program.cpp
clang/lib/AST/Interp/Program.h
clang/test/AST/Interp/records.cpp
Index: clang/test/AST/Interp/records.cpp
===================================================================
--- clang/test/AST/Interp/records.cpp
+++ clang/test/AST/Interp/records.cpp
@@ -133,6 +133,19 @@
constexpr C RVOAndParamsResult = RVOAndParams(&c);
#endif
+class Bar { // expected-note {{definition of 'Bar' is not complete}} \
+ // ref-note {{definition of 'Bar' is not complete}}
+public:
+ constexpr Bar(){}
+ constexpr Bar b; // expected-error {{cannot be constexpr}} \
+ // expected-error {{has incomplete type 'const Bar'}} \
+ // ref-error {{cannot be constexpr}} \
+ // ref-error {{has incomplete type 'const Bar'}}
+};
+constexpr Bar B; // expected-error {{must be initialized by a constant expression}} \
+ // expected-error {{failed to evaluate an expression}} \
+ // ref-error {{must be initialized by a constant expression}}
+
constexpr int locals() {
C c;
c.a = 10;
Index: clang/lib/AST/Interp/Program.h
===================================================================
--- clang/lib/AST/Interp/Program.h
+++ clang/lib/AST/Interp/Program.h
@@ -45,8 +45,10 @@
// Records might actually allocate memory themselves, but they
// are allocated using a BumpPtrAllocator. Call their desctructors
// here manually so they are properly freeing their resources.
- for (auto RecordPair : Records)
- RecordPair.second->~Record();
+ for (auto RecordPair : Records) {
+ if (Record *R = RecordPair.second)
+ R->~Record();
+ }
// Manually destroy all the blocks. They are almost all harmless,
// but primitive arrays might have an InitMap* heap allocated and
Index: clang/lib/AST/Interp/Program.cpp
===================================================================
--- clang/lib/AST/Interp/Program.cpp
+++ clang/lib/AST/Interp/Program.cpp
@@ -224,6 +224,11 @@
return It->second;
}
+ // We insert nullptr now and replace that later, so recursive calls
+ // to this function with the same RecordDecl don't run into
+ // infinite recursion.
+ Records.insert({RD, nullptr});
+
// Number of bytes required by fields and base classes.
unsigned BaseSize = 0;
// Number of bytes required by virtual base.
@@ -298,7 +303,7 @@
Record *R = new (Allocator) Record(RD, std::move(Bases), std::move(Fields),
std::move(VirtBases), VirtSize, BaseSize);
- Records.insert({RD, R});
+ Records[RD] = R;
return R;
}
Index: clang/lib/AST/Interp/ByteCodeStmtGen.cpp
===================================================================
--- clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ clang/lib/AST/Interp/ByteCodeStmtGen.cpp
@@ -98,7 +98,8 @@
if (const auto Ctor = dyn_cast<CXXConstructorDecl>(F)) {
const RecordDecl *RD = Ctor->getParent();
const Record *R = this->getRecord(RD);
- assert(R);
+ if (!R)
+ return false;
for (const auto *Init : Ctor->inits()) {
const Expr *InitExpr = Init->getInit();
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D136831.471102.patch
Type: text/x-patch
Size: 3061 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20221027/d7708609/attachment-0001.bin>
More information about the cfe-commits
mailing list