forked from OSchip/llvm-project
[randstruct] Add test for "-frandomize-layout-seed-file" flag
This test makes sure that the "-frandomize-layout-seed" and "-frandomize-layout-seed-file" flags generate the same layout for the record. Reviewed By: aaron.ballman, MaskRay Differential Revision: https://reviews.llvm.org/D123636
This commit is contained in:
parent
a68612a964
commit
31ea4798ad
|
@ -27,6 +27,7 @@
|
|||
#include "clang/Frontend/ASTUnit.h"
|
||||
#include "clang/Testing/CommandLineArgs.h"
|
||||
#include "clang/Tooling/Tooling.h"
|
||||
#include "llvm/Support/ToolOutputFile.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
@ -36,18 +37,7 @@ using namespace clang::randstruct;
|
|||
|
||||
using field_names = std::vector<std::string>;
|
||||
|
||||
static std::unique_ptr<ASTUnit> makeAST(const std::string &SourceCode) {
|
||||
std::vector<std::string> Args = getCommandLineArgsForTesting(Lang_C99);
|
||||
Args.push_back("-frandomize-layout-seed=1234567890abcdef");
|
||||
|
||||
IgnoringDiagConsumer IgnoringConsumer = IgnoringDiagConsumer();
|
||||
|
||||
return tooling::buildASTFromCodeWithArgs(
|
||||
SourceCode, Args, "input.c", "clang-tool",
|
||||
std::make_shared<PCHContainerOperations>(),
|
||||
tooling::getClangStripDependencyFileAdjuster(),
|
||||
tooling::FileContentMappings(), &IgnoringConsumer);
|
||||
}
|
||||
constexpr const char Seed[] = "1234567890abcdef";
|
||||
|
||||
static RecordDecl *getRecordDeclFromAST(const ASTContext &C,
|
||||
const std::string &Name) {
|
||||
|
@ -85,10 +75,64 @@ static bool isSubsequence(const field_names &Seq, const field_names &Subseq) {
|
|||
return IsSubseq;
|
||||
}
|
||||
|
||||
static bool recordsEqual(const std::unique_ptr<ASTUnit> &LHS,
|
||||
const std::unique_ptr<ASTUnit> &RHS,
|
||||
const std::string &RecordName) {
|
||||
const RecordDecl *LHSRD =
|
||||
getRecordDeclFromAST(LHS->getASTContext(), RecordName);
|
||||
const RecordDecl *RHSRD =
|
||||
getRecordDeclFromAST(LHS->getASTContext(), RecordName);
|
||||
|
||||
return getFieldNamesFromRecord(LHSRD) == getFieldNamesFromRecord(RHSRD);
|
||||
}
|
||||
|
||||
static std::unique_ptr<ASTUnit>
|
||||
makeAST(const std::string &SourceCode, bool ExpectError = false,
|
||||
std::vector<std::string> RecordNames = std::vector<std::string>()) {
|
||||
std::vector<std::string> Args = getCommandLineArgsForTesting(Lang_C99);
|
||||
Args.push_back("-frandomize-layout-seed=" + std::string(Seed));
|
||||
|
||||
IgnoringDiagConsumer IgnoringConsumer = IgnoringDiagConsumer();
|
||||
|
||||
std::unique_ptr<ASTUnit> AST = tooling::buildASTFromCodeWithArgs(
|
||||
SourceCode, Args, "input.c", "clang-tool",
|
||||
std::make_shared<PCHContainerOperations>(),
|
||||
tooling::getClangStripDependencyFileAdjuster(),
|
||||
tooling::FileContentMappings(), &IgnoringConsumer);
|
||||
|
||||
int SeedFileFD = -1;
|
||||
llvm::SmallString<256> SeedFilename;
|
||||
EXPECT_FALSE(llvm::sys::fs::createTemporaryFile("seed", "rng", SeedFileFD,
|
||||
SeedFilename));
|
||||
llvm::ToolOutputFile SeedFile(SeedFilename, SeedFileFD);
|
||||
SeedFile.os() << Seed << "\n";
|
||||
|
||||
Args.clear();
|
||||
Args = getCommandLineArgsForTesting(Lang_C99);
|
||||
Args.push_back("-frandomize-layout-seed-file=" +
|
||||
SeedFile.getFilename().str());
|
||||
|
||||
std::unique_ptr<ASTUnit> ASTFileSeed = tooling::buildASTFromCodeWithArgs(
|
||||
SourceCode, Args, "input.c", "clang-tool",
|
||||
std::make_shared<PCHContainerOperations>(),
|
||||
tooling::getClangStripDependencyFileAdjuster(),
|
||||
tooling::FileContentMappings(), &IgnoringConsumer);
|
||||
|
||||
if (!ExpectError) {
|
||||
if (RecordNames.empty())
|
||||
RecordNames.push_back("test");
|
||||
|
||||
for (std::string Name : RecordNames)
|
||||
EXPECT_TRUE(recordsEqual(AST, ASTFileSeed, Name));
|
||||
}
|
||||
|
||||
return AST;
|
||||
}
|
||||
|
||||
namespace clang {
|
||||
namespace ast_matchers {
|
||||
|
||||
#define RANDSTRUCT_TEST_SUITE_TEST StructureLayoutRandomizationTestSuiteTest
|
||||
#define RANDSTRUCT_TEST_SUITE_TEST RecordLayoutRandomizationTestSuiteTest
|
||||
|
||||
TEST(RANDSTRUCT_TEST_SUITE_TEST, CanDetermineIfSubsequenceExists) {
|
||||
const field_names Seq = {"a", "b", "c", "d"};
|
||||
|
@ -100,10 +144,10 @@ TEST(RANDSTRUCT_TEST_SUITE_TEST, CanDetermineIfSubsequenceExists) {
|
|||
EXPECT_FALSE(isSubsequence(Seq, {"a", "d"}));
|
||||
}
|
||||
|
||||
#define RANDSTRUCT_TEST StructureLayoutRandomization
|
||||
#define RANDSTRUCT_TEST RecordLayoutRandomization
|
||||
|
||||
TEST(RANDSTRUCT_TEST, UnmarkedStruct) {
|
||||
const std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
struct test {
|
||||
int bacon;
|
||||
long lettuce;
|
||||
|
@ -121,7 +165,7 @@ TEST(RANDSTRUCT_TEST, UnmarkedStruct) {
|
|||
}
|
||||
|
||||
TEST(RANDSTRUCT_TEST, MarkedNoRandomize) {
|
||||
const std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
struct test {
|
||||
int bacon;
|
||||
long lettuce;
|
||||
|
@ -139,7 +183,7 @@ TEST(RANDSTRUCT_TEST, MarkedNoRandomize) {
|
|||
}
|
||||
|
||||
TEST(RANDSTRUCT_TEST, MarkedRandomize) {
|
||||
const std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
struct test {
|
||||
int bacon;
|
||||
long lettuce;
|
||||
|
@ -157,7 +201,7 @@ TEST(RANDSTRUCT_TEST, MarkedRandomize) {
|
|||
}
|
||||
|
||||
TEST(RANDSTRUCT_TEST, MismatchedAttrsDeclVsDef) {
|
||||
const std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
struct test __attribute__((randomize_layout));
|
||||
struct test {
|
||||
int bacon;
|
||||
|
@ -165,11 +209,12 @@ TEST(RANDSTRUCT_TEST, MismatchedAttrsDeclVsDef) {
|
|||
long long tomato;
|
||||
float mayonnaise;
|
||||
} __attribute__((no_randomize_layout));
|
||||
)c");
|
||||
)c",
|
||||
true);
|
||||
|
||||
EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
|
||||
|
||||
DiagnosticsEngine &Diags = AST->getDiagnostics();
|
||||
const DiagnosticsEngine &Diags = AST->getDiagnostics();
|
||||
|
||||
EXPECT_FALSE(Diags.hasFatalErrorOccurred());
|
||||
EXPECT_FALSE(Diags.hasUncompilableErrorOccurred());
|
||||
|
@ -179,18 +224,19 @@ TEST(RANDSTRUCT_TEST, MismatchedAttrsDeclVsDef) {
|
|||
}
|
||||
|
||||
TEST(RANDSTRUCT_TEST, MismatchedAttrsRandomizeVsNoRandomize) {
|
||||
const std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
struct test2 {
|
||||
std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
struct test {
|
||||
int bacon;
|
||||
long lettuce;
|
||||
long long tomato;
|
||||
float mayonnaise;
|
||||
} __attribute__((randomize_layout)) __attribute__((no_randomize_layout));
|
||||
)c");
|
||||
)c",
|
||||
true);
|
||||
|
||||
EXPECT_TRUE(AST->getDiagnostics().hasErrorOccurred());
|
||||
|
||||
DiagnosticsEngine &Diags = AST->getDiagnostics();
|
||||
const DiagnosticsEngine &Diags = AST->getDiagnostics();
|
||||
|
||||
EXPECT_TRUE(Diags.hasUncompilableErrorOccurred());
|
||||
EXPECT_TRUE(Diags.hasUnrecoverableErrorOccurred());
|
||||
|
@ -199,18 +245,19 @@ TEST(RANDSTRUCT_TEST, MismatchedAttrsRandomizeVsNoRandomize) {
|
|||
}
|
||||
|
||||
TEST(RANDSTRUCT_TEST, MismatchedAttrsNoRandomizeVsRandomize) {
|
||||
const std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
struct test3 {
|
||||
int bacon;
|
||||
long lettuce;
|
||||
long long tomato;
|
||||
float mayonnaise;
|
||||
} __attribute__((no_randomize_layout)) __attribute__((randomize_layout));
|
||||
)c");
|
||||
)c",
|
||||
true);
|
||||
|
||||
EXPECT_TRUE(AST->getDiagnostics().hasErrorOccurred());
|
||||
|
||||
DiagnosticsEngine &Diags = AST->getDiagnostics();
|
||||
const DiagnosticsEngine &Diags = AST->getDiagnostics();
|
||||
|
||||
EXPECT_TRUE(Diags.hasUncompilableErrorOccurred());
|
||||
EXPECT_TRUE(Diags.hasUnrecoverableErrorOccurred());
|
||||
|
@ -219,7 +266,7 @@ TEST(RANDSTRUCT_TEST, MismatchedAttrsNoRandomizeVsRandomize) {
|
|||
}
|
||||
|
||||
TEST(RANDSTRUCT_TEST, CheckAdjacentBitfieldsRemainAdjacentAfterRandomization) {
|
||||
const std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
struct test {
|
||||
int a;
|
||||
int b;
|
||||
|
@ -241,7 +288,7 @@ TEST(RANDSTRUCT_TEST, CheckAdjacentBitfieldsRemainAdjacentAfterRandomization) {
|
|||
}
|
||||
|
||||
TEST(RANDSTRUCT_TEST, CheckVariableLengthArrayMemberRemainsAtEndOfStructure) {
|
||||
const std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
struct test {
|
||||
int a;
|
||||
double b;
|
||||
|
@ -258,7 +305,8 @@ TEST(RANDSTRUCT_TEST, CheckVariableLengthArrayMemberRemainsAtEndOfStructure) {
|
|||
}
|
||||
|
||||
TEST(RANDSTRUCT_TEST, RandstructDoesNotOverrideThePackedAttr) {
|
||||
const std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
std::unique_ptr<ASTUnit> AST =
|
||||
makeAST(R"c(
|
||||
struct test_struct {
|
||||
char a;
|
||||
float b[3];
|
||||
|
@ -277,7 +325,10 @@ TEST(RANDSTRUCT_TEST, RandstructDoesNotOverrideThePackedAttr) {
|
|||
long long b;
|
||||
int c[];
|
||||
} __attribute__((packed, randomize_layout));
|
||||
)c");
|
||||
)c",
|
||||
false,
|
||||
std::vector<std::string>(
|
||||
{"test_struct", "another_struct", "last_struct"}));
|
||||
|
||||
EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
|
||||
|
||||
|
@ -316,7 +367,7 @@ TEST(RANDSTRUCT_TEST, RandstructDoesNotOverrideThePackedAttr) {
|
|||
}
|
||||
|
||||
TEST(RANDSTRUCT_TEST, ZeroWidthBitfieldsSeparateAllocationUnits) {
|
||||
const std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
struct test {
|
||||
int a : 1;
|
||||
int : 0;
|
||||
|
@ -332,8 +383,8 @@ TEST(RANDSTRUCT_TEST, ZeroWidthBitfieldsSeparateAllocationUnits) {
|
|||
}
|
||||
|
||||
TEST(RANDSTRUCT_TEST, RandstructDoesNotRandomizeUnionFieldOrder) {
|
||||
const std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
union test_union {
|
||||
std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
union test {
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
|
@ -352,8 +403,8 @@ TEST(RANDSTRUCT_TEST, RandstructDoesNotRandomizeUnionFieldOrder) {
|
|||
}
|
||||
|
||||
TEST(RANDSTRUCT_TEST, AnonymousStructsAndUnionsRetainFieldOrder) {
|
||||
const std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
struct test_struct {
|
||||
std::unique_ptr<ASTUnit> AST = makeAST(R"c(
|
||||
struct test {
|
||||
int a;
|
||||
struct sub_struct {
|
||||
int b;
|
||||
|
@ -384,8 +435,7 @@ TEST(RANDSTRUCT_TEST, AnonymousStructsAndUnionsRetainFieldOrder) {
|
|||
|
||||
EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
|
||||
|
||||
const RecordDecl *RD =
|
||||
getRecordDeclFromAST(AST->getASTContext(), "test_struct");
|
||||
const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test");
|
||||
|
||||
EXPECT_TRUE(RD->isRandomized());
|
||||
|
||||
|
|
Loading…
Reference in New Issue