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 randomized structure needs to use a designated or default initializer.
Using a non-designated initializer will result in values being assigned
to the wrong fields.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D123763

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  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
@@ -156,68 +156,6 @@
   EXPECT_TRUE(RD->isRandomized());
 }
 
-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 {
@@ -417,5 +355,133 @@
   EXPECT_TRUE(AnonUnionTested);
 }
 
+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, RandomizedStructWithDesignatedInit) {
+  const std::unique_ptr<ASTUnit> AST = makeAST(R"c(
+    typedef void (*func_ptr)();
+
+    void foo(void);
+    void bar(void);
+    void baz(void);
+    void gaz(void);
+
+    struct test {
+        func_ptr a;
+        func_ptr b;
+        func_ptr c;
+        func_ptr d;
+        func_ptr e;
+        func_ptr f;
+        func_ptr g;
+    } __attribute__((randomize_layout)) inst = {
+      .f = baz, .b = bar, .g = gaz, .a = foo
+    };
+  )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(), 0u);
+  EXPECT_EQ(Diags.getNumErrors(), 0u);
+}
+
+TEST(RANDSTRUCT_TEST, RandomizedStructWithNonDesignatedInit) {
+  const std::unique_ptr<ASTUnit> AST = makeAST(R"c(
+    typedef void (*func_ptr)();
+
+    void foo(void);
+    void bar(void);
+    void baz(void);
+    void gaz(void);
+
+    struct test {
+        func_ptr a;
+        func_ptr b;
+        func_ptr c;
+        func_ptr d;
+        func_ptr e;
+        func_ptr f;
+        func_ptr g;
+    } __attribute__((randomize_layout)) inst = {
+      baz, bar, gaz, foo
+    };
+  )c");
+
+  EXPECT_TRUE(AST->getDiagnostics().hasErrorOccurred());
+
+  DiagnosticsEngine &Diags = AST->getDiagnostics();
+
+  EXPECT_FALSE(Diags.hasFatalErrorOccurred());
+  EXPECT_TRUE(Diags.hasUncompilableErrorOccurred());
+  EXPECT_TRUE(Diags.hasUnrecoverableErrorOccurred());
+  EXPECT_EQ(Diags.getNumWarnings(), 0u);
+  EXPECT_EQ(Diags.getNumErrors(), 1u);
+}
+
 } // namespace ast_matchers
 } // namespace clang
Index: clang/lib/Sema/SemaInit.cpp
===================================================================
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -2176,6 +2176,14 @@
       break;
     }
 
+    // Don't allow non-designated initializers on randomized structures.
+    if (RD->isRandomized()) {
+      if (!VerifyOnly)
+        SemaRef.Diag(InitLoc, diag::err_non_designated_init_used);
+      hadError = true;
+      break;
+    }
+
     // We've already initialized a member of a union. We're done.
     if (InitializedSomething && DeclType->isUnionType())
       break;
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11588,7 +11588,10 @@
 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.
+// Layout randomization diagnostics.
+def err_non_designated_init_used : Error<
+  "non-designated initializers cannot be used on a randomized struct">;
 def err_cast_from_randomized_struct : Error<
   "casting from randomized structure pointer type %0 to %1">;
+
 } // end of sema component.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to