[llvm] a58d0af - Revert D121556 "[randstruct] Add randomize structure layout support"

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 8 18:37:33 PDT 2022


Author: Fangrui Song
Date: 2022-04-08T18:37:26-07:00
New Revision: a58d0af058038595c93de961b725f86997cf8d4a

URL: https://github.com/llvm/llvm-project/commit/a58d0af058038595c93de961b725f86997cf8d4a
DIFF: https://github.com/llvm/llvm-project/commit/a58d0af058038595c93de961b725f86997cf8d4a.diff

LOG: Revert D121556 "[randstruct] Add randomize structure layout support"

This reverts commit 3f0587d0c668202bb89d29a25432aa290e551a31.

Not all tests pass after a few rounds of fixes.

I spot one failure that std::shuffle (potentially different results with
different STL implementations) was misused and replaced it with llvm::shuffle,
but there appears to be another failure in a Windows build.

The latest failure is reported on https://reviews.llvm.org/D121556#3440383

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/AST/Decl.h
    clang/include/clang/AST/DeclBase.h
    clang/include/clang/Basic/Attr.td
    clang/include/clang/Basic/AttrDocs.td
    clang/include/clang/Basic/DiagnosticDriverKinds.td
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/include/clang/Basic/LangOptions.h
    clang/include/clang/Driver/Options.td
    clang/lib/AST/CMakeLists.txt
    clang/lib/AST/Decl.cpp
    clang/lib/Driver/ToolChains/Clang.cpp
    clang/lib/Frontend/CompilerInvocation.cpp
    clang/lib/Sema/SemaCast.cpp
    clang/lib/Sema/SemaDecl.cpp
    clang/lib/Sema/SemaDeclAttr.cpp
    clang/test/Misc/pragma-attribute-supported-attributes-list.test
    clang/unittests/AST/CMakeLists.txt
    llvm/utils/gn/secondary/clang/lib/AST/BUILD.gn
    llvm/utils/gn/secondary/clang/unittests/AST/BUILD.gn

Removed: 
    clang/include/clang/AST/Randstruct.h
    clang/lib/AST/Randstruct.cpp
    clang/unittests/AST/RandstructTest.cpp


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f4feaeabf3548..7e8537e890714 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -54,20 +54,6 @@ Major New Features
   There is an analogous ``zero_call_used_regs`` attribute to allow for finer
   control of this feature.
 
-- Clang now supports randomizing structure layout in C. This feature is a
-  compile-time hardening technique, making it more 
diff icult for an attacker to
-  retrieve data from structures. Specify randomization with the
-  ``randomize_layout`` attribute. The corresponding ``no_randomize_layout``
-  attribute can be used to turn the feature off.
-
-  A seed value is required to enable randomization, and is deterministic based
-  on a seed value. Use the ``-frandomize-layout-seed=`` or
-  ``-frandomize-layout-seed-file=`` flags.
-
-  .. note::
-
-      Randomizing structure layout is a C-only feature.
-
 Bug Fixes
 ------------------
 - ``CXXNewExpr::getArraySize()`` previously returned a ``llvm::Optional``

diff  --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 21a8545920387..1246287ee2e62 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -4051,12 +4051,6 @@ class RecordDecl : public TagDecl {
     RecordDeclBits.ParamDestroyedInCallee = V;
   }
 
-  bool isRandomized() const { return RecordDeclBits.IsRandomized; }
-
-  void setIsRandomized(bool V) { RecordDeclBits.IsRandomized = V; }
-
-  void reorderFields(const SmallVectorImpl<Decl *> &Fields);
-
   /// Determines whether this declaration represents the
   /// injected class name.
   ///

