Author: Bill Wendling Date: 2022-04-14T16:35:41-07:00 New Revision: 8c77a75fb6a82a4cc2182bca89e007e7190a83de
URL: https://github.com/llvm/llvm-project/commit/8c77a75fb6a82a4cc2182bca89e007e7190a83de DIFF: https://github.com/llvm/llvm-project/commit/8c77a75fb6a82a4cc2182bca89e007e7190a83de.diff LOG: [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 Added: Modified: clang/unittests/AST/RandstructTest.cpp Removed: ################################################################################ diff --git a/clang/unittests/AST/RandstructTest.cpp b/clang/unittests/AST/RandstructTest.cpp index 9e03beaa9caf8..134752fa7937e 100644 --- a/clang/unittests/AST/RandstructTest.cpp +++ b/clang/unittests/AST/RandstructTest.cpp @@ -15,7 +15,7 @@ * * Run this test suite by running the following in the build folder: * ` ./tools/clang/unittests/AST/ASTTests - * --gtest_filter=StructureLayoutRandomization*` + * --gtest_filter=RecordLayoutRandomization*` */ #include "clang/AST/Randstruct.h" @@ -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; @@ -346,14 +397,14 @@ TEST(RANDSTRUCT_TEST, RandstructDoesNotRandomizeUnionFieldOrder) { EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred()); const RecordDecl *RD = - getRecordDeclFromAST(AST->getASTContext(), "test_union"); + getRecordDeclFromAST(AST->getASTContext(), "test"); EXPECT_FALSE(RD->isRandomized()); } 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()); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits