[clang] a7815d3 - [randstruct] Check final randomized layout ordering
Bill Wendling via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 21 19:41:10 PDT 2022
Author: Bill Wendling
Date: 2022-04-21T19:41:00-07:00
New Revision: a7815d33bf8f955f2a1888abbccf974bd4858f79
URL: https://github.com/llvm/llvm-project/commit/a7815d33bf8f955f2a1888abbccf974bd4858f79
DIFF: https://github.com/llvm/llvm-project/commit/a7815d33bf8f955f2a1888abbccf974bd4858f79.diff
LOG: [randstruct] Check final randomized layout ordering
This uses "llvm::shuffle" to stop differences in shuffle ordering on
different platforms.
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D124199
Added:
Modified:
clang/lib/AST/Randstruct.cpp
clang/unittests/AST/RandstructTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Randstruct.cpp b/clang/lib/AST/Randstruct.cpp
index fadc727bbc4ed..7d996fbadbe76 100644
--- a/clang/lib/AST/Randstruct.cpp
+++ b/clang/lib/AST/Randstruct.cpp
@@ -150,14 +150,14 @@ void randomizeStructureLayoutImpl(const ASTContext &Context,
if (CurrentBitfieldRun)
Buckets.push_back(std::move(CurrentBitfieldRun));
- std::shuffle(std::begin(Buckets), std::end(Buckets), RNG);
+ llvm::shuffle(std::begin(Buckets), std::end(Buckets), RNG);
// Produce the new ordering of the elements from the Buckets.
SmallVector<FieldDecl *, 16> FinalOrder;
for (const std::unique_ptr<Bucket> &B : Buckets) {
llvm::SmallVectorImpl<FieldDecl *> &RandFields = B->fields();
if (!B->isBitfieldRun())
- std::shuffle(std::begin(RandFields), std::end(RandFields), RNG);
+ llvm::shuffle(std::begin(RandFields), std::end(RandFields), RNG);
FinalOrder.insert(FinalOrder.end(), RandFields.begin(), RandFields.end());
}
diff --git a/clang/unittests/AST/RandstructTest.cpp b/clang/unittests/AST/RandstructTest.cpp
index 134752fa7937e..3c3f6a78390f9 100644
--- a/clang/unittests/AST/RandstructTest.cpp
+++ b/clang/unittests/AST/RandstructTest.cpp
@@ -159,7 +159,9 @@ TEST(RANDSTRUCT_TEST, UnmarkedStruct) {
EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test");
+ const field_names Expected = {"bacon", "lettuce", "tomato", "mayonnaise"};
+ EXPECT_EQ(Expected, getFieldNamesFromRecord(RD));
EXPECT_FALSE(RD->hasAttr<RandomizeLayoutAttr>());
EXPECT_FALSE(RD->isRandomized());
}
@@ -177,7 +179,9 @@ TEST(RANDSTRUCT_TEST, MarkedNoRandomize) {
EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test");
+ const field_names Expected = {"bacon", "lettuce", "tomato", "mayonnaise"};
+ EXPECT_EQ(Expected, getFieldNamesFromRecord(RD));
EXPECT_TRUE(RD->hasAttr<NoRandomizeLayoutAttr>());
EXPECT_FALSE(RD->isRandomized());
}
@@ -195,7 +199,9 @@ TEST(RANDSTRUCT_TEST, MarkedRandomize) {
EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test");
+ const field_names Expected = {"lettuce", "bacon", "mayonnaise", "tomato"};
+ EXPECT_EQ(Expected, getFieldNamesFromRecord(RD));
EXPECT_TRUE(RD->hasAttr<RandomizeLayoutAttr>());
EXPECT_TRUE(RD->isRandomized());
}
@@ -209,8 +215,7 @@ TEST(RANDSTRUCT_TEST, MismatchedAttrsDeclVsDef) {
long long tomato;
float mayonnaise;
} __attribute__((no_randomize_layout));
- )c",
- true);
+ )c", true);
EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
@@ -231,8 +236,7 @@ TEST(RANDSTRUCT_TEST, MismatchedAttrsRandomizeVsNoRandomize) {
long long tomato;
float mayonnaise;
} __attribute__((randomize_layout)) __attribute__((no_randomize_layout));
- )c",
- true);
+ )c", true);
EXPECT_TRUE(AST->getDiagnostics().hasErrorOccurred());
@@ -252,8 +256,7 @@ TEST(RANDSTRUCT_TEST, MismatchedAttrsNoRandomizeVsRandomize) {
long long tomato;
float mayonnaise;
} __attribute__((no_randomize_layout)) __attribute__((randomize_layout));
- )c",
- true);
+ )c", true);
EXPECT_TRUE(AST->getDiagnostics().hasErrorOccurred());
@@ -280,14 +283,16 @@ TEST(RANDSTRUCT_TEST, CheckAdjacentBitfieldsRemainAdjacentAfterRandomization) {
EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test");
- const field_names Actual = getFieldNamesFromRecord(RD);
- const field_names Subseq = {"x", "y", "z"};
+ const field_names Expected = {
+ "a", "b", "c", "x", "y", "z" // x, y, z needs to be a subsequnce.
+ };
+ EXPECT_EQ(Expected, getFieldNamesFromRecord(RD));
EXPECT_TRUE(RD->isRandomized());
- EXPECT_TRUE(isSubsequence(Actual, Subseq));
}
-TEST(RANDSTRUCT_TEST, CheckVariableLengthArrayMemberRemainsAtEndOfStructure) {
+// FIXME: Enable when fix for flexible arrays is submitted.
+TEST(RANDSTRUCT_TEST, DISABLED_CheckVariableLengthArrayMemberRemainsAtEndOfStructure) {
std::unique_ptr<ASTUnit> AST = makeAST(R"c(
struct test {
int a;
@@ -300,7 +305,9 @@ TEST(RANDSTRUCT_TEST, CheckVariableLengthArrayMemberRemainsAtEndOfStructure) {
EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test");
+ const field_names Expected = {"c", "a", "b", "name"};
+ EXPECT_EQ(Expected, getFieldNamesFromRecord(RD));
EXPECT_TRUE(RD->isRandomized());
}
@@ -325,10 +332,7 @@ TEST(RANDSTRUCT_TEST, RandstructDoesNotOverrideThePackedAttr) {
long long b;
int c[];
} __attribute__((packed, randomize_layout));
- )c",
- false,
- std::vector<std::string>(
- {"test_struct", "another_struct", "last_struct"}));
+ )c", false, field_names({"test_struct", "another_struct", "last_struct"}));
EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
@@ -340,7 +344,9 @@ TEST(RANDSTRUCT_TEST, RandstructDoesNotOverrideThePackedAttr) {
getRecordDeclFromAST(AST->getASTContext(), "test_struct");
const ASTRecordLayout *Layout =
&AST->getASTContext().getASTRecordLayout(RD);
+ const field_names Expected = {"b", "a", "c", "d"};
+ EXPECT_EQ(Expected, getFieldNamesFromRecord(RD));
EXPECT_TRUE(RD->isRandomized());
EXPECT_EQ(19, Layout->getSize().getQuantity());
}
@@ -350,7 +356,9 @@ TEST(RANDSTRUCT_TEST, RandstructDoesNotOverrideThePackedAttr) {
getRecordDeclFromAST(AST->getASTContext(), "another_struct");
const ASTRecordLayout *Layout =
&AST->getASTContext().getASTRecordLayout(RD);
+ const field_names Expected = {"c", "b", "a"};
+ EXPECT_EQ(Expected, getFieldNamesFromRecord(RD));
EXPECT_TRUE(RD->isRandomized());
EXPECT_EQ(10, Layout->getSize().getQuantity());
}
@@ -360,7 +368,9 @@ TEST(RANDSTRUCT_TEST, RandstructDoesNotOverrideThePackedAttr) {
getRecordDeclFromAST(AST->getASTContext(), "last_struct");
const ASTRecordLayout *Layout =
&AST->getASTContext().getASTRecordLayout(RD);
+ const field_names Expected = {"a", "c", "b"};
+ EXPECT_EQ(Expected, getFieldNamesFromRecord(RD));
EXPECT_TRUE(RD->isRandomized());
EXPECT_EQ(9, Layout->getSize().getQuantity());
}
@@ -378,7 +388,9 @@ TEST(RANDSTRUCT_TEST, ZeroWidthBitfieldsSeparateAllocationUnits) {
EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test");
+ const field_names Expected = {"a", "b", ""};
+ EXPECT_EQ(Expected, getFieldNamesFromRecord(RD));
EXPECT_TRUE(RD->isRandomized());
}
@@ -396,9 +408,10 @@ TEST(RANDSTRUCT_TEST, RandstructDoesNotRandomizeUnionFieldOrder) {
EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
- const RecordDecl *RD =
- getRecordDeclFromAST(AST->getASTContext(), "test");
+ const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test");
+ const field_names Expected = {"a", "b", "c", "d", "e", "f"};
+ EXPECT_EQ(Expected, getFieldNamesFromRecord(RD));
EXPECT_FALSE(RD->isRandomized());
}
@@ -436,7 +449,9 @@ TEST(RANDSTRUCT_TEST, AnonymousStructsAndUnionsRetainFieldOrder) {
EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test");
+ const field_names Expected = {"", "l", "", "r", "s", "a", "f"};
+ EXPECT_EQ(Expected, getFieldNamesFromRecord(RD));
EXPECT_TRUE(RD->isRandomized());
bool AnonStructTested = false;
More information about the cfe-commits
mailing list