diff  --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index a4a44e0b30e64..a89f776248c1f 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -313,7 +313,6 @@ class alignas(8) Decl {
   friend class ASTReader;
   friend class CXXClassMemberWrapper;
   friend class LinkageComputer;
-  friend class RecordDecl;
   template<typename decl_type> friend class Redeclarable;
 
   /// Access - Used by C++ decls for the access specifier.
@@ -1541,13 +1540,10 @@ class DeclContext {
 
     /// Represents the way this type is passed to a function.
     uint64_t ArgPassingRestrictions : 2;
-
-    /// Indicates whether this struct has had its field layout randomized.
-    uint64_t IsRandomized : 1;
   };
 
   /// Number of non-inherited bits in RecordDeclBitfields.
-  enum { NumRecordDeclBits = 15 };
+  enum { NumRecordDeclBits = 14 };
 
   /// Stores the bits used by OMPDeclareReductionDecl.
   /// If modified NumOMPDeclareReductionDeclBits and the accessor

diff  --git a/clang/include/clang/AST/Randstruct.h b/clang/include/clang/AST/Randstruct.h
deleted file mode 100644
index 0110e8c355551..0000000000000
--- a/clang/include/clang/AST/Randstruct.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//===- Randstruct.h - Interfact for structure randomization -------*- C++ -*-=//
-//
-// 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 the interface for Clang's structure field layout
-// randomization.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_RANDSTRUCT_H
-#define LLVM_CLANG_AST_RANDSTRUCT_H
-
-namespace llvm {
-template <typename T> class ArrayRef;
-template <typename T> class SmallVectorImpl;
-class StringRef;
-} // end namespace llvm
-
-namespace clang {
-
-class ASTContext;
-class Decl;
-class RecordDecl;
-
-namespace randstruct {
-
-bool randomizeStructureLayout(const ASTContext &Context, llvm::StringRef Name,
-                              llvm::ArrayRef<Decl *> Fields,
-                              llvm::SmallVectorImpl<Decl *> &FinalOrdering);
-
-} // namespace randstruct
-} // namespace clang
-
-#endif // LLVM_CLANG_AST_RANDSTRUCT_H

diff  --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index dee9ede951745..c7141ff463b38 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -3957,18 +3957,3 @@ def HLSLNumThreads: InheritableAttr {
   let LangOpts = [HLSL];
   let Documentation = [NumThreadsDocs];
 }
-
-def RandomizeLayout : InheritableAttr {
-  let Spellings = [GCC<"randomize_layout">];
-  let Subjects = SubjectList<[Record]>;
-  let Documentation = [ClangRandomizeLayoutDocs];
-  let LangOpts = [COnly];
-}
-
-def NoRandomizeLayout : InheritableAttr {
-  let Spellings = [GCC<"no_randomize_layout">];
-  let Subjects = SubjectList<[Record]>;
-  let Documentation = [ClangRandomizeLayoutDocs];
-  let LangOpts = [COnly];
-}
-def : MutualExclusions<[RandomizeLayout, NoRandomizeLayout]>;

diff  --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 6a8b2e600f949..89db454f7dac4 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -6379,35 +6379,3 @@ dictate the thread id. Total number of threads executed is ``X * Y * Z``.
 The full documentation is available here: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sm5-attributes-numthreads
   }];
 }
-
-def ClangRandomizeLayoutDocs : Documentation {
-  let Category = DocCatDecl;
-  let Heading = "randomize_layout, no_randomize_layout";
-  let Content = [{
-The attribute ``randomize_layout``, when attached to a C structure, selects it
-for structure layout field randomization; a compile-time hardening technique. A
-"seed" value, is specified via the ``-frandomize-layout-seed=`` command line flag.
-For example:
-
-.. code-block:: bash
-
-  SEED=`od -A n -t x8 -N 32 /dev/urandom | tr -d ' \n'`
-  make ... CFLAGS="-frandomize-layout-seed=$SEED" ...
-
-You can also supply the seed in a file with ``-frandomize-layout-seed-file=``.
-For example:
-
-.. code-block:: bash
-
-  od -A n -t x8 -N 32 /dev/urandom | tr -d ' \n' > /tmp/seed_file.txt
-  make ... CFLAGS="-frandomize-layout-seed-file=/tmp/seed_file.txt" ...
-
-The randomization is deterministic based for a given seed, so the entire
-program should be compiled with the same seed, but keep the seed safe
-otherwise.
-
-The attribute ``no_randomize_layout``, when attached to a C structure,
-instructs the compiler that this structure should not have its field layout
-randomized.
-  }];
-}

diff  --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 1100f775ed6ab..89260a5f4b47d 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -165,8 +165,6 @@ def err_drv_amdgpu_ieee_without_no_honor_nans : Error<
   "invalid argument '-mno-amdgpu-ieee' only allowed with relaxed NaN handling">;
 def err_drv_argument_not_allowed_with : Error<
   "invalid argument '%0' not allowed with '%1'">;
-def err_drv_cannot_open_randomize_layout_seed_file : Error<
-  "cannot read randomize layout seed file '%0'">;
 def err_drv_invalid_version_number : Error<
   "invalid version number in '%0'">;
 def err_drv_no_linker_llvm_support : Error<

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 3213163ee7876..d8fd33deae115 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11588,7 +11588,5 @@ def err_hlsl_numthreads_argument_oor : Error<"argument '%select{X|Y|Z}0' to numt
 def err_hlsl_numthreads_invalid : Error<"total number of threads cannot exceed %0">;
 def err_hlsl_attribute_param_mismatch : Error<"%0 attribute parameters do not match the previous declaration">;
 
-// Layout randomization warning.
-def err_cast_from_randomized_struct : Error<
-  "casting from randomized structure pointer type %0 to %1">;
 } // end of sema component.
+

diff  --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index f82992877c0b4..f5a2fd8461674 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -445,9 +445,6 @@ class LangOptions : public LangOptionsBase {
   /// The default stream kind used for HIP kernel launching.
   GPUDefaultStreamKind GPUDefaultStream;
 
-  /// The seed used by the randomize structure layout feature.
-  std::string RandstructSeed;
-
   LangOptions();
 
   // Define accessors/mutators for language options of enumeration type.

diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 98443b2757c93..799fd1b62f185 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2122,12 +2122,6 @@ defm merge_all_constants : BoolFOption<"merge-all-constants",
 def fmessage_length_EQ : Joined<["-"], "fmessage-length=">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Format message diagnostics so that they fit within N columns">,
   MarshallingInfoInt<DiagnosticOpts<"MessageLength">>;
-def frandomize_layout_seed_EQ : Joined<["-"], "frandomize-layout-seed=">,
-  MetaVarName<"<seed>">, Group<f_clang_Group>, Flags<[CC1Option]>,
-  HelpText<"The seed used by the randomize structure layout feature">;
-def frandomize_layout_seed_file_EQ : Joined<["-"], "frandomize-layout-seed-file=">,
-  MetaVarName<"<file>">, Group<f_clang_Group>, Flags<[CC1Option]>,
-  HelpText<"File holding the seed used by the randomize structure layout feature">;
 def fms_compatibility : Flag<["-"], "fms-compatibility">, Group<f_Group>, Flags<[CC1Option, CoreOption]>,
   HelpText<"Enable full Microsoft Visual C++ compatibility">,
   MarshallingInfoFlag<LangOpts<"MSVCCompat">>;

diff  --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index 24c8cb89c7ff6..9365a2272b3e7 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -97,7 +97,6 @@ add_clang_library(clangAST
   ParentMap.cpp
   PrintfFormatString.cpp
   QualTypeNames.cpp
-  Randstruct.cpp
   RawCommentList.cpp
   RecordLayout.cpp
   RecordLayoutBuilder.cpp

diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index c651fa22a0351..6af7a37dfc7b2 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -30,7 +30,6 @@
 #include "clang/AST/ODRHash.h"
 #include "clang/AST/PrettyDeclStackTrace.h"
 #include "clang/AST/PrettyPrinter.h"
-#include "clang/AST/Randstruct.h"
 #include "clang/AST/Redeclarable.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/TemplateBase.h"
@@ -4584,7 +4583,6 @@ RecordDecl::RecordDecl(Kind DK, TagKind TK, const ASTContext &C,
   setHasNonTrivialToPrimitiveCopyCUnion(false);
   setParamDestroyedInCallee(false);
   setArgPassingRestrictions(APK_CanPassInRegs);
-  setIsRandomized(false);
 }
 
 RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC,
@@ -4668,12 +4666,6 @@ bool RecordDecl::isMsStruct(const ASTContext &C) const {
   return hasAttr<MSStructAttr>() || C.getLangOpts().MSBitfields == 1;
 }
 
-void RecordDecl::reorderFields(const SmallVectorImpl<Decl *> &Fields) {
-  std::tie(FirstDecl, LastDecl) = DeclContext::BuildDeclChain(Fields, false);
-  LastDecl->NextInContextAndBits.setPointer(nullptr);
-  setIsRandomized(true);
-}
-
 void RecordDecl::LoadFieldsFromExternalStorage() const {
   ExternalASTSource *Source = getASTContext().getExternalSource();
   assert(hasExternalLexicalStorage() && Source && "No external storage?");

diff  --git a/clang/lib/AST/Randstruct.cpp b/clang/lib/AST/Randstruct.cpp
deleted file mode 100644
index 477915eade547..0000000000000
--- a/clang/lib/AST/Randstruct.cpp
+++ /dev/null
@@ -1,223 +0,0 @@
-//===--- Randstruct.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 the implementation for Clang's structure field layout
-// randomization.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/Randstruct.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/ASTDiagnostic.h"
-#include "clang/AST/Attr.h"
-#include "clang/Basic/Diagnostic.h"
-#include "llvm/ADT/SmallVector.h"
-
-#include <algorithm>
-#include <random>
-#include <set>
-#include <sstream>
-#include <string>
-
-using clang::ASTContext;
-using clang::FieldDecl;
-using llvm::SmallVector;
-
-namespace {
-
-// FIXME: Replace this with some discovery once that mechanism exists.
-enum { CACHE_LINE = 64 };
-
-// The Bucket class holds the struct fields we're trying to fill to a
-// cache-line.
-class Bucket {
-  SmallVector<FieldDecl *, 64> Fields;
-  int Size = 0;
-
-public:
-  virtual ~Bucket() = default;
-
-  SmallVector<FieldDecl *, 64> &fields() { return Fields; }
-  void addField(FieldDecl *Field, int FieldSize);
-  virtual bool canFit(int FieldSize) const {
-    return Size + FieldSize <= CACHE_LINE;
-  }
-  virtual bool isBitfieldRun() const { return false; }
-  bool full() const { return Size >= CACHE_LINE; }
-};
-
-void Bucket::addField(FieldDecl *Field, int FieldSize) {
-  Size += FieldSize;
-  Fields.push_back(Field);
-}
-
-struct BitfieldRunBucket : public Bucket {
-  bool canFit(int FieldSize) const override { return true; }
-  bool isBitfieldRun() const override { return true; }
-};
-
-void randomizeStructureLayoutImpl(const ASTContext &Context,
-                                  llvm::SmallVectorImpl<FieldDecl *> &FieldsOut,
-                                  std::mt19937 &RNG) {
-  // All of the Buckets produced by best-effort cache-line algorithm.
-  SmallVector<std::unique_ptr<Bucket>, 16> Buckets;
-
-  // The current bucket of fields that we are trying to fill to a cache-line.
-  std::unique_ptr<Bucket> CurrentBucket;
-
-  // The current bucket containing the run of adjacent bitfields to ensure they
-  // remain adjacent.
-  std::unique_ptr<BitfieldRunBucket> CurrentBitfieldRun;
-
-  // Tracks the number of fields that we failed to fit to the current bucket,
-  // and thus still need to be added later.
-  size_t Skipped = 0;
-
-  while (!FieldsOut.empty()) {
-    // If we've Skipped more fields than we have remaining to place, that means
-    // that they can't fit in our current bucket, and we need to start a new
-    // one.
-    if (Skipped >= FieldsOut.size()) {
-      Skipped = 0;
-      Buckets.push_back(std::move(CurrentBucket));
-    }
-
-    // Take the first field that needs to be put in a bucket.
-    auto FieldIter = FieldsOut.begin();
-    FieldDecl *FD = *FieldIter;
-
-    if (FD->isBitField() && !FD->isZeroLengthBitField(Context)) {
-      // Start a bitfield run if this is the first bitfield we have found.
-      if (!CurrentBitfieldRun)
-        CurrentBitfieldRun = std::make_unique<BitfieldRunBucket>();
-
-      // We've placed the field, and can remove it from the "awaiting Buckets"
-      // vector called "Fields."
-      CurrentBitfieldRun->addField(FD, /*FieldSize is irrelevant here*/ 1);
-      FieldsOut.erase(FieldIter);
-      continue;
-    }
-
-    // Else, current field is not a bitfield. If we were previously in a
-    // bitfield run, end it.
-    if (CurrentBitfieldRun)
-      Buckets.push_back(std::move(CurrentBitfieldRun));
-
-    // If we don't have a bucket, make one.
-    if (!CurrentBucket)
-      CurrentBucket = std::make_unique<Bucket>();
-
-    uint64_t Width = Context.getTypeInfo(FD->getType()).Width;
-    if (Width >= CACHE_LINE) {
-      std::unique_ptr<Bucket> OverSized = std::make_unique<Bucket>();
-      OverSized->addField(FD, Width);
-      FieldsOut.erase(FieldIter);
-      Buckets.push_back(std::move(OverSized));
-      continue;
-    }
-
-    // If it fits, add it.
-    if (CurrentBucket->canFit(Width)) {
-      CurrentBucket->addField(FD, Width);
-      FieldsOut.erase(FieldIter);
-
-      // If it's now full, tie off the bucket.
-      if (CurrentBucket->full()) {
-        Skipped = 0;
-        Buckets.push_back(std::move(CurrentBucket));
-      }
-    } else {
-      // We can't fit it in our current bucket. Move to the end for processing
-      // later.
-      ++Skipped; // Mark it skipped.
-      FieldsOut.push_back(FD);
-      FieldsOut.erase(FieldIter);
-    }
-  }
-
-  // Done processing the fields awaiting a bucket.
-
-  // If we were filling a bucket, tie it off.
-  if (CurrentBucket)
-    Buckets.push_back(std::move(CurrentBucket));
-
-  // If we were processing a bitfield run bucket, tie it off.
-  if (CurrentBitfieldRun)
-    Buckets.push_back(std::move(CurrentBitfieldRun));
-
-  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())
-      llvm::shuffle(std::begin(RandFields), std::end(RandFields), RNG);
-
-    FinalOrder.insert(FinalOrder.end(), RandFields.begin(), RandFields.end());
-  }
-
-  FieldsOut = FinalOrder;
-}
-
-} // anonymous namespace
-
-namespace clang {
-namespace randstruct {
-
-bool randomizeStructureLayout(const ASTContext &Context, StringRef Name,
-                              ArrayRef<Decl *> Fields,
-                              SmallVectorImpl<Decl *> &FinalOrdering) {
-  SmallVector<FieldDecl *, 64> RandomizedFields;
-
-  unsigned TotalNumFields = 0;
-  for (Decl *D : Fields) {
-    ++TotalNumFields;
-    if (auto *FD = dyn_cast<FieldDecl>(D))
-      RandomizedFields.push_back(FD);
-    else
-      FinalOrdering.push_back(D);
-  }
-
-  if (RandomizedFields.empty())
-    return false;
-
-  // Struct might end with a variable-length array or an array of size 0 or 1,
-  // in which case we don't want to randomize it.
-  FieldDecl *VLA = nullptr;
-  const auto *CA =
-      dyn_cast<ConstantArrayType>(RandomizedFields.back()->getType());
-  if ((CA && (CA->getSize().sle(2) || CA->isIncompleteArrayType())) ||
-      llvm::any_of(Fields, [](Decl *D) {
-        if (const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
-          const Type *FDTy = FD->getType().getTypePtr();
-          if (const RecordType *FDTTy = FDTy->getAs<RecordType>())
-            return FDTTy->getDecl()->hasFlexibleArrayMember();
-        }
-        return false;
-      }))
-    VLA = RandomizedFields.pop_back_val();
-
-  std::string Seed = (Context.getLangOpts().RandstructSeed + Name).str();
-  std::seed_seq SeedSeq(Seed.begin(), Seed.end());
-  std::mt19937 RNG(SeedSeq);
-
-  randomizeStructureLayoutImpl(Context, RandomizedFields, RNG);
-  if (VLA)
-    RandomizedFields.push_back(VLA);
-
-  FinalOrdering.insert(FinalOrdering.end(), RandomizedFields.begin(),
-                       RandomizedFields.end());
-
-  assert(TotalNumFields == FinalOrdering.size() &&
-         "Decl count has been altered after Randstruct randomization!");
-  return true;
-}
-
-} // end namespace randstruct
-} // end namespace clang

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 1601dba171d26..baac938412ec8 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5907,14 +5907,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
     CmdArgs.push_back(
         Args.MakeArgString("-fmessage-length=" + Twine(MessageLength)));
 
-  if (Arg *A = Args.getLastArg(options::OPT_frandomize_layout_seed_EQ))
-    CmdArgs.push_back(
-        Args.MakeArgString("-frandomize-layout-seed=" + Twine(A->getValue(0))));
-
-  if (Arg *A = Args.getLastArg(options::OPT_frandomize_layout_seed_file_EQ))
-    CmdArgs.push_back(Args.MakeArgString("-frandomize-layout-seed-file=" +
-                                         Twine(A->getValue(0))));
-
   // -fvisibility= and -fvisibility-ms-compat are of a piece.
   if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ,
                                      options::OPT_fvisibility_ms_compat)) {

diff  --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 5181999203b1e..83de27b3a4f1b 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -94,7 +94,6 @@
 #include <cassert>
 #include <cstddef>
 #include <cstring>
-#include <fstream>
 #include <memory>
 #include <string>
 #include <tuple>
@@ -3686,9 +3685,6 @@ void CompilerInvocation::GenerateLangArgs(const LangOptions &Opts,
 
   for (const auto &MP : Opts.MacroPrefixMap)
     GenerateArg(Args, OPT_fmacro_prefix_map_EQ, MP.first + "=" + MP.second, SA);
-
-  if (!Opts.RandstructSeed.empty())
-    GenerateArg(Args, OPT_frandomize_layout_seed_EQ, Opts.RandstructSeed, SA);
 }
 
 bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
@@ -4241,19 +4237,6 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
       Diags.Report(diag::err_cc1_unbounded_vscale_min);
   }
 
-  if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_file_EQ)) {
-    std::ifstream SeedFile(A->getValue(0));
-
-    if (!SeedFile.is_open())
-      Diags.Report(diag::err_drv_cannot_open_randomize_layout_seed_file)
-          << A->getValue(0);
-
-    std::getline(SeedFile, Opts.RandstructSeed);
-  }
-
-  if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_EQ))
-    Opts.RandstructSeed = A->getValue(0);
-
   return Diags.getNumErrors() == NumErrorsBefore;
 }
 

diff  --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 7b5bc7ca80b17..7d580dc5b6b3a 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -3129,23 +3129,6 @@ void CastOperation::CheckCStyleCast() {
     Self.Diag(OpRange.getBegin(), diag::warn_cast_function_type)
         << SrcType << DestType << OpRange;
 
-  if (isa<PointerType>(SrcType) && isa<PointerType>(DestType)) {
-    QualType SrcTy = cast<PointerType>(SrcType)->getPointeeType();
-    QualType DestTy = cast<PointerType>(DestType)->getPointeeType();
-
-    const RecordDecl *SrcRD = SrcTy->getAsRecordDecl();
-    const RecordDecl *DestRD = DestTy->getAsRecordDecl();
-
-    if (SrcRD && DestRD && SrcRD->hasAttr<RandomizeLayoutAttr>() &&
-        SrcRD != DestRD) {
-      // The struct we are casting the pointer from was randomized.
-      Self.Diag(OpRange.getBegin(), diag::err_cast_from_randomized_struct)
-          << SrcType << DestType;
-      SrcExpr = ExprError();
-      return;
-    }
-  }
-
   DiagnoseCastOfObjCSEL(Self, SrcExpr, DestType);
   DiagnoseCallingConvCast(Self, SrcExpr, DestType, OpRange);
   DiagnoseBadFunctionCast(Self, SrcExpr, DestType);

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a99b9833b3f53..51b630500f74f 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -24,7 +24,6 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/NonTrivialTypeVisitor.h"
-#include "clang/AST/Randstruct.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/PartialDiagnostic.h"
@@ -17969,18 +17968,6 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
     // Handle attributes before checking the layout.
     ProcessDeclAttributeList(S, Record, Attrs);
 
-    // Maybe randomize the field order.
-    if (!getLangOpts().CPlusPlus && Record->hasAttr<RandomizeLayoutAttr>() &&
-        !Record->isUnion() && !getLangOpts().RandstructSeed.empty() &&
-        !Record->isRandomized()) {
-      SmallVector<Decl *, 32> OrigFieldOrdering(Record->fields());
-      SmallVector<Decl *, 32> NewFieldOrdering;
-      if (randstruct::randomizeStructureLayout(
-              Context, Record->getNameAsString(), OrigFieldOrdering,
-              NewFieldOrdering))
-        Record->reorderFields(NewFieldOrdering);
-    }
-
     // We may have deferred checking for a deleted destructor. Check now.
     if (CXXRecord) {
       auto *Dtor = CXXRecord->getDestructor();

diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 843ddbd7e3229..4b5201db7517c 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5121,21 +5121,6 @@ static void handleLifetimeCategoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   }
 }
 
-static void handleRandomizeLayoutAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
-  if (checkAttrMutualExclusion<NoRandomizeLayoutAttr>(S, D, AL))
-    return;
-  if (!D->hasAttr<RandomizeLayoutAttr>())
-    D->addAttr(::new (S.Context) RandomizeLayoutAttr(S.Context, AL));
-}
-
-static void handleNoRandomizeLayoutAttr(Sema &S, Decl *D,
-                                        const ParsedAttr &AL) {
-  if (checkAttrMutualExclusion<RandomizeLayoutAttr>(S, D, AL))
-    return;
-  if (!D->hasAttr<NoRandomizeLayoutAttr>())
-    D->addAttr(::new (S.Context) NoRandomizeLayoutAttr(S.Context, AL));
-}
-
 bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
                                 const FunctionDecl *FD) {
   if (Attrs.isInvalid())
@@ -8650,12 +8635,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
   case ParsedAttr::AT_Section:
     handleSectionAttr(S, D, AL);
     break;
-  case ParsedAttr::AT_RandomizeLayout:
-    handleRandomizeLayoutAttr(S, D, AL);
-    break;
-  case ParsedAttr::AT_NoRandomizeLayout:
-    handleNoRandomizeLayoutAttr(S, D, AL);
-    break;
   case ParsedAttr::AT_CodeSeg:
     handleCodeSegAttr(S, D, AL);
     break;

diff  --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index 0713252385885..daae71f5167c4 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -104,7 +104,6 @@
 // CHECK-NEXT: NoMicroMips (SubjectMatchRule_function)
 // CHECK-NEXT: NoMips16 (SubjectMatchRule_function)
 // CHECK-NEXT: NoProfileFunction (SubjectMatchRule_function)
-// CHECK-NEXT: NoRandomizeLayout (SubjectMatchRule_record)
 // CHECK-NEXT: NoSanitize (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_variable_is_global)
 // CHECK-NEXT: NoSanitizeSpecific (SubjectMatchRule_function, SubjectMatchRule_variable_is_global)
 // CHECK-NEXT: NoSpeculativeLoadHardening (SubjectMatchRule_function, SubjectMatchRule_objc_method)
@@ -149,7 +148,6 @@
 // CHECK-NEXT: PassObjectSize (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: PatchableFunctionEntry (SubjectMatchRule_function, SubjectMatchRule_objc_method)
 // CHECK-NEXT: Pointer (SubjectMatchRule_record_not_is_union)
-// CHECK-NEXT: RandomizeLayout (SubjectMatchRule_record)
 // CHECK-NEXT: ReleaseHandle (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: RenderScriptKernel (SubjectMatchRule_function)
 // CHECK-NEXT: ReqdWorkGroupSize (SubjectMatchRule_function)

diff  --git a/clang/unittests/AST/CMakeLists.txt b/clang/unittests/AST/CMakeLists.txt
index 2dcef2d2fca0e..ab718d192024e 100644
--- a/clang/unittests/AST/CMakeLists.txt
+++ b/clang/unittests/AST/CMakeLists.txt
@@ -25,7 +25,6 @@ add_clang_unittest(ASTTests
   EvaluateAsRValueTest.cpp
   ExternalASTSourceTest.cpp
   NamedDeclPrinterTest.cpp
-  RandstructTest.cpp
   RecursiveASTVisitorTest.cpp
   SizelessTypesTest.cpp
   SourceLocationTest.cpp

diff  --git a/clang/unittests/AST/RandstructTest.cpp b/clang/unittests/AST/RandstructTest.cpp
deleted file mode 100644
index 932ef7b3c48cc..0000000000000
--- a/clang/unittests/AST/RandstructTest.cpp
+++ /dev/null
@@ -1,442 +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));
-}
-
-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");
-  const field_names Expected = {"lettuce", "bacon", "mayonnaise", "tomato"};
-
-  EXPECT_TRUE(RD->hasAttr<RandomizeLayoutAttr>());
-  EXPECT_TRUE(RD->isRandomized());
-  EXPECT_EQ(Expected, getFieldNamesFromRecord(RD));
-}
-
-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");
-
-  const field_names Expected = {"a", "b", "c", "x", "y", "z"};
-  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");
-  const field_names Expected = {"c", "a", "name", "b"};
-
-  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);
-    const field_names Expected = {"b", "a", "c", "d"};
-
-    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);
-    const field_names Expected = {"c", "b", "a"};
-
-    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 = {"a", "c", "b"};
-
-    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");
-  const field_names Expected = {"b", "a", ""};
-
-  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");
-  const field_names Expected = {"", "l", "r", "f", "a", "s", ""};
-
-  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()) {
-          const field_names Expected = {"c", "b", "e", "d", "f"};
-          EXPECT_EQ(Expected, getFieldNamesFromRecord(RD));
-        }
-      }
-    }
-
-  EXPECT_TRUE(AnonStructTested);
-  EXPECT_TRUE(AnonUnionTested);
-}
-
-} // namespace ast_matchers
-} // namespace clang

