)]}'
{
  "commit": "e27771e5dcd8cf2cb757db6177a3485acd28b88f",
  "tree": "3e20a8f7438b874abb66dd4d0c83d8c68a77300b",
  "parents": [
    "1ba7adabf29eb671e418692fad076ea6edd08e3d"
  ],
  "author": {
    "name": "Jonathan Wakely",
    "email": "jwakely@redhat.com",
    "time": "Fri Oct 15 10:58:56 2021 +0100"
  },
  "committer": {
    "name": "Jonathan Wakely",
    "email": "jwakely@redhat.com",
    "time": "Fri Oct 15 18:26:53 2021 +0100"
  },
  "message": "libstdc++: Remove try/catch overhead in std::variant::emplace\n\nThe __variant_construct_by_index helper function sets the new index\nbefore constructing the new object. This means that if the construction\nthrows then the exception needs to be caught, so the index can be reset\nto variant_npos, and then the exception rethrown. This means callers are\nresponsible for restoring the variant\u0027s invariants and they need the\noverhead of a catch handler and a rethrow.\n\nIf we don\u0027t set the index until after construction completes then the\ninvariant is never broken, and callers can ignore the exception and let\nit propagate. The callers all call _M_reset() first, which sets index to\nvariant_npos as required while the variant is valueless.\n\nWe need to be slightly careful here, because changing the order of\noperations in __variant_construct_by_index and removing the try-block\nfrom variant::emplace\u003cI\u003e changes an implicit ABI contract between those\ntwo functions. If the linker were to create an executable containing an\ninstantiation of the old __variant_construct_by_index and an\ninstantiation of the new variant::emplace\u003cI\u003e code then we would have a\ncombination that breaks the invariant and doesn\u0027t have the exception\nhandling to restore it. To avoid this problem, we can rename the\n__variant_construct_by_index function so that the new emplace\u003cI\u003e code\ncalls a new symbol, and is unaffected by the behaviour of the old\nsymbol.\n\nlibstdc++-v3/ChangeLog:\n\n\t* include/std/variant (__detail::__variant::__get_storage):\n\tRemove unused function.\n\t(__variant_construct_by_index): Set index after construction is\n\tcomplete. Rename to ...\n\t(__detail::__variant::__construct_by_index): ... this.\n\t(variant): Use new name for __variant_construct_by_index friend\n\tdeclaration. Remove __get_storage friend declaration.\n\t(variant::emplace): Use new name and remove try-blocks.\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "4a6826b7ba6aad6752b4adbd33d33ea68915f04d",
      "old_mode": 33188,
      "old_path": "libstdc++-v3/include/std/variant",
      "new_id": "f49094130ee0c31ca3773d1b0e76cc389893d993",
      "new_mode": 33188,
      "new_path": "libstdc++-v3/include/std/variant"
    }
  ]
}
