Author: Bill Wendling Date: 2022-04-08T17:04:22-07:00 New Revision: 8d7595be1dd41d7f7470ec90867936ca5e4e0d82
URL: https://github.com/llvm/llvm-project/commit/8d7595be1dd41d7f7470ec90867936ca5e4e0d82 DIFF: https://github.com/llvm/llvm-project/commit/8d7595be1dd41d7f7470ec90867936ca5e4e0d82.diff LOG: [randstruct] temporarily remove test that's failing Added: Modified: Removed: clang/unittests/AST/RandstructTest.cpp ################################################################################ diff --git a/clang/unittests/AST/RandstructTest.cpp b/clang/unittests/AST/RandstructTest.cpp deleted file mode 100644 index ad07e55bef207..0000000000000 --- a/clang/unittests/AST/RandstructTest.cpp +++ /dev/null @@ -1,476 +0,0 @@ -//===- unittest/AST/RandstructTest.cpp ------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file contains tests for Clang's structure field layout randomization. -// -//===----------------------------------------------------------------------===// - -/* - * Build this test suite by running `make ASTTests` in the build folder. - * - * Run this test suite by running the following in the build folder: - * ` ./tools/clang/unittests/AST/ASTTests - * --gtest_filter=StructureLayoutRandomization*` - */ - -#include "clang/AST/Randstruct.h" -#include "gtest/gtest.h" - -#include "DeclMatcher.h" -#include "clang/AST/RecordLayout.h" -#include "clang/ASTMatchers/ASTMatchers.h" -#include "clang/Frontend/ASTUnit.h" -#include "clang/Testing/CommandLineArgs.h" -#include "clang/Tooling/Tooling.h" - -#include <vector> - -using namespace clang; -using namespace clang::ast_matchers; -using namespace clang::randstruct; - -using field_names = std::vector<std::string>; - -namespace { - -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); -} - -RecordDecl *getRecordDeclFromAST(const ASTContext &C, const std::string &Name) { - RecordDecl *RD = FirstDeclMatcher<RecordDecl>().match( - C.getTranslationUnitDecl(), recordDecl(hasName(Name))); - return RD; -} - -std::vector<std::string> getFieldNamesFromRecord(const RecordDecl *RD) { - std::vector<std::string> Fields; - - Fields.reserve(8); - for (auto *Field : RD->fields()) - Fields.push_back(Field->getNameAsString()); - - return Fields; -} - -bool isSubsequence(const field_names &Seq, const field_names &Subseq) { - unsigned SeqLen = Seq.size(); - unsigned SubLen = Subseq.size(); - - bool IsSubseq = false; - for (unsigned I = 0; I < SeqLen; ++I) - if (Seq[I] == Subseq[0]) { - IsSubseq = true; - for (unsigned J = 0; J + I < SeqLen && J < SubLen; ++J) { - if (Seq[J + I] != Subseq[J]) { - IsSubseq = false; - break; - } - } - } - - return IsSubseq; -} - -} // end anonymous namespace - -namespace clang { -namespace ast_matchers { - -#define RANDSTRUCT_TEST_SUITE_TEST StructureLayoutRandomizationTestSuiteTest - -TEST(RANDSTRUCT_TEST_SUITE_TEST, CanDetermineIfSubsequenceExists) { - const field_names Seq = {"a", "b", "c", "d"}; - - EXPECT_TRUE(isSubsequence(Seq, {"b", "c"})); - EXPECT_TRUE(isSubsequence(Seq, {"a", "b", "c", "d"})); - EXPECT_TRUE(isSubsequence(Seq, {"b", "c", "d"})); - EXPECT_TRUE(isSubsequence(Seq, {"a"})); - EXPECT_FALSE(isSubsequence(Seq, {"a", "d"})); -} - -#define RANDSTRUCT_TEST StructureLayoutRandomization - -TEST(RANDSTRUCT_TEST, UnmarkedStruct) { - const std::unique_ptr<ASTUnit> AST = makeAST(R"c( - struct test { - int bacon; - long lettuce; - long long tomato; - float mayonnaise; - }; - )c"); - - EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred()); - - const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test"); - const field_names Expected = {"bacon", "lettuce", "tomato", "mayonnaise"}; - - EXPECT_FALSE(RD->hasAttr<RandomizeLayoutAttr>()); - EXPECT_FALSE(RD->isRandomized()); - EXPECT_EQ(Expected, getFieldNamesFromRecord(RD)); -} - -TEST(RANDSTRUCT_TEST, MarkedNoRandomize) { - const std::unique_ptr<ASTUnit> AST = makeAST(R"c( - struct test { - int bacon; - long lettuce; - long long tomato; - float mayonnaise; - } __attribute__((no_randomize_layout)); - )c"); - - EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred()); - - const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test"); - const field_names Expected = {"bacon", "lettuce", "tomato", "mayonnaise"}; - - EXPECT_TRUE(RD->hasAttr<NoRandomizeLayoutAttr>()); - EXPECT_FALSE(RD->isRandomized()); - EXPECT_EQ(Expected, getFieldNamesFromRecord(RD)); -} - -#ifndef _WIN32 -TEST(RANDSTRUCT_TEST, MarkedRandomize) { - const std::unique_ptr<ASTUnit> AST = makeAST(R"c( - struct test { - int bacon; - long lettuce; - long long tomato; - float mayonnaise; - } __attribute__((randomize_layout)); - )c"); - - EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred()); - - const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test"); -#ifdef _WIN32 - const field_names Expected = {"lettuce", "bacon", "mayonnaise", "tomato"}; -#else - const field_names Expected = {"mayonnaise", "bacon", "tomato", "lettuce"}; -#endif - - EXPECT_TRUE(RD->hasAttr<RandomizeLayoutAttr>()); - EXPECT_TRUE(RD->isRandomized()); - EXPECT_EQ(Expected, getFieldNamesFromRecord(RD)); -} -#endif - -TEST(RANDSTRUCT_TEST, MismatchedAttrsDeclVsDef) { - const std::unique_ptr<ASTUnit> AST = makeAST(R"c( - struct test __attribute__((randomize_layout)); - struct test { - int bacon; - long lettuce; - long long tomato; - float mayonnaise; - } __attribute__((no_randomize_layout)); - )c"); - - EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred()); - - DiagnosticsEngine &Diags = AST->getDiagnostics(); - - EXPECT_FALSE(Diags.hasFatalErrorOccurred()); - EXPECT_FALSE(Diags.hasUncompilableErrorOccurred()); - EXPECT_FALSE(Diags.hasUnrecoverableErrorOccurred()); - EXPECT_EQ(Diags.getNumWarnings(), 1u); - EXPECT_EQ(Diags.getNumErrors(), 0u); -} - -TEST(RANDSTRUCT_TEST, MismatchedAttrsRandomizeVsNoRandomize) { - const std::unique_ptr<ASTUnit> AST = makeAST(R"c( - struct test2 { - int bacon; - long lettuce; - long long tomato; - float mayonnaise; - } __attribute__((randomize_layout)) __attribute__((no_randomize_layout)); - )c"); - - EXPECT_TRUE(AST->getDiagnostics().hasErrorOccurred()); - - DiagnosticsEngine &Diags = AST->getDiagnostics(); - - EXPECT_TRUE(Diags.hasUncompilableErrorOccurred()); - EXPECT_TRUE(Diags.hasUnrecoverableErrorOccurred()); - EXPECT_EQ(Diags.getNumWarnings(), 0u); - EXPECT_EQ(Diags.getNumErrors(), 1u); -} - -TEST(RANDSTRUCT_TEST, MismatchedAttrsNoRandomizeVsRandomize) { - const 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"); - - EXPECT_TRUE(AST->getDiagnostics().hasErrorOccurred()); - - DiagnosticsEngine &Diags = AST->getDiagnostics(); - - EXPECT_TRUE(Diags.hasUncompilableErrorOccurred()); - EXPECT_TRUE(Diags.hasUnrecoverableErrorOccurred()); - EXPECT_EQ(Diags.getNumWarnings(), 0u); - EXPECT_EQ(Diags.getNumErrors(), 1u); -} - -TEST(RANDSTRUCT_TEST, CheckAdjacentBitfieldsRemainAdjacentAfterRandomization) { - const std::unique_ptr<ASTUnit> AST = makeAST(R"c( - struct test { - int a; - int b; - int x : 1; - int y : 1; - int z : 1; - int c; - } __attribute__((randomize_layout)); - )c"); - - EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred()); - - const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test"); - -#ifdef _WIN32 - const field_names Expected = {"b", "a", "c", "x", "y", "z"}; -#else - const field_names Expected = {"c", "x", "y", "z", "b", "a"}; -#endif - const field_names Subseq = {"x", "y", "z"}; - const field_names Actual = getFieldNamesFromRecord(RD); - - EXPECT_TRUE(isSubsequence(Actual, Subseq)); - EXPECT_EQ(Expected, Actual); -} - -TEST(RANDSTRUCT_TEST, CheckVariableLengthArrayMemberRemainsAtEndOfStructure) { - const std::unique_ptr<ASTUnit> AST = makeAST(R"c( - struct test { - int a; - double b; - short c; - char name[]; - } __attribute__((randomize_layout)); - )c"); - - EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred()); - - const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test"); -#ifdef _WIN32 - const field_names Expected = {"b", "a", "c", "name"}; -#else - const field_names Expected = {"b", "c", "a", "name"}; -#endif - - EXPECT_EQ(Expected, getFieldNamesFromRecord(RD)); -} - -TEST(RANDSTRUCT_TEST, RandstructDoesNotOverrideThePackedAttr) { - const std::unique_ptr<ASTUnit> AST = makeAST(R"c( - struct test_struct { - char a; - float b[3]; - short c; - int d; - } __attribute__((packed, randomize_layout)); - - struct another_struct { - char a; - char b[5]; - int c; - } __attribute__((packed, randomize_layout)); - - struct last_struct { - char a; - long long b; - int c[]; - } __attribute__((packed, randomize_layout)); - )c"); - - EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred()); - - // FIXME (?): calling getASTRecordLayout is probably a necessary evil so that - // Clang's RecordBuilders can actually flesh out the information like - // alignment, etc. - { - const RecordDecl *RD = - getRecordDeclFromAST(AST->getASTContext(), "test_struct"); - const ASTRecordLayout *Layout = - &AST->getASTContext().getASTRecordLayout(RD); -#ifdef _WIN32 - const field_names Expected = {"a", "c", "d", "b"}; -#else - const field_names Expected = {"c", "a", "d", "b"}; -#endif - - EXPECT_EQ(19, Layout->getSize().getQuantity()); - EXPECT_EQ(Expected, getFieldNamesFromRecord(RD)); - } - - { - const RecordDecl *RD = - getRecordDeclFromAST(AST->getASTContext(), "another_struct"); - const ASTRecordLayout *Layout = - &AST->getASTContext().getASTRecordLayout(RD); -#ifdef _WIN32 - const field_names Expected = {"a", "b", "c"}; -#else - const field_names Expected = {"c", "a", "b"}; -#endif - - EXPECT_EQ(10, Layout->getSize().getQuantity()); - EXPECT_EQ(Expected, getFieldNamesFromRecord(RD)); - } - - { - const RecordDecl *RD = - getRecordDeclFromAST(AST->getASTContext(), "last_struct"); - const ASTRecordLayout *Layout = - &AST->getASTContext().getASTRecordLayout(RD); - const field_names Expected = {"b", "c", "a"}; - - EXPECT_EQ(9, Layout->getSize().getQuantity()); - EXPECT_EQ(Expected, getFieldNamesFromRecord(RD)); - } -} - -TEST(RANDSTRUCT_TEST, ZeroWidthBitfieldsSeparateAllocationUnits) { - const std::unique_ptr<ASTUnit> AST = makeAST(R"c( - struct test_struct { - int a : 1; - int : 0; - int b : 1; - } __attribute__((randomize_layout)); - )c"); - - EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred()); - - const RecordDecl *RD = - getRecordDeclFromAST(AST->getASTContext(), "test_struct"); -#ifdef _WIN32 - const field_names Expected = {"b", "a", ""}; -#else - const field_names Expected = {"", "a", "b"}; -#endif - - EXPECT_EQ(Expected, getFieldNamesFromRecord(RD)); -} - -TEST(RANDSTRUCT_TEST, RandstructDoesNotRandomizeUnionFieldOrder) { - const std::unique_ptr<ASTUnit> AST = makeAST(R"c( - union test_union { - int a; - int b; - int c; - int d; - int e; - int f; - } __attribute__((randomize_layout)); - )c"); - - EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred()); - - const RecordDecl *RD = - getRecordDeclFromAST(AST->getASTContext(), "test_union"); - const field_names Expected = {"a", "b", "c", "d", "e", "f"}; - - EXPECT_FALSE(RD->isRandomized()); - EXPECT_EQ(Expected, getFieldNamesFromRecord(RD)); -} - -TEST(RANDSTRUCT_TEST, AnonymousStructsAndUnionsRetainFieldOrder) { - const std::unique_ptr<ASTUnit> AST = makeAST(R"c( - struct test_struct { - int a; - struct sub_struct { - int b; - int c; - int d; - int e; - int f; - } __attribute__((randomize_layout)) s; - int f; - struct { - int g; - int h; - int i; - int j; - int k; - }; - int l; - union { - int m; - int n; - int o; - int p; - int q; - }; - int r; - } __attribute__((randomize_layout)); - )c"); - - EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred()); - - const RecordDecl *RD = - getRecordDeclFromAST(AST->getASTContext(), "test_struct"); -#ifdef _WIN32 - const field_names Expected = {"", "s", "l", "", "r", "a", "f"}; -#else - const field_names Expected = {"f", "a", "l", "", "", "s", "r"}; -#endif - - EXPECT_EQ(Expected, getFieldNamesFromRecord(RD)); - - bool AnonStructTested = false; - bool AnonUnionTested = false; - for (const Decl *D : RD->decls()) - if (const FieldDecl *FD = dyn_cast<FieldDecl>(D)) { - if (const auto *Record = FD->getType()->getAs<RecordType>()) { - RD = Record->getDecl(); - if (RD->isAnonymousStructOrUnion()) { - if (RD->isUnion()) { - const field_names Expected = {"m", "n", "o", "p", "q"}; - - EXPECT_EQ(Expected, getFieldNamesFromRecord(RD)); - AnonUnionTested = true; - } else { - const field_names Expected = {"g", "h", "i", "j", "k"}; - - EXPECT_EQ(Expected, getFieldNamesFromRecord(RD)); - AnonStructTested = true; - } - } else if (RD->isStruct()) { -#ifdef _WIN32 - const field_names Expected = {"b", "c", "f", "d", "e"}; -#else - const field_names Expected = {"d", "e", "f", "c", "b"}; -#endif - EXPECT_EQ(Expected, getFieldNamesFromRecord(RD)); - } - } - } - - EXPECT_TRUE(AnonStructTested); - EXPECT_TRUE(AnonUnionTested); -} - -} // namespace ast_matchers -} // namespace clang _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits