void created this revision.
void added reviewers: aaron.ballman, MaskRay.
Herald added a subscriber: StephenFan.
Herald added a project: All.
void requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

A record may have more than just FieldDecls in it. If so, then we're
likely to drop them if we only randomize the FieldDecls.

Link: https://github.com/KSPP/linux/issues/185


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D123958

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/unittests/AST/RandstructTest.cpp

Index: clang/unittests/AST/RandstructTest.cpp
===================================================================
--- clang/unittests/AST/RandstructTest.cpp
+++ clang/unittests/AST/RandstructTest.cpp
@@ -159,9 +159,12 @@
   EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
 
   const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test");
+  long OriginalDeclCount = std::distance(RD->decls_begin(), RD->decls_end());
 
   EXPECT_FALSE(RD->hasAttr<RandomizeLayoutAttr>());
   EXPECT_FALSE(RD->isRandomized());
+  EXPECT_EQ(OriginalDeclCount,
+            std::distance(RD->decls_begin(), RD->decls_end()));
 }
 
 TEST(RANDSTRUCT_TEST, MarkedNoRandomize) {
@@ -177,9 +180,12 @@
   EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
 
   const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test");
+  long OriginalDeclCount = std::distance(RD->decls_begin(), RD->decls_end());
 
   EXPECT_TRUE(RD->hasAttr<NoRandomizeLayoutAttr>());
   EXPECT_FALSE(RD->isRandomized());
+  EXPECT_EQ(OriginalDeclCount,
+            std::distance(RD->decls_begin(), RD->decls_end()));
 }
 
 TEST(RANDSTRUCT_TEST, MarkedRandomize) {
@@ -195,9 +201,12 @@
   EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
 
   const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test");
+  long OriginalDeclCount = std::distance(RD->decls_begin(), RD->decls_end());
 
   EXPECT_TRUE(RD->hasAttr<RandomizeLayoutAttr>());
   EXPECT_TRUE(RD->isRandomized());
+  EXPECT_EQ(OriginalDeclCount,
+            std::distance(RD->decls_begin(), RD->decls_end()));
 }
 
 TEST(RANDSTRUCT_TEST, MismatchedAttrsDeclVsDef) {
@@ -280,11 +289,14 @@
   EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
 
   const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test");
+  long OriginalDeclCount = std::distance(RD->decls_begin(), RD->decls_end());
   const field_names Actual = getFieldNamesFromRecord(RD);
   const field_names Subseq = {"x", "y", "z"};
 
   EXPECT_TRUE(RD->isRandomized());
   EXPECT_TRUE(isSubsequence(Actual, Subseq));
+  EXPECT_EQ(OriginalDeclCount,
+            std::distance(RD->decls_begin(), RD->decls_end()));
 }
 
 TEST(RANDSTRUCT_TEST, CheckVariableLengthArrayMemberRemainsAtEndOfStructure) {
@@ -300,8 +312,11 @@
   EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
 
   const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test");
+  long OriginalDeclCount = std::distance(RD->decls_begin(), RD->decls_end());
 
   EXPECT_TRUE(RD->isRandomized());
+  EXPECT_EQ(OriginalDeclCount,
+            std::distance(RD->decls_begin(), RD->decls_end()));
 }
 
 TEST(RANDSTRUCT_TEST, RandstructDoesNotOverrideThePackedAttr) {
@@ -340,9 +355,12 @@
         getRecordDeclFromAST(AST->getASTContext(), "test_struct");
     const ASTRecordLayout *Layout =
         &AST->getASTContext().getASTRecordLayout(RD);
+    long OriginalDeclCount = std::distance(RD->decls_begin(), RD->decls_end());
 
     EXPECT_TRUE(RD->isRandomized());
     EXPECT_EQ(19, Layout->getSize().getQuantity());
+    EXPECT_EQ(OriginalDeclCount,
+              std::distance(RD->decls_begin(), RD->decls_end()));
   }
 
   {
@@ -350,9 +368,12 @@
         getRecordDeclFromAST(AST->getASTContext(), "another_struct");
     const ASTRecordLayout *Layout =
         &AST->getASTContext().getASTRecordLayout(RD);
+    long OriginalDeclCount = std::distance(RD->decls_begin(), RD->decls_end());
 
     EXPECT_TRUE(RD->isRandomized());
     EXPECT_EQ(10, Layout->getSize().getQuantity());
+    EXPECT_EQ(OriginalDeclCount,
+              std::distance(RD->decls_begin(), RD->decls_end()));
   }
 
   {
@@ -360,9 +381,12 @@
         getRecordDeclFromAST(AST->getASTContext(), "last_struct");
     const ASTRecordLayout *Layout =
         &AST->getASTContext().getASTRecordLayout(RD);
+    long OriginalDeclCount = std::distance(RD->decls_begin(), RD->decls_end());
 
     EXPECT_TRUE(RD->isRandomized());
     EXPECT_EQ(9, Layout->getSize().getQuantity());
+    EXPECT_EQ(OriginalDeclCount,
+              std::distance(RD->decls_begin(), RD->decls_end()));
   }
 }
 
