This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG99d3ead44cfb: [clang][Interp] Protect Record creation against infinite recursion (authored by tbaeder).
Changed prior to commit: https://reviews.llvm.org/D136831?vs=471102&id=474670#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D136831/new/ 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,20 @@ 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 Bar *pb = nullptr; + 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 @@ -51,8 +51,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(); + } } /// Marshals a native pointer to an ID for embedding in bytecode. Index: clang/lib/AST/Interp/Program.cpp =================================================================== --- clang/lib/AST/Interp/Program.cpp +++ clang/lib/AST/Interp/Program.cpp @@ -221,6 +221,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. @@ -294,7 +299,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();
Index: clang/test/AST/Interp/records.cpp =================================================================== --- clang/test/AST/Interp/records.cpp +++ clang/test/AST/Interp/records.cpp @@ -133,6 +133,20 @@ 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 Bar *pb = nullptr; + 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 @@ -51,8 +51,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(); + } } /// Marshals a native pointer to an ID for embedding in bytecode. Index: clang/lib/AST/Interp/Program.cpp =================================================================== --- clang/lib/AST/Interp/Program.cpp +++ clang/lib/AST/Interp/Program.cpp @@ -221,6 +221,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. @@ -294,7 +299,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();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits