[clang] a58d0af - Revert D121556 "[randstruct] Add randomize structure layout support"
Fangrui Song via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 8 18:37:31 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 cfe-commits
mailing list