)]}'
{
  "commit": "00b6d032a22196bc14e4e30e413c040eb1b65da4",
  "tree": "1bc2dc7af5a7196fea5ceb6cc645deae14192222",
  "parents": [
    "1b5f72c5ece4442ca29ced45f8bcb25ed0d57790"
  ],
  "author": {
    "name": "Bill Wendling",
    "email": "5993918+bwendling@users.noreply.github.com",
    "time": "Wed Jan 10 15:21:10 2024 -0800"
  },
  "committer": {
    "name": "Bill Wendling",
    "email": "morbo@google.com",
    "time": "Tue Jan 16 14:26:12 2024 -0800"
  },
  "message": "[Clang] Implement the \u0027counted_by\u0027 attribute (#76348)\n\nThe \u0027counted_by\u0027 attribute is used on flexible array members. The\r\nargument for the attribute is the name of the field member holding the\r\ncount of elements in the flexible array. This information is used to\r\nimprove the results of the array bound sanitizer and the\r\n\u0027__builtin_dynamic_object_size\u0027 builtin. The \u0027count\u0027 field member must\r\nbe within the same non-anonymous, enclosing struct as the flexible array\r\nmember. For example:\r\n\r\n```\r\n  struct bar;\r\n  struct foo {\r\n    int count;\r\n    struct inner {\r\n      struct {\r\n        int count; /* The \u0027count\u0027 referenced by \u0027counted_by\u0027 */\r\n      };\r\n      struct {\r\n        /* ... */\r\n        struct bar *array[] __attribute__((counted_by(count)));\r\n      };\r\n    } baz;\r\n  };\r\n```\r\n\r\nThis example specifies that the flexible array member \u0027array\u0027 has the\r\nnumber of elements allocated for it in \u0027count\u0027:\r\n\r\n```\r\n  struct bar;\r\n  struct foo {\r\n    size_t count;\r\n     /* ... */\r\n    struct bar *array[] __attribute__((counted_by(count)));\r\n  };\r\n```\r\n\r\nThis establishes a relationship between \u0027array\u0027 and \u0027count\u0027;\r\nspecifically that \u0027p-\u003earray\u0027 must have *at least* \u0027p-\u003ecount\u0027 number of\r\nelements available. It\u0027s the user\u0027s responsibility to ensure that this\r\nrelationship is maintained throughout changes to the structure.\r\n\r\nIn the following, the allocated array erroneously has fewer elements\r\nthan what\u0027s specified by \u0027p-\u003ecount\u0027. This would result in an\r\nout-of-bounds access not not being detected:\r\n\r\n```\r\n  struct foo *p;\r\n\r\n  void foo_alloc(size_t count) {\r\n    p \u003d malloc(MAX(sizeof(struct foo),\r\n                   offsetof(struct foo, array[0]) + count *\r\n                       sizeof(struct bar *)));\r\n    p-\u003ecount \u003d count + 42;\r\n  }\r\n```\r\n\r\nThe next example updates \u0027p-\u003ecount\u0027, breaking the relationship\r\nrequirement that \u0027p-\u003earray\u0027 must have at least \u0027p-\u003ecount\u0027 number of\r\nelements available:\r\n\r\n```\r\n  void use_foo(int index, int val) {\r\n    p-\u003ecount +\u003d 42;\r\n    p-\u003earray[index] \u003d val; /* The sanitizer can\u0027t properly check this access */\r\n  }\r\n```\r\n\r\nIn this example, an update to \u0027p-\u003ecount\u0027 maintains the relationship\r\nrequirement:\r\n\r\n```\r\n  void use_foo(int index, int val) {\r\n    if (p-\u003ecount \u003d\u003d 0)\r\n      return;\r\n    --p-\u003ecount;\r\n    p-\u003earray[index] \u003d val;\r\n  }\r\n```",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "6c968c628dc14a9ebfa3f54454c0c08895637626",
      "old_mode": 33188,
      "old_path": "clang/docs/ReleaseNotes.rst",
      "new_id": "4bc91ef938bac72d9d4c264fc8e10d8a81ad2f14",
      "new_mode": 33188,
      "new_path": "clang/docs/ReleaseNotes.rst"
    },
    {
      "type": "modify",
      "old_id": "10dcbdb262d84e40c58b72a25a33e2ef5cf1ab0b",
      "old_mode": 33188,
      "old_path": "clang/include/clang/AST/DeclBase.h",
      "new_id": "5b1038582bc674700132386ff9687ef30ad86592",
      "new_mode": 33188,
      "new_path": "clang/include/clang/AST/DeclBase.h"
    },
    {
      "type": "modify",
      "old_id": "47b7a0292b7466a5520a52a7c91355baae8e7f56",
      "old_mode": 33188,
      "old_path": "clang/include/clang/Basic/Attr.td",
      "new_id": "b9ec720dd9e199c6e667849a06800d3d03fc5823",
      "new_mode": 33188,
      "new_path": "clang/include/clang/Basic/Attr.td"
    },
    {
      "type": "modify",
      "old_id": "b4bd55b783f447d3a48ea19f8a521135c80c0444",
      "old_mode": 33188,
      "old_path": "clang/include/clang/Basic/AttrDocs.td",
      "new_id": "9e8190614fbe8ab3518eecdcf07002ebc3237080",
      "new_mode": 33188,
      "new_path": "clang/include/clang/Basic/AttrDocs.td"
    },
    {
      "type": "modify",
      "old_id": "c3213f7ccb8c88e034dc64bc76f9879aa37c67fd",
      "old_mode": 33188,
      "old_path": "clang/include/clang/Basic/DiagnosticSemaKinds.td",
      "new_id": "414779a7970ab8eba710632854c1bdb18c4a8f0c",
      "new_mode": 33188,
      "new_path": "clang/include/clang/Basic/DiagnosticSemaKinds.td"
    },
    {
      "type": "modify",
      "old_id": "b55f7584913b466ea147c326bb8c2ca243d50e9f",
      "old_mode": 33188,
      "old_path": "clang/include/clang/Sema/Sema.h",
      "new_id": "4ef1fe542ea54f0cb62aa4c864b2d8afa08eb466",
      "new_mode": 33188,
      "new_path": "clang/include/clang/Sema/Sema.h"
    },
    {
      "type": "modify",
      "old_id": "e0f8d152dbe5545a56055ec2b554c0a37e93b889",
      "old_mode": 33188,
      "old_path": "clang/include/clang/Sema/TypoCorrection.h",
      "new_id": "09de164297e7baa982ef75db617647bd5d92b528",
      "new_mode": 33188,
      "new_path": "clang/include/clang/Sema/TypoCorrection.h"
    },
    {
      "type": "modify",
      "old_id": "c8085c5dd48a596db215bfb5a748bdebd9296a85",
      "old_mode": 33188,
      "old_path": "clang/lib/AST/ASTImporter.cpp",
      "new_id": "aa23c99b5990109e61088d56ffe69672c705c63e",
      "new_mode": 33188,
      "new_path": "clang/lib/AST/ASTImporter.cpp"
    },
    {
      "type": "modify",
      "old_id": "b1733c2d052a65ef654eddd6b8350749596f0500",
      "old_mode": 33188,
      "old_path": "clang/lib/AST/DeclBase.cpp",
      "new_id": "8163f9bdaf8d971063b4a533623ca1d3a6ac347d",
      "new_mode": 33188,
      "new_path": "clang/lib/AST/DeclBase.cpp"
    },
    {
      "type": "modify",
      "old_id": "a90f92d07f86d26b85a544a888487f5cc8169e72",
      "old_mode": 33188,
      "old_path": "clang/lib/AST/Expr.cpp",
      "new_id": "b125fc676da8419e737761b7db2a711df54adb46",
      "new_mode": 33188,
      "new_path": "clang/lib/AST/Expr.cpp"
    },
    {
      "type": "modify",
      "old_id": "ee6866dabaa89bca1586566106c98e198be9ffbe",
      "old_mode": 33188,
      "old_path": "clang/lib/CodeGen/CGBuiltin.cpp",
      "new_id": "de48b15645b1abe7ab6bc4944ffbb3c64f35cce0",
      "new_mode": 33188,
      "new_path": "clang/lib/CodeGen/CGBuiltin.cpp"
    },
    {
      "type": "modify",
      "old_id": "3f277725d9e7fc2a5e548124ce48501045bf3b95",
      "old_mode": 33188,
      "old_path": "clang/lib/CodeGen/CGExpr.cpp",
      "new_id": "d12e85b48d0b00b141aca52d39ba0cdfb5c38978",
      "new_mode": 33188,
      "new_path": "clang/lib/CodeGen/CGExpr.cpp"
    },
    {
      "type": "modify",
      "old_id": "07c7678df87eb8c5d257583bfd2f370934696deb",
      "old_mode": 33188,
      "old_path": "clang/lib/CodeGen/CodeGenFunction.h",
      "new_id": "143ad64e8816b12ee5297ab6689ca058b6e1aa96",
      "new_mode": 33188,
      "new_path": "clang/lib/CodeGen/CodeGenFunction.h"
    },
    {
      "type": "modify",
      "old_id": "793bb90da74d280218d57abc3fe7cb1820c7ae1f",
      "old_mode": 33188,
      "old_path": "clang/lib/Sema/SemaDecl.cpp",
      "new_id": "c6d00ddf5c1088532ee955c3a2d4803a61fe61a8",
      "new_mode": 33188,
      "new_path": "clang/lib/Sema/SemaDecl.cpp"
    },
    {
      "type": "modify",
      "old_id": "3c10c4e09c0c663f91768a0c5be033d9e84fc405",
      "old_mode": 33188,
      "old_path": "clang/lib/Sema/SemaDeclAttr.cpp",
      "new_id": "7e6881049d8d953aa07a653dacb8a4b3a1d62087",
      "new_mode": 33188,
      "new_path": "clang/lib/Sema/SemaDeclAttr.cpp"
    },
    {
      "type": "modify",
      "old_id": "2aa192c3909cbece023ea8f31bc2b52b192189ab",
      "old_mode": 33188,
      "old_path": "clang/lib/Sema/SemaExpr.cpp",
      "new_id": "049fdae09bb185c9cc1629ca9e9b0f4d8b9d2cc6",
      "new_mode": 33188,
      "new_path": "clang/lib/Sema/SemaExpr.cpp"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "74d5457e398b91dedfb0a7dd052202622d0e22e8",
      "new_mode": 33188,
      "new_path": "clang/test/CodeGen/attr-counted-by.c"
    },
    {
      "type": "modify",
      "old_id": "636d4f289e247863f1f312c57e03792f1d99f616",
      "old_mode": 33188,
      "old_path": "clang/test/CodeGen/bounds-checking.c",
      "new_id": "8100e30d0650adca140e08d8a262b45a32793128",
      "new_mode": 33188,
      "new_path": "clang/test/CodeGen/bounds-checking.c"
    },
    {
      "type": "modify",
      "old_id": "2f80c96e1d527187def063d915cf72ed3e84f612",
      "old_mode": 33188,
      "old_path": "clang/test/Misc/pragma-attribute-supported-attributes-list.test",
      "new_id": "e476c15b35ded939f4326e17707e5e3e53af8de0",
      "new_mode": 33188,
      "new_path": "clang/test/Misc/pragma-attribute-supported-attributes-list.test"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "f14da9c77fa8b42bb7d955b67150ffc8d4ffcb22",
      "new_mode": 33188,
      "new_path": "clang/test/Sema/attr-counted-by.c"
    }
  ]
}
