https://github.com/fmayer updated 
https://github.com/llvm/llvm-project/pull/126163

>From e9f2dbecb2b4836100a565b4c741fc3425d08966 Mon Sep 17 00:00:00 2001
From: Florian Mayer <fma...@google.com>
Date: Thu, 6 Feb 2025 16:50:02 -0800
Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
 =?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.4
---
 clang/include/clang/Basic/LangOptions.def |  3 ++
 clang/include/clang/Basic/LangOptions.h   | 13 +++++++++
 clang/include/clang/Driver/Options.td     | 15 ++++++++++
 clang/lib/CodeGen/CGExpr.cpp              | 34 +++++++++++++++++++++--
 clang/lib/CodeGen/CodeGenFunction.h       |  1 +
 clang/lib/Driver/ToolChains/Clang.cpp     |  2 ++
 clang/test/CodeGen/bounds-checking-fam.c  | 10 +++++++
 7 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index cb55f09acc076cf..590237eb4f40baf 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -481,6 +481,9 @@ LANGOPT(RawStringLiterals, 1, 1, "Enable or disable raw 
string literals")
 ENUM_LANGOPT(StrictFlexArraysLevel, StrictFlexArraysLevelKind, 2,
              StrictFlexArraysLevelKind::Default,
              "Rely on strict definition of flexible arrays")
+ENUM_LANGOPT(ArrayBoundsStrictFlexArraysLevel, 
ArrayBoundsStrictFlexArraysLevelKind, 3,
+             ArrayBoundsStrictFlexArraysLevelKind::None,
+             "Definition of flexible arrays for bounds checks")
 
 COMPATIBLE_VALUE_LANGOPT(MaxTokens, 32, 0, "Max number of tokens per TU or 0")
 
diff --git a/clang/include/clang/Basic/LangOptions.h 
b/clang/include/clang/Basic/LangOptions.h
index f58a719a45a84de..597165dfc24044c 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -444,6 +444,19 @@ class LangOptionsBase {
     IncompleteOnly = 3,
   };
 
+  enum class ArrayBoundsStrictFlexArraysLevelKind {
+    // Use same StrictFlexArrayLevel as compiler.
+    None = 0,
+    /// Any trailing array member is a FAM.
+    Default = 1,
+    /// Any trailing array member of undefined, 0, or 1 size is a FAM.
+    OneZeroOrIncomplete = 2,
+    /// Any trailing array member of undefined or 0 size is a FAM.
+    ZeroOrIncomplete = 3,
+    /// Any trailing array member of undefined size is a FAM.
+    IncompleteOnly = 4,
+  };
+
   /// Controls the various implementations for complex multiplication and
   // division.
   enum ComplexRangeKind {
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 77ca2d2aac31be1..3ae768206a34b71 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1533,6 +1533,21 @@ def fstrict_flex_arrays_EQ : Joined<["-"], 
"fstrict-flex-arrays=">, Group<f_Grou
   NormalizedValues<["Default", "OneZeroOrIncomplete", "ZeroOrIncomplete", 
"IncompleteOnly"]>,
   HelpText<"Enable optimizations based on the strict definition of flexible 
arrays">,
   MarshallingInfoEnum<LangOpts<"StrictFlexArraysLevel">, "Default">;
+// We might want a different (generally stricter) definition of flexible arrays
+// for sanitization than for the codegen.
+def fsanitize_array_bounds_strict_flex_arrays_EQ
+    : Joined<["-"], "fsanitize-bounds-strict-flex-arrays=">,
+      Group<f_Group>,
+      MetaVarName<"<n>">,
+      Values<"none,0,1,2,3">,
+      LangOpts<"ArrayBoundsStrictFlexArraysLevel">,
+      Visibility<[ClangOption, CC1Option]>,
+      NormalizedValuesScope<
+          "LangOptions::ArrayBoundsStrictFlexArraysLevelKind">,
+      NormalizedValues<["None", "Default", "OneZeroOrIncomplete",
+                        "ZeroOrIncomplete", "IncompleteOnly"]>,
+      HelpText<"Set definition of flexible arrays for bounds checks">,
+      MarshallingInfoEnum<LangOpts<"ArrayBoundsStrictFlexArraysLevel">, 
"None">;
 defm apple_pragma_pack : BoolFOption<"apple-pragma-pack",
   LangOpts<"ApplePragmaPack">, DefaultFalse,
   PosFlag<SetTrue, [], [ClangOption, CC1Option],
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 1e233c42c8782df..d2540d209f23d9c 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -31,6 +31,7 @@
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/CodeGenOptions.h"
+#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
@@ -1192,13 +1193,40 @@ llvm::Value *CodeGenFunction::EmitLoadOfCountedByField(
   return nullptr;
 }
 
+LangOptions::StrictFlexArraysLevelKind
+CodeGenFunction::effectiveArrayBoundsFlexArraysLevel() {
+  using StrictFlexArraysLevelKind = LangOptions::StrictFlexArraysLevelKind;
+  using ArrayBoundsStrictFlexArraysLevelKind =
+      LangOptions::ArrayBoundsStrictFlexArraysLevelKind;
+  StrictFlexArraysLevelKind StrictFlexArraysLevel;
+  switch (getLangOpts().getArrayBoundsStrictFlexArraysLevel()) {
+  case ArrayBoundsStrictFlexArraysLevelKind::Default:
+    StrictFlexArraysLevel = StrictFlexArraysLevelKind::Default;
+    break;
+  case ArrayBoundsStrictFlexArraysLevelKind::OneZeroOrIncomplete:
+    StrictFlexArraysLevel = StrictFlexArraysLevelKind::OneZeroOrIncomplete;
+    break;
+  case ArrayBoundsStrictFlexArraysLevelKind::ZeroOrIncomplete:
+    StrictFlexArraysLevel = StrictFlexArraysLevelKind::ZeroOrIncomplete;
+    break;
+  case ArrayBoundsStrictFlexArraysLevelKind::IncompleteOnly:
+    StrictFlexArraysLevel = StrictFlexArraysLevelKind::IncompleteOnly;
+    break;
+  case ArrayBoundsStrictFlexArraysLevelKind::None:
+    StrictFlexArraysLevel = getLangOpts().getStrictFlexArraysLevel();
+    break;
+  }
+  return StrictFlexArraysLevel;
+}
+
 void CodeGenFunction::EmitBoundsCheck(const Expr *E, const Expr *Base,
                                       llvm::Value *Index, QualType IndexType,
                                       bool Accessed) {
   assert(SanOpts.has(SanitizerKind::ArrayBounds) &&
          "should not be called unless adding bounds checks");
-  const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel =
-      getLangOpts().getStrictFlexArraysLevel();
+  LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel =
+      effectiveArrayBoundsFlexArraysLevel();
+
   QualType IndexedType;
   llvm::Value *Bound =
       getArrayIndexingBound(*this, Base, IndexedType, StrictFlexArraysLevel);
@@ -4383,7 +4411,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const 
ArraySubscriptExpr *E,
       // i.e. "a.b.count", so we shouldn't need the full force of EmitLValue or
       // similar to emit the correct GEP.
       const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel =
-          getLangOpts().getStrictFlexArraysLevel();
+          effectiveArrayBoundsFlexArraysLevel();
 
       if (const auto *ME = dyn_cast<MemberExpr>(Array);
           ME &&
diff --git a/clang/lib/CodeGen/CodeGenFunction.h 
b/clang/lib/CodeGen/CodeGenFunction.h
index e7a5100a9fa2946..62067c8bd9a802b 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -3315,6 +3315,7 @@ class CodeGenFunction : public CodeGenTypeCache {
                      SanitizerSet SkippedChecks = SanitizerSet(),
                      llvm::Value *ArraySize = nullptr);
 
+  LangOptions::StrictFlexArraysLevelKind effectiveArrayBoundsFlexArraysLevel();
   /// Emit a check that \p Base points into an array object, which
   /// we can access at index \p Index. \p Accessed should be \c false if we
   /// this expression is used as an lvalue, for instance in "&Arr[Idx]".
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index c0891d46b0a62cd..ce937adcb946004 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6976,6 +6976,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
                   options::OPT_fno_unroll_loops);
 
   Args.AddLastArg(CmdArgs, options::OPT_fstrict_flex_arrays_EQ);
+  Args.AddLastArg(CmdArgs,
+                  options::OPT_fsanitize_array_bounds_strict_flex_arrays_EQ);
 
   Args.AddLastArg(CmdArgs, options::OPT_pthread);
 
diff --git a/clang/test/CodeGen/bounds-checking-fam.c 
b/clang/test/CodeGen/bounds-checking-fam.c
index ae211c49ca1f552..dcfe99fa6ff6d91 100644
--- a/clang/test/CodeGen/bounds-checking-fam.c
+++ b/clang/test/CodeGen/bounds-checking-fam.c
@@ -7,6 +7,16 @@
 // RUN: %clang_cc1 -emit-llvm -triple x86_64 -fstrict-flex-arrays=2 
-fsanitize=array-bounds -x c++ %s -o - | FileCheck %s 
--check-prefixes=CHECK,CHECK-STRICT-2,CXX
 // RUN: %clang_cc1 -emit-llvm -triple x86_64 -fstrict-flex-arrays=3 
-fsanitize=array-bounds        %s -o - | FileCheck %s 
--check-prefixes=CHECK,CHECK-STRICT-3
 // RUN: %clang_cc1 -emit-llvm -triple x86_64 -fstrict-flex-arrays=3 
-fsanitize=array-bounds -x c++ %s -o - | FileCheck %s 
--check-prefixes=CHECK,CHECK-STRICT-3,CXX
+
+// RUN: %clang_cc1 -emit-llvm -triple x86_64 
-fsanitize-bounds-strict-flex-arrays=0 -fsanitize=array-bounds -x c++ %s -o - | 
FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-0,CXX,CXX-STRICT-0
+// RUN: %clang_cc1 -emit-llvm -triple x86_64 
-fsanitize-bounds-strict-flex-arrays=0 -fsanitize=array-bounds        %s -o - | 
FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-0
+// RUN: %clang_cc1 -emit-llvm -triple x86_64 
-fsanitize-bounds-strict-flex-arrays=1 -fsanitize=array-bounds        %s -o - | 
FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-1
+// RUN: %clang_cc1 -emit-llvm -triple x86_64 
-fsanitize-bounds-strict-flex-arrays=1 -fsanitize=array-bounds -x c++ %s -o - | 
FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-1,CXX
+// RUN: %clang_cc1 -emit-llvm -triple x86_64 
-fsanitize-bounds-strict-flex-arrays=2 -fsanitize=array-bounds        %s -o - | 
FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-2
+// RUN: %clang_cc1 -emit-llvm -triple x86_64 
-fsanitize-bounds-strict-flex-arrays=2 -fsanitize=array-bounds -x c++ %s -o - | 
FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-2,CXX
+// RUN: %clang_cc1 -emit-llvm -triple x86_64 
-fsanitize-bounds-strict-flex-arrays=3 -fsanitize=array-bounds        %s -o - | 
FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-3
+// RUN: %clang_cc1 -emit-llvm -triple x86_64 
-fsanitize-bounds-strict-flex-arrays=3 -fsanitize=array-bounds -x c++ %s -o - | 
FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-3,CXX
+
 // Before flexible array member was added to C99, many projects use a
 // one-element array as the last member of a structure as an alternative.
 // E.g. https://github.com/python/cpython/issues/84301

>From cde09da532846cce988a6ce68b16b441e369db11 Mon Sep 17 00:00:00 2001
From: Florian Mayer <fma...@google.com>
Date: Fri, 7 Feb 2025 17:15:05 -0800
Subject: [PATCH 2/2] nit

Created using spr 1.3.4
---
 clang/lib/CodeGen/CGExpr.cpp | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d2540d209f23d9c..3f04d0393bf9c6e 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1198,25 +1198,18 @@ CodeGenFunction::effectiveArrayBoundsFlexArraysLevel() {
   using StrictFlexArraysLevelKind = LangOptions::StrictFlexArraysLevelKind;
   using ArrayBoundsStrictFlexArraysLevelKind =
       LangOptions::ArrayBoundsStrictFlexArraysLevelKind;
-  StrictFlexArraysLevelKind StrictFlexArraysLevel;
   switch (getLangOpts().getArrayBoundsStrictFlexArraysLevel()) {
   case ArrayBoundsStrictFlexArraysLevelKind::Default:
-    StrictFlexArraysLevel = StrictFlexArraysLevelKind::Default;
-    break;
+    return StrictFlexArraysLevelKind::Default;
   case ArrayBoundsStrictFlexArraysLevelKind::OneZeroOrIncomplete:
-    StrictFlexArraysLevel = StrictFlexArraysLevelKind::OneZeroOrIncomplete;
-    break;
+    return StrictFlexArraysLevelKind::OneZeroOrIncomplete;
   case ArrayBoundsStrictFlexArraysLevelKind::ZeroOrIncomplete:
-    StrictFlexArraysLevel = StrictFlexArraysLevelKind::ZeroOrIncomplete;
-    break;
+    return StrictFlexArraysLevelKind::ZeroOrIncomplete;
   case ArrayBoundsStrictFlexArraysLevelKind::IncompleteOnly:
-    StrictFlexArraysLevel = StrictFlexArraysLevelKind::IncompleteOnly;
-    break;
+    return StrictFlexArraysLevelKind::IncompleteOnly;
   case ArrayBoundsStrictFlexArraysLevelKind::None:
-    StrictFlexArraysLevel = getLangOpts().getStrictFlexArraysLevel();
-    break;
+    return getLangOpts().getStrictFlexArraysLevel();
   }
-  return StrictFlexArraysLevel;
 }
 
 void CodeGenFunction::EmitBoundsCheck(const Expr *E, const Expr *Base,

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to