[PATCH] D156201: [ASTImporter] Fix corrupted RecordLayout introduced by circular referenced fields
Ding Fei via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 27 22:08:41 PDT 2023
danix800 updated this revision to Diff 545016.
danix800 added a comment.
Add missing field value setting (`FPOptionsOverride`).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D156201/new/
https://reviews.llvm.org/D156201
Files:
clang/include/clang/AST/Expr.h
clang/lib/AST/ASTImporter.cpp
clang/unittests/AST/ASTImporterTest.cpp
Index: clang/unittests/AST/ASTImporterTest.cpp
===================================================================
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -10,6 +10,7 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/AST/RecordLayout.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/SmallVectorMemoryBuffer.h"
@@ -8028,6 +8029,45 @@
Import(FromF, Lang_CXX11);
}
+TEST_P(ASTImporterOptionSpecificTestBase,
+ ImportCirularRefFieldsWithoutCorruptedRecordLayoutCacheTest) {
+ // Import sequence: A => A.b => B => B.f() => ... => UnaryOperator(&) => ...
+ //
+ // UnaryOperator(&) should not introduce invalid RecordLayout since 'A' is
+ // still not completely imported.
+ auto Code =
+ R"(
+ class B;
+ class A {
+ B* b;
+ int c;
+ };
+ class B {
+ A *f() { return &((B *)0)->a; }
+ A a;
+ };
+ )";
+
+ auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
+ getTuDecl(Code, Lang_CXX11), cxxRecordDecl(hasName("A")));
+ FromR = FromR->getDefinition();
+ auto &FromAST = FromR->getASTContext();
+ auto *ToR = Import(FromR, Lang_CXX11);
+ auto &ToAST = ToR->getASTContext();
+
+ uint64_t SecondFieldOffset = FromAST.getTypeSize(FromAST.VoidPtrTy);
+
+ EXPECT_TRUE(FromR->isCompleteDefinition());
+ const auto &FromLayout = FromAST.getASTRecordLayout(FromR);
+ EXPECT_TRUE(FromLayout.getFieldOffset(0) == 0);
+ EXPECT_TRUE(FromLayout.getFieldOffset(1) == SecondFieldOffset);
+
+ EXPECT_TRUE(ToR->isCompleteDefinition());
+ const auto &ToLayout = ToAST.getASTRecordLayout(ToR);
+ EXPECT_TRUE(ToLayout.getFieldOffset(0) == 0);
+ EXPECT_TRUE(ToLayout.getFieldOffset(1) == SecondFieldOffset);
+}
+
TEST_P(ASTImporterOptionSpecificTestBase,
ImportRecordWithLayoutRequestingExpr) {
TranslationUnitDecl *FromTU = getTuDecl(
Index: clang/lib/AST/ASTImporter.cpp
===================================================================
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -7405,10 +7405,17 @@
if (Err)
return std::move(Err);
- return UnaryOperator::Create(
- Importer.getToContext(), ToSubExpr, E->getOpcode(), ToType,
- E->getValueKind(), E->getObjectKind(), ToOperatorLoc, E->canOverflow(),
- E->getFPOptionsOverride());
+ auto *UO = UnaryOperator::CreateEmpty(Importer.getToContext(),
+ E->hasStoredFPFeatures());
+ UO->setType(ToType);
+ UO->setSubExpr(ToSubExpr);
+ UO->setOpcode(E->getOpcode());
+ UO->setOperatorLoc(ToOperatorLoc);
+ UO->setCanOverflow(E->canOverflow());
+ if (E->hasStoredFPFeatures())
+ UO->setStoredFPFeatures(E->getStoredFPFeatures());
+
+ return UO;
}
ExpectedStmt
Index: clang/include/clang/AST/Expr.h
===================================================================
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -2340,8 +2340,7 @@
return getTrailingFPFeatures();
}
-protected:
- /// Set FPFeatures in trailing storage, used only by Serialization
+ /// Set FPFeatures in trailing storage, used by Serialization & ASTImporter
void setStoredFPFeatures(FPOptionsOverride F) { getTrailingFPFeatures() = F; }
public:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D156201.545016.patch
Type: text/x-patch
Size: 3361 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230728/d079736f/attachment.bin>
More information about the cfe-commits
mailing list