diff  --git a/llvm/utils/gn/secondary/clang/lib/AST/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/AST/BUILD.gn
index 3fb5981ef9328..aee4db327096f 100644
--- a/llvm/utils/gn/secondary/clang/lib/AST/BUILD.gn
+++ b/llvm/utils/gn/secondary/clang/lib/AST/BUILD.gn
@@ -126,7 +126,6 @@ static_library("AST") {
     "ParentMapContext.cpp",
     "PrintfFormatString.cpp",
     "QualTypeNames.cpp",
-    "Randstruct.cpp",
     "RawCommentList.cpp",
     "RecordLayout.cpp",
     "RecordLayoutBuilder.cpp",

diff  --git a/llvm/utils/gn/secondary/clang/unittests/AST/BUILD.gn b/llvm/utils/gn/secondary/clang/unittests/AST/BUILD.gn
index 803b9eb7eb105..c275553d01c96 100644
--- a/llvm/utils/gn/secondary/clang/unittests/AST/BUILD.gn
+++ b/llvm/utils/gn/secondary/clang/unittests/AST/BUILD.gn
@@ -34,7 +34,6 @@ unittest("ASTTests") {
     "EvaluateAsRValueTest.cpp",
     "ExternalASTSourceTest.cpp",
     "NamedDeclPrinterTest.cpp",
-    "RandstructTest.cpp",
     "RecursiveASTVisitorTest.cpp",
     "SizelessTypesTest.cpp",
     "SourceLocationTest.cpp",


        


More information about the llvm-commits mailing list