@@ -378,8 +402,11 @@
   EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
 
   const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test");
+  long OriginalDeclCount = std::distance(RD->decls_begin(), RD->decls_end());
 
   EXPECT_TRUE(RD->isRandomized());
+  EXPECT_EQ(OriginalDeclCount,
+            std::distance(RD->decls_begin(), RD->decls_end()));
 }
 
 TEST(RANDSTRUCT_TEST, RandstructDoesNotRandomizeUnionFieldOrder) {
@@ -396,10 +423,12 @@
 
   EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
 
-  const RecordDecl *RD =
-      getRecordDeclFromAST(AST->getASTContext(), "test");
+  const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test");
+  long OriginalDeclCount = std::distance(RD->decls_begin(), RD->decls_end());
 
   EXPECT_FALSE(RD->isRandomized());
+  EXPECT_EQ(OriginalDeclCount,
+            std::distance(RD->decls_begin(), RD->decls_end()));
 }
 
 TEST(RANDSTRUCT_TEST, AnonymousStructsAndUnionsRetainFieldOrder) {
@@ -436,8 +465,11 @@
   EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
 
   const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test");
+  long OriginalDeclCount = std::distance(RD->decls_begin(), RD->decls_end());
 
   EXPECT_TRUE(RD->isRandomized());
+  EXPECT_EQ(OriginalDeclCount,
+            std::distance(RD->decls_begin(), RD->decls_end()));
 
   bool AnonStructTested = false;
   bool AnonUnionTested = false;
@@ -467,5 +499,35 @@
   EXPECT_TRUE(AnonUnionTested);
 }
 
+TEST(RANDSTRUCT_TEST, AnonymousStructsAndUnionsReferenced) {
+  std::unique_ptr<ASTUnit> AST = makeAST(R"c(
+    struct test {
+        int bacon;
+        long lettuce;
+        struct { double avocado; char blech; };
+        long long tomato;
+        union { char toast[8]; unsigned toast_thing; };
+        float mayonnaise;
+    } __attribute__((randomize_layout));
+
+    int foo(struct test *t) {
+      return t->blech;
+    }
+
+    char *bar(struct test *t) {
+      return t->toast;
+    }
+  )c");
+
+  EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
+
+  const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test");
+  long OriginalDeclCount = std::distance(RD->decls_begin(), RD->decls_end());
+
+  EXPECT_TRUE(RD->isRandomized());
+  EXPECT_EQ(OriginalDeclCount,
+            std::distance(RD->decls_begin(), RD->decls_end()));
+}
+
 } // namespace ast_matchers
 } // namespace clang
Index: clang/lib/Sema/SemaInit.cpp
===================================================================
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -2123,7 +2123,7 @@
   // worthwhile to skip over the rest of the initializer, though.
   RecordDecl *RD = DeclType->castAs<RecordType>()->getDecl();
   RecordDecl::field_iterator FieldEnd = RD->field_end();
-  size_t NumRecordFields = std::distance(RD->field_begin(), RD->field_end());
+  size_t NumRecordFields = std::distance(RD->decls_begin(), RD->decls_end());
   bool CheckForMissingFields =
     !IList->isIdiomaticZeroInitializer(SemaRef.getLangOpts());
   bool HasDesignatedInit = false;
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -18046,7 +18046,7 @@
     if (!getLangOpts().CPlusPlus && Record->hasAttr<RandomizeLayoutAttr>() &&
         !Record->isUnion() && !getLangOpts().RandstructSeed.empty() &&
         !Record->isRandomized()) {
-      SmallVector<Decl *, 32> OrigFieldOrdering(Record->fields());
+      SmallVector<Decl *, 32> OrigFieldOrdering(Record->decls());
       SmallVector<Decl *, 32> NewFieldOrdering;
       if (randstruct::randomizeStructureLayout(
               Context, Record->getNameAsString(), OrigFieldOrdering,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to