Hello community,

here is the log from the commit of package chromium for openSUSE:Factory 
checked in at 2019-05-02 19:17:20
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/chromium (Old)
 and      /work/SRC/openSUSE:Factory/.chromium.new.5148 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "chromium"

Thu May  2 19:17:20 2019 rev:216 rq:699638 version:74.0.3729.108

Changes:
--------
--- /work/SRC/openSUSE:Factory/chromium/chromium.changes        2019-04-08 
10:35:47.599229655 +0200
+++ /work/SRC/openSUSE:Factory/.chromium.new.5148/chromium.changes      
2019-05-02 19:17:47.117469129 +0200
@@ -1,0 +2,43 @@
+Tue Apr 30 09:04:56 UTC 2019 - Tomáš Chvátal <[email protected]>
+
+- Update to 74.0.3729.108 bsc#1133313:
+  * CVE-2019-5805: Use after free in PDFium
+  * CVE-2019-5806: Integer overflow in Angle
+  * CVE-2019-5807: Memory corruption in V8
+  * CVE-2019-5808: Use after free in Blink
+  * CVE-2019-5809: Use after free in Blink
+  * CVE-2019-5810: User information disclosure in Autofill
+  * CVE-2019-5811: CORS bypass in Blink
+  * CVE-2019-5813: Out of bounds read in V8
+  * CVE-2019-5814: CORS bypass in Blink
+  * CVE-2019-5815: Heap buffer overflow in Blink
+  * CVE-2019-5818: Uninitialized value in media reader
+  * CVE-2019-5819: Incorrect escaping in developer tools
+  * CVE-2019-5820: Integer overflow in PDFium
+  * CVE-2019-5821: Integer overflow in PDFium
+  * CVE-2019-5822: CORS bypass in download manager
+  * CVE-2019-5823: Forced navigation from service worker
+  * CVE-2019-5812: URL spoof in Omnibox on iOS
+  * CVE-2019-5816: Exploit persistence extension on Android
+  * CVE-2019-5817: Heap buffer overflow in Angle on Windows
+- Add patches:
+  * 00-basevalue.patch
+  * 01-basevalue.patch
+  * 02-basevalue.patch
+  * 03-basevalue.patch
+  * 04-basevalue.patch
+  * 05-basevalue.patch
+  * 06-basevalue.patch
+  * old-libva.patch
+  * quic.patch
+- Remove patches:
+  * chromium-73.0.3683.75-pipewire-cstring-fix.patch
+  * chromium-fix_crashpad.patch
+  * chromium-fix_swiftshader.patch
+  * chromium-old-libva.patch
+- Rebase patches:
+  * chromium-gcc.patch
+  * chromium-non-void-return.patch
+  * chromium-old-glibc.patch
+
+-------------------------------------------------------------------

Old:
----
  chromium-73.0.3683.103.tar.xz
  chromium-73.0.3683.75-pipewire-cstring-fix.patch
  chromium-fix_crashpad.patch
  chromium-fix_swiftshader.patch
  chromium-old-libva.patch

New:
----
  00-basevalue.patch
  01-basevalue.patch
  02-basevalue.patch
  03-basevalue.patch
  04-basevalue.patch
  05-basevalue.patch
  06-basevalue.patch
  chromium-74.0.3729.108.tar.xz
  old-libva.patch
  quic.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ chromium.spec ++++++
--- /var/tmp/diff_new_pack.yvyoKb/_old  2019-05-02 19:18:03.701499275 +0200
+++ /var/tmp/diff_new_pack.yvyoKb/_new  2019-05-02 19:18:03.701499275 +0200
@@ -48,7 +48,7 @@
 %bcond_with clang
 %bcond_with wayland
 Name:           chromium
-Version:        73.0.3683.103
+Version:        74.0.3729.108
 Release:        0
 Summary:        Google's open source browser project
 License:        BSD-3-Clause AND LGPL-2.1-or-later
@@ -81,22 +81,25 @@
 Patch10:        chromium-system-libusb.patch
 Patch11:        chromium-old-glibc.patch
 Patch12:        chromium-skia-aarch64-buildfix.patch
-Patch13:        chromium-old-libva.patch
-# GCC does not support -Wno-error=header-hygiene flag
-Patch14:        chromium-fix_swiftshader.patch
-Patch15:        chromium-gcc.patch
-# Patch-FIX-UPSTREAM 
https://chromium-review.googlesource.com/c/crashpad/crashpad/+/1454376
-Patch16:        chromium-fix_crashpad.patch
-Patch17:        chromium-73.0.3683.75-pipewire-cstring-fix.patch
+Patch13:        chromium-gcc.patch
+Patch14:        00-basevalue.patch
+Patch15:        01-basevalue.patch
+Patch16:        02-basevalue.patch
+Patch17:        03-basevalue.patch
+Patch18:        04-basevalue.patch
+Patch19:        05-basevalue.patch
+Patch20:        06-basevalue.patch
+Patch21:        quic.patch
 # Google seem not too keen on merging this but GPU accel is quite important
 #  https://chromium-review.googlesource.com/c/chromium/src/+/532294
 #  
https://github.com/saiarcot895/chromium-ubuntu-build/tree/master/debian/patches
 #  Recreated from scratch to be smaller and use system the orginal switches
 #  (default on) compared to the PR
 Patch100:       chromium-vaapi.patch
+Patch101:       old-libva.patch
 # Google does not care much about system libs here
 #  https://bugs.chromium.org/p/skia/issues/detail?id=6663
-Patch101:       chromium-skia-system-fontconfig.patch
+Patch102:       chromium-skia-system-fontconfig.patch
 # PATCH-FIX-SUSE: allow prop codecs to be set with chromium branding
 Patch202:       chromium-prop-codecs.patch
 BuildRequires:  SDL-devel
@@ -230,7 +233,7 @@
 BuildRequires:  pkgconfig(libtcmalloc)
 %endif
 %if %{with system_harfbuzz}
-BuildRequires:  pkgconfig(harfbuzz) > 1.9.0
+BuildRequires:  pkgconfig(harfbuzz) > 2.3.0
 %endif
 %if %{with system_libxml}
 BuildRequires:  pkgconfig(libxml-2.0) >= 2.9.5
@@ -346,8 +349,10 @@
     third_party/crashpad/crashpad/third_party/zlib
     third_party/crc32c
     third_party/cros_system_api
+    third_party/dav1d
     third_party/devscripts
     third_party/dom_distiller_js
+    third_party/emoji-segmenter
     third_party/fips181
     third_party/flatbuffers
     third_party/flot
@@ -386,6 +391,7 @@
     third_party/metrics_proto
     third_party/minigbm
     third_party/modp_b64
+    third_party/nasm
     third_party/node
     third_party/node/node_modules/polymer-bundler/lib/third_party/UglifyJS2
     third_party/openh264

++++++ 00-basevalue.patch ++++++
>From 0e121588d500217a38d57f5e285aa586676059b2 Mon Sep 17 00:00:00 2001
From: Sergey Abbakumov <[email protected]>
Date: Fri, 15 Mar 2019 22:32:16 +0000
Subject: [PATCH] base::Value::SetKey/SetPath performance improvements

Use rvalue references to avoid copying sizeof(base::Value).

This commit gives about -20KB of the browser.dll and browser_child.dll
size. Also it reduces renderer memory consumption by ~200
KB max.

Bug: 646113
Change-Id: I8c86594838292a2faf4d134b899a7978dbc214fc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1520407
Reviewed-by: danakj <[email protected]>
Commit-Queue: danakj <[email protected]>
Cr-Commit-Position: refs/heads/master@{#641329}
---
 base/values.cc | 10 +++++-----
 base/values.h  | 10 +++++-----
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/base/values.cc b/base/values.cc
index 2b0c6c8163d8..0c002551b317 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -353,7 +353,7 @@ bool Value::RemoveKey(StringPiece key) {
   return dict_.erase(key) != 0;
 }
 
-Value* Value::SetKey(StringPiece key, Value value) {
+Value* Value::SetKey(StringPiece key, Value&& value) {
   CHECK(is_dict());
   // NOTE: We can't use |insert_or_assign| here, as only |try_emplace| does
   // an explicit conversion from StringPiece to std::string if necessary.
@@ -366,7 +366,7 @@ Value* Value::SetKey(StringPiece key, Value value) {
   return result.first->second.get();
 }
 
-Value* Value::SetKey(std::string&& key, Value value) {
+Value* Value::SetKey(std::string&& key, Value&& value) {
   CHECK(is_dict());
   return dict_
       .insert_or_assign(std::move(key),
@@ -374,7 +374,7 @@ Value* Value::SetKey(std::string&& key, Value value) {
       .first->second.get();
 }
 
-Value* Value::SetKey(const char* key, Value value) {
+Value* Value::SetKey(const char* key, Value&& value) {
   return SetKey(StringPiece(key), std::move(value));
 }
 
@@ -425,12 +425,12 @@ const Value* Value::FindPathOfType(span<const 
StringPiece> path,
   return result;
 }
 
-Value* Value::SetPath(std::initializer_list<StringPiece> path, Value value) {
+Value* Value::SetPath(std::initializer_list<StringPiece> path, Value&& value) {
   DCHECK_GE(path.size(), 2u) << "Use SetKey() for a path of length 1.";
   return SetPath(make_span(path.begin(), path.size()), std::move(value));
 }
 
-Value* Value::SetPath(span<const StringPiece> path, Value value) {
+Value* Value::SetPath(span<const StringPiece> path, Value&& value) {
   DCHECK(path.begin() != path.end());  // Can't be empty path.
 
   // Walk/construct intermediate dictionaries. The last element requires
diff --git a/base/values.h b/base/values.h
index 7546fa53756d..429ef1dfdebd 100644
--- a/base/values.h
+++ b/base/values.h
@@ -210,11 +210,11 @@ class BASE_EXPORT Value {
   //
   // Example:
   //   SetKey("foo", std::move(myvalue));
-  Value* SetKey(StringPiece key, Value value);
+  Value* SetKey(StringPiece key, Value&& value);
   // This overload results in a performance improvement for std::string&&.
-  Value* SetKey(std::string&& key, Value value);
+  Value* SetKey(std::string&& key, Value&& value);
   // This overload is necessary to avoid ambiguity for const char* arguments.
-  Value* SetKey(const char* key, Value value);
+  Value* SetKey(const char* key, Value&& value);
 
   // This attemps to remove the value associated with |key|. In case of 
failure,
   // e.g. the key does not exist, |false| is returned and the underlying
@@ -276,8 +276,8 @@ class BASE_EXPORT Value {
   //   value.SetPath(components, std::move(myvalue));
   //
   // Note: If there is only one component in the path, use SetKey() instead.
-  Value* SetPath(std::initializer_list<StringPiece> path, Value value);
-  Value* SetPath(span<const StringPiece> path, Value value);
+  Value* SetPath(std::initializer_list<StringPiece> path, Value&& value);
+  Value* SetPath(span<const StringPiece> path, Value&& value);
 
   // Tries to remove a Value at the given path.
   //
-- 
2.21.0

++++++ 01-basevalue.patch ++++++
>From e1b1f3a5f273c8da533fad495b9de316e2c83c9b Mon Sep 17 00:00:00 2001
From: jdoerrie <[email protected]>
Date: Sat, 16 Mar 2019 04:08:01 +0000
Subject: [PATCH] [base] Add Dead Type to base::Value

This change adds a temporary DEAD type to base::Value which should help
to track down use-after-free bugs. Furthermore, this change also removes
the now unneeded is_alive_ flag.

Bug: 859477, 941404
Change-Id: I9b7a2f3cbb0b22d7e3ed35b2453537419f3f7e55
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1478897
Reviewed-by: Pavol Marko <[email protected]>
Reviewed-by: Tao Bai <[email protected]>
Reviewed-by: Thomas Anderson <[email protected]>
Reviewed-by: Mike Pinkerton <[email protected]>
Reviewed-by: Bill Budge <[email protected]>
Reviewed-by: Ken Rockot <[email protected]>
Reviewed-by: Steven Bennetts <[email protected]>
Reviewed-by: Daniel Cheng <[email protected]>
Reviewed-by: David Turner <[email protected]>
Commit-Queue: Thomas Anderson <[email protected]>
Cr-Commit-Position: refs/heads/master@{#641404}
---
 base/json/json_writer.cc                      |  5 ++
 base/values.cc                                | 68 ++++++++++++-------
 base/values.h                                 | 23 ++-----
 base/values_unittest.cc                       | 10 ++-
 .../ui/cocoa/applescript/apple_event_util.mm  | 10 +++
 chromeos/network/onc/variable_expander.cc     |  6 ++
 .../core/browser/android/policy_converter.cc  | 11 ++-
 .../core/common/policy_loader_win_unittest.cc |  8 ++-
 .../policy/core/common/policy_test_utils.cc   |  5 ++
 .../policy/core/common/registry_dict.cc       |  4 ++
 .../gin_java_script_to_java_types_coercion.cc |  8 ++-
 ipc/ipc_message_utils.cc                      | 11 ++-
 mojo/public/cpp/base/values_mojom_traits.h    |  7 +-
 .../ppb_x509_certificate_private_shared.cc    |  2 +
 14 files changed, 127 insertions(+), 51 deletions(-)

diff --git a/base/json/json_writer.cc b/base/json/json_writer.cc
index 376a459f9a46..cd020e7fa0c0 100644
--- a/base/json/json_writer.cc
+++ b/base/json/json_writer.cc
@@ -179,6 +179,11 @@ bool JSONWriter::BuildJSONString(const Value& node, size_t 
depth) {
       // Successful only if we're allowed to omit it.
       DLOG_IF(ERROR, !omit_binary_values_) << "Cannot serialize binary value.";
       return omit_binary_values_;
+
+    // TODO(crbug.com/859477): Remove after root cause is found.
+    case Value::Type::DEAD:
+      CHECK(false);
+      return false;
   }
 
   // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
diff --git a/base/values.cc b/base/values.cc
index 0c002551b317..035aa2350cde 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -90,8 +90,6 @@ std::unique_ptr<Value> CopyWithoutEmptyChildren(const Value& 
node) {
 
 }  // namespace
 
-constexpr uint16_t Value::kMagicIsAlive;
-
 // static
 std::unique_ptr<Value> Value::CreateWithCopiedBuffer(const char* buffer,
                                                      size_t size) {
@@ -112,9 +110,9 @@ Value::Value(Value&& that) noexcept {
   InternalMoveConstructFrom(std::move(that));
 }
 
-Value::Value() noexcept : type_(Type::NONE), is_alive_(kMagicIsAlive) {}
+Value::Value() noexcept : type_(Type::NONE) {}
 
-Value::Value(Type type) : type_(type), is_alive_(kMagicIsAlive) {
+Value::Value(Type type) : type_(type) {
   // Initialize with the default value.
   switch (type_) {
     case Type::NONE:
@@ -141,22 +139,26 @@ Value::Value(Type type) : type_(type), 
is_alive_(kMagicIsAlive) {
     case Type::LIST:
       new (&list_) ListStorage();
       return;
+    // TODO(crbug.com/859477): Remove after root cause is found.
+    case Type::DEAD:
+      CHECK(false);
+      return;
   }
+
+  // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
+  CHECK(false);
 }
 
 Value::Value(bool in_bool)
     : bool_type_(Type::BOOLEAN),
-      bool_is_alive_(kMagicIsAlive),
       bool_value_(in_bool) {}
 
 Value::Value(int in_int)
     : int_type_(Type::INTEGER),
-      int_is_alive_(kMagicIsAlive),
       int_value_(in_int) {}
 
 Value::Value(double in_double)
     : double_type_(Type::DOUBLE),
-      double_is_alive_(kMagicIsAlive),
       double_value_(in_double) {
   if (!std::isfinite(double_value_)) {
     NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
@@ -171,7 +173,6 @@ Value::Value(StringPiece in_string) : 
Value(std::string(in_string)) {}
 
 Value::Value(std::string&& in_string) noexcept
     : string_type_(Type::STRING),
-      string_is_alive_(kMagicIsAlive),
       string_value_(std::move(in_string)) {
   DCHECK(IsStringUTF8(string_value_));
 }
@@ -182,21 +183,18 @@ Value::Value(StringPiece16 in_string16) : 
Value(UTF16ToUTF8(in_string16)) {}
 
 Value::Value(const std::vector<char>& in_blob)
     : binary_type_(Type::BINARY),
-      binary_is_alive_(kMagicIsAlive),
       binary_value_(in_blob.begin(), in_blob.end()) {}
 
 Value::Value(base::span<const uint8_t> in_blob)
     : binary_type_(Type::BINARY),
-      binary_is_alive_(kMagicIsAlive),
       binary_value_(in_blob.begin(), in_blob.end()) {}
 
 Value::Value(BlobStorage&& in_blob) noexcept
     : binary_type_(Type::BINARY),
-      binary_is_alive_(kMagicIsAlive),
       binary_value_(std::move(in_blob)) {}
 
 Value::Value(const DictStorage& in_dict)
-    : dict_type_(Type::DICTIONARY), dict_is_alive_(kMagicIsAlive), dict_() {
+    : dict_type_(Type::DICTIONARY), dict_() {
   dict_.reserve(in_dict.size());
   for (const auto& it : in_dict) {
     dict_.try_emplace(dict_.end(), it.first,
@@ -206,11 +204,9 @@ Value::Value(const DictStorage& in_dict)
 
 Value::Value(DictStorage&& in_dict) noexcept
     : dict_type_(Type::DICTIONARY),
-      dict_is_alive_(kMagicIsAlive),
       dict_(std::move(in_dict)) {}
 
-Value::Value(const ListStorage& in_list)
-    : list_type_(Type::LIST), list_is_alive_(kMagicIsAlive), list_() {
+Value::Value(const ListStorage& in_list) : list_type_(Type::LIST), list_() {
   list_.reserve(in_list.size());
   for (const auto& val : in_list)
     list_.emplace_back(val.Clone());
@@ -218,7 +214,6 @@ Value::Value(const ListStorage& in_list)
 
 Value::Value(ListStorage&& in_list) noexcept
     : list_type_(Type::LIST),
-      list_is_alive_(kMagicIsAlive),
       list_(std::move(in_list)) {}
 
 Value& Value::operator=(Value&& that) noexcept {
@@ -246,15 +241,21 @@ Value Value::Clone() const {
       return Value(dict_);
     case Type::LIST:
       return Value(list_);
+      // TODO(crbug.com/859477): Remove after root cause is found.
+    case Type::DEAD:
+      CHECK(false);
+      return Value();
   }
 
-  NOTREACHED();
+  // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
+  CHECK(false);
   return Value();
 }
 
 Value::~Value() {
   InternalCleanup();
-  is_alive_ = 0;
+  // TODO(crbug.com/859477): Remove after root cause is found.
+  type_ = Type::DEAD;
 }
 
 // static
@@ -654,9 +655,14 @@ bool operator==(const Value& lhs, const Value& rhs) {
                         });
     case Value::Type::LIST:
       return lhs.list_ == rhs.list_;
+      // TODO(crbug.com/859477): Remove after root cause is found.
+    case Value::Type::DEAD:
+      CHECK(false);
+      return false;
   }
 
-  NOTREACHED();
+  // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
+  CHECK(false);
   return false;
 }
 
@@ -693,9 +699,14 @@ bool operator<(const Value& lhs, const Value& rhs) {
           });
     case Value::Type::LIST:
       return lhs.list_ < rhs.list_;
+      // TODO(crbug.com/859477): Remove after root cause is found.
+    case Value::Type::DEAD:
+      CHECK(false);
+      return false;
   }
 
-  NOTREACHED();
+  // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
+  CHECK(false);
   return false;
 }
 
@@ -733,7 +744,6 @@ size_t Value::EstimateMemoryUsage() const {
 
 void Value::InternalMoveConstructFrom(Value&& that) {
   type_ = that.type_;
-  is_alive_ = that.is_alive_;
 
   switch (type_) {
     case Type::NONE:
@@ -759,12 +769,17 @@ void Value::InternalMoveConstructFrom(Value&& that) {
     case Type::LIST:
       new (&list_) ListStorage(std::move(that.list_));
       return;
+      // TODO(crbug.com/859477): Remove after root cause is found.
+    case Type::DEAD:
+      CHECK(false);
+      return;
   }
+
+  // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
+  CHECK(false);
 }
 
 void Value::InternalCleanup() {
-  CHECK_EQ(is_alive_, kMagicIsAlive);
-
   switch (type_) {
     case Type::NONE:
     case Type::BOOLEAN:
@@ -785,7 +800,14 @@ void Value::InternalCleanup() {
     case Type::LIST:
       list_.~ListStorage();
       return;
+      // TODO(crbug.com/859477): Remove after root cause is found.
+    case Type::DEAD:
+      CHECK(false);
+      return;
   }
+
+  // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
+  CHECK(false);
 }
 
 ///////////////////// DictionaryValue ////////////////////
diff --git a/base/values.h b/base/values.h
index 429ef1dfdebd..e31cadd83102 100644
--- a/base/values.h
+++ b/base/values.h
@@ -92,7 +92,9 @@ class BASE_EXPORT Value {
     STRING,
     BINARY,
     DICTIONARY,
-    LIST
+    LIST,
+    // TODO(crbug.com/859477): Remove once root cause is found.
+    DEAD
     // Note: Do not add more types. See the file-level comment above for why.
   };
 
@@ -375,10 +377,6 @@ class BASE_EXPORT Value {
   size_t EstimateMemoryUsage() const;
 
  protected:
-  // Magic IsAlive signature to debug double frees.
-  // TODO(crbug.com/859477): Remove once root cause is found.
-  static constexpr uint16_t kMagicIsAlive = 0x2f19;
-
   // Technical note:
   // The naive way to implement a tagged union leads to wasted bytes
   // in the object on CPUs like ARM ones, which impose an 8-byte alignment
@@ -408,8 +406,8 @@ class BASE_EXPORT Value {
   // that |double_value_| below is always located at an offset that is a
   // multiple of 8, relative to the start of the overall data structure.
   //
-  // Each struct must declare its own |type_| and |is_alive_| field, which
-  // must have a different name, to appease the C++ compiler.
+  // Each struct must declare its own |type_| field, which must have a 
different
+  // name, to appease the C++ compiler.
   //
   // Using this technique sizeof(base::Value) == 16 on 32-bit ARM instead
   // of 24, without losing any information. Results are unchanged for x86,
@@ -419,24 +417,17 @@ class BASE_EXPORT Value {
       // TODO(crbug.com/646113): Make these private once DictionaryValue and
       // ListValue are properly inlined.
       Type type_ : 8;
-
-      // IsAlive member to debug double frees.
-      // TODO(crbug.com/859477): Remove once root cause is found.
-      uint16_t is_alive_ = kMagicIsAlive;
     };
     struct {
       Type bool_type_ : 8;
-      uint16_t bool_is_alive_;
       bool bool_value_;
     };
     struct {
       Type int_type_ : 8;
-      uint16_t int_is_alive_;
       int int_value_;
     };
     struct {
       Type double_type_ : 8;
-      uint16_t double_is_alive_;
       // Subtle: On architectures that require it, the compiler will ensure
       // that |double_value_|'s offset is a multiple of 8 (e.g. 32-bit ARM).
       // See technical note above to understand why it is important.
@@ -444,22 +435,18 @@ class BASE_EXPORT Value {
     };
     struct {
       Type string_type_ : 8;
-      uint16_t string_is_alive_;
       std::string string_value_;
     };
     struct {
       Type binary_type_ : 8;
-      uint16_t binary_is_alive_;
       BlobStorage binary_value_;
     };
     struct {
       Type dict_type_ : 8;
-      uint16_t dict_is_alive_;
       DictStorage dict_;
     };
     struct {
       Type list_type_ : 8;
-      uint16_t list_is_alive_;
       ListStorage list_;
     };
   };
diff --git a/base/values_unittest.cc b/base/values_unittest.cc
index 0a641bcc7ef4..b23fd8332491 100644
--- a/base/values_unittest.cc
+++ b/base/values_unittest.cc
@@ -20,17 +20,20 @@
 #include "base/strings/string16.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace base {
 
+// Test is currently incorrect on Windows x86.
+#if !defined(OS_WIN) || !defined(ARCH_CPU_X86)
 TEST(ValuesTest, SizeOfValue) {
   // Ensure that base::Value is as small as possible, i.e. that there is
   // no wasted space after the inner value due to alignment constraints.
-  // Distinguish between the 'header' that includes |type_| and |is_alive_|
-  // and the inner value that follows it, which can be a bool, int, double,
-  // string, blob, list or dict.
+  // Distinguish between the 'header' that includes |type_| and and the inner
+  // value that follows it, which can be a bool, int, double, string, blob, 
list
+  // or dict.
 #define INNER_TYPES_LIST(X)            \
   X(bool, bool_value_)                 \
   X(int, int_value_)                   \
@@ -61,6 +64,7 @@ TEST(ValuesTest, SizeOfValue) {
     LOG(INFO) << "max_inner_struct_limit=" << max_inner_struct_limit;
   }
 }
+#endif
 
 TEST(ValuesTest, TestNothrow) {
   static_assert(std::is_nothrow_move_constructible<Value>::value,
diff --git a/chrome/browser/ui/cocoa/applescript/apple_event_util.mm 
b/chrome/browser/ui/cocoa/applescript/apple_event_util.mm
index 16d685607ced..25a59338ee73 100644
--- a/chrome/browser/ui/cocoa/applescript/apple_event_util.mm
+++ b/chrome/browser/ui/cocoa/applescript/apple_event_util.mm
@@ -96,6 +96,16 @@ NSAppleEventDescriptor* ValueToAppleEventDescriptor(const 
base::Value* value) {
       }
       break;
     }
+
+    // TODO(crbug.com/859477): Remove after root cause is found.
+    case base::Value::Type::DEAD:
+      CHECK(false);
+      break;
+
+    // TODO(crbug.com/859477): Remove after root cause is found.
+    default:
+      CHECK(false);
+      break;
   }
 
   return descriptor;
diff --git a/chromeos/network/onc/variable_expander.cc 
b/chromeos/network/onc/variable_expander.cc
index fd72752c2aa6..cd5bbb238eb3 100644
--- a/chromeos/network/onc/variable_expander.cc
+++ b/chromeos/network/onc/variable_expander.cc
@@ -145,6 +145,12 @@ bool VariableExpander::ExpandValue(base::Value* value) 
const {
       // Nothing to do here.
       break;
     }
+
+    // TODO(crbug.com/859477): Remove after root cause is found.
+    case base::Value::Type::DEAD: {
+      CHECK(false);
+      break;
+    }
   }
   return no_error;
 }
diff --git a/components/policy/core/browser/android/policy_converter.cc 
b/components/policy/core/browser/android/policy_converter.cc
index b711a64febc9..9d41ad0d1507 100644
--- a/components/policy/core/browser/android/policy_converter.cc
+++ b/components/policy/core/browser/android/policy_converter.cc
@@ -175,10 +175,17 @@ std::unique_ptr<base::Value> 
PolicyConverter::ConvertValueToSchema(
       }
       return value;
     }
+
+    // TODO(crbug.com/859477): Remove after root cause is found.
+    case base::Value::Type::DEAD: {
+      CHECK(false);
+      return nullptr;
+    }
   }
 
-  NOTREACHED();
-  return std::unique_ptr<base::Value>();
+  // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
+  CHECK(false);
+  return nullptr;
 }
 
 void PolicyConverter::SetPolicyValue(const std::string& key,
diff --git a/components/policy/core/common/policy_loader_win_unittest.cc 
b/components/policy/core/common/policy_loader_win_unittest.cc
index 311e7fb122fc..0377307c5e28 100644
--- a/components/policy/core/common/policy_loader_win_unittest.cc
+++ b/components/policy/core/common/policy_loader_win_unittest.cc
@@ -133,8 +133,14 @@ bool InstallValue(const base::Value& value,
 
     case base::Value::Type::BINARY:
       return false;
+
+    // TODO(crbug.com/859477): Remove after root cause is found.
+    case base::Value::Type::DEAD:
+      CHECK(false);
+      return false;
   }
-  NOTREACHED();
+  // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
+  CHECK(false);
   return false;
 }
 
diff --git a/components/policy/core/common/policy_test_utils.cc 
b/components/policy/core/common/policy_test_utils.cc
index 5af98b47275c..919f004153ec 100644
--- a/components/policy/core/common/policy_test_utils.cc
+++ b/components/policy/core/common/policy_test_utils.cc
@@ -137,6 +137,11 @@ CFPropertyListRef ValueToProperty(const base::Value& 
value) {
       // because there's no equivalent JSON type, and policy values can only
       // take valid JSON values.
       break;
+
+    // TODO(crbug.com/859477): Remove after root cause is found.
+    case base::Value::Type::DEAD:
+      CHECK(false);
+      break;
   }
 
   return NULL;
diff --git a/components/policy/core/common/registry_dict.cc 
b/components/policy/core/common/registry_dict.cc
index f3ed372bdcb3..696ba7e04abe 100644
--- a/components/policy/core/common/registry_dict.cc
+++ b/components/policy/core/common/registry_dict.cc
@@ -135,6 +135,10 @@ std::unique_ptr<base::Value> ConvertRegistryValue(const 
base::Value& value,
     case base::Value::Type::BINARY:
       // No conversion possible.
       break;
+    // TODO(crbug.com/859477): Remove after root cause is found.
+    case base::Value::Type::DEAD:
+      CHECK(false);
+      return nullptr;
   }
 
   LOG(WARNING) << "Failed to convert " << value.type() << " to "
diff --git 
a/content/browser/android/java/gin_java_script_to_java_types_coercion.cc 
b/content/browser/android/java/gin_java_script_to_java_types_coercion.cc
index dabd66ba8c72..84fd5489a414 100644
--- a/content/browser/android/java/gin_java_script_to_java_types_coercion.cc
+++ b/content/browser/android/java/gin_java_script_to_java_types_coercion.cc
@@ -722,8 +722,14 @@ jvalue CoerceJavaScriptValueToJavaValue(JNIEnv* env,
     case base::Value::Type::BINARY:
       return CoerceGinJavaBridgeValueToJavaValue(
           env, value, target_type, coerce_to_string, object_refs, error);
+    // TODO(crbug.com/859477): Remove after root cause is found.
+    case base::Value::Type::DEAD:
+      CHECK(false);
+      return jvalue();
   }
-  NOTREACHED();
+
+  // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
+  CHECK(false);
   return jvalue();
 }
 
diff --git a/ipc/ipc_message_utils.cc b/ipc/ipc_message_utils.cc
index ec04c77c6c18..df6ec39bd663 100644
--- a/ipc/ipc_message_utils.cc
+++ b/ipc/ipc_message_utils.cc
@@ -92,7 +92,7 @@ void WriteValue(base::Pickle* m, const base::Value* value, 
int recursion) {
 
   switch (value->type()) {
     case base::Value::Type::NONE:
-    break;
+      break;
     case base::Value::Type::BOOLEAN: {
       bool val;
       result = value->GetAsBoolean(&val);
@@ -147,6 +147,11 @@ void WriteValue(base::Pickle* m, const base::Value* value, 
int recursion) {
       }
       break;
     }
+
+    // TODO(crbug.com/859477): Remove after root cause is found.
+    default:
+      CHECK(false);
+      break;
   }
 }
 
@@ -260,7 +265,9 @@ bool ReadValue(const base::Pickle* m,
       break;
     }
     default:
-    return false;
+      // TODO(crbug.com/859477): Remove after root cause is found.
+      CHECK(false);
+      return false;
   }
 
   return true;
diff --git a/mojo/public/cpp/base/values_mojom_traits.h 
b/mojo/public/cpp/base/values_mojom_traits.h
index cdb9bbbd94df..66752b7c90d8 100644
--- a/mojo/public/cpp/base/values_mojom_traits.h
+++ b/mojo/public/cpp/base/values_mojom_traits.h
@@ -86,8 +86,13 @@ struct COMPONENT_EXPORT(MOJO_BASE_SHARED_TRAITS)
         return mojo_base::mojom::ValueDataView::Tag::DICTIONARY_VALUE;
       case base::Value::Type::LIST:
         return mojo_base::mojom::ValueDataView::Tag::LIST_VALUE;
+      // TODO(crbug.com/859477): Remove after root cause is found.
+      case base::Value::Type::DEAD:
+        CHECK(false);
+        return mojo_base::mojom::ValueDataView::Tag::NULL_VALUE;
     }
-    NOTREACHED();
+    // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is 
found.
+    CHECK(false);
     return mojo_base::mojom::ValueDataView::Tag::NULL_VALUE;
   }
 
diff --git a/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc 
b/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc
index 6ffff36337e0..7f392d50f718 100644
--- a/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc
+++ b/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc
@@ -73,6 +73,8 @@ PP_Var PPB_X509Certificate_Fields::GetFieldAsPPVar(
     }
     case base::Value::Type::DICTIONARY:
     case base::Value::Type::LIST:
+    // TODO(crbug.com/859477): Remove after root cause is found.
+    case base::Value::Type::DEAD:
       // Not handled.
       break;
   }
-- 
2.21.0

++++++ 02-basevalue.patch ++++++
>From c2c467f69fc00d353879d7add5f2c04a6acabbb1 Mon Sep 17 00:00:00 2001
From: David 'Digit' Turner <[email protected]>
Date: Wed, 20 Mar 2019 21:41:09 +0000
Subject: [PATCH] base: Value::FindDoubleKey() converts integers to doubles

Ensure that FindDoubleKey() can return the value of an
INTEGER key as a double. This is consistent with the behaviour
of Value::GetDouble() which will auto-convert INTEGER values
to doubles.

BUG=646113
[email protected],[email protected],[email protected],[email protected]

Change-Id: I2c08cb91b6cfd5db268a182ffffe16682d848008
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1529017
Reviewed-by: Sylvain Defresne <[email protected]>
Reviewed-by: Daniel Cheng <[email protected]>
Commit-Queue: David Turner <[email protected]>
Cr-Commit-Position: refs/heads/master@{#642680}
---
 base/values.cc          | 10 ++++++++--
 base/values.h           |  2 ++
 base/values_unittest.cc |  2 +-
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/base/values.cc b/base/values.cc
index 035aa2350cde..69d66ff8ab00 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -339,8 +339,14 @@ base::Optional<int> Value::FindIntKey(StringPiece key) 
const {
 }
 
 base::Optional<double> Value::FindDoubleKey(StringPiece key) const {
-  const Value* result = FindKeyOfType(key, Type::DOUBLE);
-  return result ? base::make_optional(result->double_value_) : base::nullopt;
+  const Value* result = FindKey(key);
+  if (result) {
+    if (result->is_int())
+      return base::make_optional(static_cast<double>(result->int_value_));
+    if (result->is_double())
+      return base::make_optional(result->double_value_);
+  }
+  return base::nullopt;
 }
 
 const std::string* Value::FindStringKey(StringPiece key) const {
diff --git a/base/values.h b/base/values.h
index e31cadd83102..6f2cd3cc3d79 100644
--- a/base/values.h
+++ b/base/values.h
@@ -200,6 +200,8 @@ class BASE_EXPORT Value {
   // function's name.
   base::Optional<bool> FindBoolKey(StringPiece key) const;
   base::Optional<int> FindIntKey(StringPiece key) const;
+  // Note FindDoubleKey() will auto-convert INTEGER keys to their double
+  // value, for consistency with GetDouble().
   base::Optional<double> FindDoubleKey(StringPiece key) const;
 
   // |FindStringKey| returns |nullptr| if value is not found or not a string.
diff --git a/base/values_unittest.cc b/base/values_unittest.cc
index b23fd8332491..7c545c09d947 100644
--- a/base/values_unittest.cc
+++ b/base/values_unittest.cc
@@ -674,7 +674,7 @@ TEST(ValuesTest, FindDoubleKey) {
   const Value dict(std::move(storage));
   EXPECT_EQ(base::nullopt, dict.FindDoubleKey("null"));
   EXPECT_EQ(base::nullopt, dict.FindDoubleKey("bool"));
-  EXPECT_EQ(base::nullopt, dict.FindDoubleKey("int"));
+  EXPECT_NE(base::nullopt, dict.FindDoubleKey("int"));
   EXPECT_NE(base::nullopt, dict.FindDoubleKey("double"));
   EXPECT_EQ(base::nullopt, dict.FindDoubleKey("string"));
   EXPECT_EQ(base::nullopt, dict.FindDoubleKey("blob"));
-- 
2.21.0

++++++ 03-basevalue.patch ++++++
>From fca8c4b5680297d58fa16a3ccf174f954b66cb48 Mon Sep 17 00:00:00 2001
From: David 'Digit' Turner <[email protected]>
Date: Tue, 26 Mar 2019 11:14:06 +0000
Subject: [PATCH] base: Add Value::Find{Blob,List,Dict}Key() methods
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This CL adds new Value::Find<Type>Key() methods for convenience.
This saves typing and makes the code simpler to read and
understand as well.

+ Fix minor typo in values_unittest.cc

BUG=646113
[email protected],[email protected],[email protected],[email protected]
[email protected]

Change-Id: I7cbc3f84da0f682411c7f5384849e7c0923c2fb0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1530910
Commit-Queue: David Turner <[email protected]>
Reviewed-by: Hidehiko Abe <[email protected]>
Reviewed-by: Mark Pearson <[email protected]>
Reviewed-by: Primiano Tucci <[email protected]>
Reviewed-by: Jan Wilken Dörrie <[email protected]>
Cr-Commit-Position: refs/heads/master@{#644251}
---
 base/json/json_reader_unittest.cc            | 15 ++--
 base/metrics/statistics_recorder_unittest.cc | 11 ++-
 base/trace_event/trace_config.cc             |  3 +-
 base/values.cc                               | 21 ++++++
 base/values.h                                | 11 +++
 base/values_unittest.cc                      | 74 ++++++++++++++++++--
 6 files changed, 113 insertions(+), 22 deletions(-)

diff --git a/base/json/json_reader_unittest.cc 
b/base/json/json_reader_unittest.cc
index 5023f33ed7cd..186a6f1dce30 100644
--- a/base/json/json_reader_unittest.cc
+++ b/base/json/json_reader_unittest.cc
@@ -371,17 +371,15 @@ TEST(JSONReaderTest, NestedDictionaries) {
       "{\"inner\":{\"array\":[true]},\"false\":false,\"d\":{}}");
   ASSERT_TRUE(dict_val);
   ASSERT_TRUE(dict_val->is_dict());
-  const Value* inner_dict =
-      dict_val->FindKeyOfType("inner", base::Value::Type::DICTIONARY);
+  const Value* inner_dict = dict_val->FindDictKey("inner");
   ASSERT_TRUE(inner_dict);
-  const Value* inner_array =
-      inner_dict->FindKeyOfType("array", base::Value::Type::LIST);
+  const Value* inner_array = inner_dict->FindListKey("array");
   ASSERT_TRUE(inner_array);
   EXPECT_EQ(1U, inner_array->GetList().size());
   auto bool_value = dict_val->FindBoolKey("false");
   ASSERT_TRUE(bool_value);
   EXPECT_FALSE(*bool_value);
-  inner_dict = dict_val->FindKeyOfType("d", base::Value::Type::DICTIONARY);
+  inner_dict = dict_val->FindDictKey("d");
   EXPECT_TRUE(inner_dict);
 
   Optional<Value> root2 = JSONReader::Read(
@@ -403,8 +401,7 @@ TEST(JSONReaderTest, DictionaryKeysWithPeriods) {
   integer_value = dict_val->FindIntKey("c");
   ASSERT_TRUE(integer_value);
   EXPECT_EQ(2, *integer_value);
-  const Value* inner_dict =
-      dict_val->FindKeyOfType("d.e.f", base::Value::Type::DICTIONARY);
+  const Value* inner_dict = dict_val->FindDictKey("d.e.f");
   ASSERT_TRUE(inner_dict);
   EXPECT_EQ(1U, inner_dict->DictSize());
   integer_value = inner_dict->FindIntKey("g.h.i.j");
@@ -595,9 +592,9 @@ TEST(JSONReaderTest, StringOptimizations) {
     ASSERT_TRUE(root);
     ASSERT_TRUE(root->is_dict());
 
-    Value* dict = root->FindKeyOfType("test", Value::Type::DICTIONARY);
+    Value* dict = root->FindDictKey("test");
     ASSERT_TRUE(dict);
-    Value* list = root->FindKeyOfType("list", Value::Type::LIST);
+    Value* list = root->FindListKey("list");
     ASSERT_TRUE(list);
 
     Value* to_move = dict->FindKey("foo");
diff --git a/base/metrics/statistics_recorder_unittest.cc 
b/base/metrics/statistics_recorder_unittest.cc
index f54f4146037a..9392e17cd25a 100644
--- a/base/metrics/statistics_recorder_unittest.cc
+++ b/base/metrics/statistics_recorder_unittest.cc
@@ -366,8 +366,7 @@ TEST_P(StatisticsRecorderTest, ToJSON) {
   // No query should be set.
   ASSERT_FALSE(root->FindKey("query"));
 
-  const Value* histogram_list =
-      root->FindKeyOfType("histograms", base::Value::Type::LIST);
+  const Value* histogram_list = root->FindListKey("histograms");
 
   ASSERT_TRUE(histogram_list);
   ASSERT_EQ(2u, histogram_list->GetList().size());
@@ -380,8 +379,7 @@ TEST_P(StatisticsRecorderTest, ToJSON) {
   ASSERT_TRUE(sample_count);
   EXPECT_EQ(2, *sample_count);
 
-  const Value* buckets_list =
-      histogram_dict.FindKeyOfType("buckets", base::Value::Type::LIST);
+  const Value* buckets_list = histogram_dict.FindListKey("buckets");
   ASSERT_TRUE(buckets_list);
   EXPECT_EQ(2u, buckets_list->GetList().size());
 
@@ -390,7 +388,7 @@ TEST_P(StatisticsRecorderTest, ToJSON) {
   root = JSONReader::Read(json);
   ASSERT_TRUE(root);
   ASSERT_TRUE(root->is_dict());
-  histogram_list = root->FindKeyOfType("histograms", base::Value::Type::LIST);
+  histogram_list = root->FindListKey("histograms");
   ASSERT_TRUE(histogram_list);
   ASSERT_EQ(2u, histogram_list->GetList().size());
   const Value& histogram_dict2 = histogram_list->GetList()[0];
@@ -398,8 +396,7 @@ TEST_P(StatisticsRecorderTest, ToJSON) {
   sample_count = histogram_dict2.FindIntKey("count");
   ASSERT_TRUE(sample_count);
   EXPECT_EQ(2, *sample_count);
-  buckets_list =
-      histogram_dict2.FindKeyOfType("buckets", base::Value::Type::LIST);
+  buckets_list = histogram_dict2.FindListKey("buckets");
   // Bucket information should be omitted.
   ASSERT_FALSE(buckets_list);
 }
diff --git a/base/trace_event/trace_config.cc b/base/trace_event/trace_config.cc
index e28456bdd0c9..e5bc3a58ed7d 100644
--- a/base/trace_event/trace_config.cc
+++ b/base/trace_event/trace_config.cc
@@ -147,8 +147,7 @@ void TraceConfig::ProcessFilterConfig::Merge(
 void TraceConfig::ProcessFilterConfig::InitializeFromConfigDict(
     const base::DictionaryValue& dict) {
   included_process_ids_.clear();
-  const Value* value =
-      dict.FindKeyOfType(kIncludedProcessesParam, Value::Type::LIST);
+  const Value* value = dict.FindListKey(kIncludedProcessesParam);
   if (!value)
     return;
   for (auto& pid_value : value->GetList()) {
diff --git a/base/values.cc b/base/values.cc
index 69d66ff8ab00..6f3a9e2cd8a2 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -354,6 +354,27 @@ const std::string* Value::FindStringKey(StringPiece key) 
const {
   return result ? &result->string_value_ : nullptr;
 }
 
+const Value::BlobStorage* Value::FindBlobKey(StringPiece key) const {
+  const Value* value = FindKeyOfType(key, Type::BINARY);
+  return value ? &value->binary_value_ : nullptr;
+}
+
+const Value* Value::FindDictKey(StringPiece key) const {
+  return FindKeyOfType(key, Type::DICTIONARY);
+}
+
+Value* Value::FindDictKey(StringPiece key) {
+  return FindKeyOfType(key, Type::DICTIONARY);
+}
+
+const Value* Value::FindListKey(StringPiece key) const {
+  return FindKeyOfType(key, Type::LIST);
+}
+
+Value* Value::FindListKey(StringPiece key) {
+  return FindKeyOfType(key, Type::LIST);
+}
+
 bool Value::RemoveKey(StringPiece key) {
   CHECK(is_dict());
   // NOTE: Can't directly return dict_->erase(key) due to MSVC warning C4800.
diff --git a/base/values.h b/base/values.h
index 6f2cd3cc3d79..7bc355ee586d 100644
--- a/base/values.h
+++ b/base/values.h
@@ -207,6 +207,17 @@ class BASE_EXPORT Value {
   // |FindStringKey| returns |nullptr| if value is not found or not a string.
   const std::string* FindStringKey(StringPiece key) const;
 
+  // Returns nullptr is value is not found or not a binary.
+  const BlobStorage* FindBlobKey(StringPiece key) const;
+
+  // Returns nullptr if value is not found or not a dictionary.
+  const Value* FindDictKey(StringPiece key) const;
+  Value* FindDictKey(StringPiece key);
+
+  // Returns nullptr if value is not found or not a list.
+  const Value* FindListKey(StringPiece key) const;
+  Value* FindListKey(StringPiece key);
+
   // |SetKey| looks up |key| in the underlying dictionary and sets the mapped
   // value to |value|. If |key| could not be found, a new element is inserted.
   // A pointer to the modified item is returned.
diff --git a/base/values_unittest.cc b/base/values_unittest.cc
index 7c545c09d947..2907dc066843 100644
--- a/base/values_unittest.cc
+++ b/base/values_unittest.cc
@@ -635,7 +635,7 @@ TEST(ValuesTest, FindBoolKey) {
   EXPECT_EQ(base::nullopt, dict.FindBoolKey("string"));
   EXPECT_EQ(base::nullopt, dict.FindBoolKey("blob"));
   EXPECT_EQ(base::nullopt, dict.FindBoolKey("list"));
-  EXPECT_EQ(base::nullopt, dict.FindBoolKey("dist"));
+  EXPECT_EQ(base::nullopt, dict.FindBoolKey("dict"));
 }
 
 TEST(ValuesTest, FindIntKey) {
@@ -657,7 +657,7 @@ TEST(ValuesTest, FindIntKey) {
   EXPECT_EQ(base::nullopt, dict.FindIntKey("string"));
   EXPECT_EQ(base::nullopt, dict.FindIntKey("blob"));
   EXPECT_EQ(base::nullopt, dict.FindIntKey("list"));
-  EXPECT_EQ(base::nullopt, dict.FindIntKey("dist"));
+  EXPECT_EQ(base::nullopt, dict.FindIntKey("dict"));
 }
 
 TEST(ValuesTest, FindDoubleKey) {
@@ -679,7 +679,7 @@ TEST(ValuesTest, FindDoubleKey) {
   EXPECT_EQ(base::nullopt, dict.FindDoubleKey("string"));
   EXPECT_EQ(base::nullopt, dict.FindDoubleKey("blob"));
   EXPECT_EQ(base::nullopt, dict.FindDoubleKey("list"));
-  EXPECT_EQ(base::nullopt, dict.FindDoubleKey("dist"));
+  EXPECT_EQ(base::nullopt, dict.FindDoubleKey("dict"));
 }
 
 TEST(ValuesTest, FindStringKey) {
@@ -701,7 +701,73 @@ TEST(ValuesTest, FindStringKey) {
   EXPECT_NE(nullptr, dict.FindStringKey("string"));
   EXPECT_EQ(nullptr, dict.FindStringKey("blob"));
   EXPECT_EQ(nullptr, dict.FindStringKey("list"));
-  EXPECT_EQ(nullptr, dict.FindStringKey("dist"));
+  EXPECT_EQ(nullptr, dict.FindStringKey("dict"));
+}
+
+TEST(ValuesTest, FindDictKey) {
+  Value::DictStorage storage;
+  storage.emplace("null", std::make_unique<Value>(Value::Type::NONE));
+  storage.emplace("bool", std::make_unique<Value>(Value::Type::BOOLEAN));
+  storage.emplace("int", std::make_unique<Value>(Value::Type::INTEGER));
+  storage.emplace("double", std::make_unique<Value>(Value::Type::DOUBLE));
+  storage.emplace("string", std::make_unique<Value>(Value::Type::STRING));
+  storage.emplace("blob", std::make_unique<Value>(Value::Type::BINARY));
+  storage.emplace("list", std::make_unique<Value>(Value::Type::LIST));
+  storage.emplace("dict", std::make_unique<Value>(Value::Type::DICTIONARY));
+
+  const Value dict(std::move(storage));
+  EXPECT_EQ(nullptr, dict.FindDictKey("null"));
+  EXPECT_EQ(nullptr, dict.FindDictKey("bool"));
+  EXPECT_EQ(nullptr, dict.FindDictKey("int"));
+  EXPECT_EQ(nullptr, dict.FindDictKey("double"));
+  EXPECT_EQ(nullptr, dict.FindDictKey("string"));
+  EXPECT_EQ(nullptr, dict.FindDictKey("blob"));
+  EXPECT_EQ(nullptr, dict.FindDictKey("list"));
+  EXPECT_NE(nullptr, dict.FindDictKey("dict"));
+}
+
+TEST(ValuesTest, FindListKey) {
+  Value::DictStorage storage;
+  storage.emplace("null", std::make_unique<Value>(Value::Type::NONE));
+  storage.emplace("bool", std::make_unique<Value>(Value::Type::BOOLEAN));
+  storage.emplace("int", std::make_unique<Value>(Value::Type::INTEGER));
+  storage.emplace("double", std::make_unique<Value>(Value::Type::DOUBLE));
+  storage.emplace("string", std::make_unique<Value>(Value::Type::STRING));
+  storage.emplace("blob", std::make_unique<Value>(Value::Type::BINARY));
+  storage.emplace("list", std::make_unique<Value>(Value::Type::LIST));
+  storage.emplace("dict", std::make_unique<Value>(Value::Type::DICTIONARY));
+
+  const Value dict(std::move(storage));
+  EXPECT_EQ(nullptr, dict.FindListKey("null"));
+  EXPECT_EQ(nullptr, dict.FindListKey("bool"));
+  EXPECT_EQ(nullptr, dict.FindListKey("int"));
+  EXPECT_EQ(nullptr, dict.FindListKey("double"));
+  EXPECT_EQ(nullptr, dict.FindListKey("string"));
+  EXPECT_EQ(nullptr, dict.FindListKey("blob"));
+  EXPECT_NE(nullptr, dict.FindListKey("list"));
+  EXPECT_EQ(nullptr, dict.FindListKey("dict"));
+}
+
+TEST(ValuesTest, FindBlobKey) {
+  Value::DictStorage storage;
+  storage.emplace("null", std::make_unique<Value>(Value::Type::NONE));
+  storage.emplace("bool", std::make_unique<Value>(Value::Type::BOOLEAN));
+  storage.emplace("int", std::make_unique<Value>(Value::Type::INTEGER));
+  storage.emplace("double", std::make_unique<Value>(Value::Type::DOUBLE));
+  storage.emplace("string", std::make_unique<Value>(Value::Type::STRING));
+  storage.emplace("blob", std::make_unique<Value>(Value::Type::BINARY));
+  storage.emplace("list", std::make_unique<Value>(Value::Type::LIST));
+  storage.emplace("dict", std::make_unique<Value>(Value::Type::DICTIONARY));
+
+  const Value dict(std::move(storage));
+  EXPECT_EQ(nullptr, dict.FindBlobKey("null"));
+  EXPECT_EQ(nullptr, dict.FindBlobKey("bool"));
+  EXPECT_EQ(nullptr, dict.FindBlobKey("int"));
+  EXPECT_EQ(nullptr, dict.FindBlobKey("double"));
+  EXPECT_EQ(nullptr, dict.FindBlobKey("string"));
+  EXPECT_NE(nullptr, dict.FindBlobKey("blob"));
+  EXPECT_EQ(nullptr, dict.FindBlobKey("list"));
+  EXPECT_EQ(nullptr, dict.FindBlobKey("dict"));
 }
 
 TEST(ValuesTest, SetKey) {
-- 
2.21.0

++++++ 04-basevalue.patch ++++++
++++ 794 lines (skipped)

++++++ 05-basevalue.patch ++++++
>From 2f28731c17b246bd70075f828dcafcd23547da5d Mon Sep 17 00:00:00 2001
From: David 'Digit' Turner <[email protected]>
Date: Wed, 3 Apr 2019 14:32:09 +0000
Subject: [PATCH] base: Fix Value layout for GCC
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

It turns out that the previous changes to the base::Value
layout broke GCC compilation (see [1] for details).

This CL fixes the situation by using a new DoubleStorage
type that will store double values in a 4-byte aligned
struct, with bit_cast<> being used to convert between
double and DoubleStorage values in the implementation.

This ensures that base::Value remains as small as possible
in all cases. The small penalty is that loading/storing
double values on 32-bit ARM is slightly slower due to
the fact that the value is no longer 8-byte aligned.

+ Fix the ValuesTest.SizeOfValue test to work correctly,
  and disable it for debug builds, so it doesn't fail
  because debug versions of the internal containers
  are larger on certain systems.

[1] https://chromium-review.googlesource.com/c/chromium/src/+/1472716

BUG=646113
[email protected], [email protected], [email protected], 
[email protected], [email protected]

Change-Id: I9a365407dc064ba1bdc19859706f4154a495921e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1550363
Commit-Queue: David Turner <[email protected]>
Reviewed-by: Jan Wilken Dörrie <[email protected]>
Cr-Commit-Position: refs/heads/master@{#647271}
---
 base/values.cc          | 67 +++++++++++++---------------
 base/values.h           | 94 ++++++++++------------------------------
 base/values_unittest.cc | 96 ++++++++++++++++++++++++++++++-----------
 3 files changed, 124 insertions(+), 133 deletions(-)

diff --git a/base/values.cc b/base/values.cc
index 9fed5b52d60e..16d686b0bee5 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -12,6 +12,7 @@
 #include <ostream>
 #include <utility>
 
+#include "base/bit_cast.h"
 #include "base/json/json_writer.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
@@ -36,6 +37,9 @@ static_assert(std::is_standard_layout<Value>::value,
               "base::Value should be a standard-layout C++ class in order "
               "to avoid undefined behaviour in its implementation!");
 
+static_assert(sizeof(Value::DoubleStorage) == sizeof(double),
+              "The double and DoubleStorage types should have the same size");
+
 namespace {
 
 const char* const kTypeNames[] = {"null",   "boolean", "integer",    "double",
@@ -110,8 +114,6 @@ Value::Value(Value&& that) noexcept {
   InternalMoveConstructFrom(std::move(that));
 }
 
-Value::Value() noexcept : type_(Type::NONE) {}
-
 Value::Value(Type type) : type_(type) {
   // Initialize with the default value.
   switch (type_) {
@@ -125,7 +127,7 @@ Value::Value(Type type) : type_(type) {
       int_value_ = 0;
       return;
     case Type::DOUBLE:
-      double_value_ = 0.0;
+      double_value_ = bit_cast<DoubleStorage>(0.0);
       return;
     case Type::STRING:
       new (&string_value_) std::string();
@@ -149,21 +151,16 @@ Value::Value(Type type) : type_(type) {
   CHECK(false);
 }
 
-Value::Value(bool in_bool)
-    : bool_type_(Type::BOOLEAN),
-      bool_value_(in_bool) {}
+Value::Value(bool in_bool) : type_(Type::BOOLEAN), bool_value_(in_bool) {}
 
-Value::Value(int in_int)
-    : int_type_(Type::INTEGER),
-      int_value_(in_int) {}
+Value::Value(int in_int) : type_(Type::INTEGER), int_value_(in_int) {}
 
 Value::Value(double in_double)
-    : double_type_(Type::DOUBLE),
-      double_value_(in_double) {
-  if (!std::isfinite(double_value_)) {
+    : type_(Type::DOUBLE), double_value_(bit_cast<DoubleStorage>(in_double)) {
+  if (!std::isfinite(in_double)) {
     NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
                  << "values cannot be represented in JSON";
-    double_value_ = 0.0;
+    double_value_ = bit_cast<DoubleStorage>(0.0);
   }
 }
 
@@ -172,8 +169,7 @@ Value::Value(const char* in_string) : 
Value(std::string(in_string)) {}
 Value::Value(StringPiece in_string) : Value(std::string(in_string)) {}
 
 Value::Value(std::string&& in_string) noexcept
-    : string_type_(Type::STRING),
-      string_value_(std::move(in_string)) {
+    : type_(Type::STRING), string_value_(std::move(in_string)) {
   DCHECK(IsStringUTF8(string_value_));
 }
 
@@ -182,19 +178,15 @@ Value::Value(const char16* in_string16) : 
Value(StringPiece16(in_string16)) {}
 Value::Value(StringPiece16 in_string16) : Value(UTF16ToUTF8(in_string16)) {}
 
 Value::Value(const std::vector<char>& in_blob)
-    : binary_type_(Type::BINARY),
-      binary_value_(in_blob.begin(), in_blob.end()) {}
+    : type_(Type::BINARY), binary_value_(in_blob.begin(), in_blob.end()) {}
 
 Value::Value(base::span<const uint8_t> in_blob)
-    : binary_type_(Type::BINARY),
-      binary_value_(in_blob.begin(), in_blob.end()) {}
+    : type_(Type::BINARY), binary_value_(in_blob.begin(), in_blob.end()) {}
 
 Value::Value(BlobStorage&& in_blob) noexcept
-    : binary_type_(Type::BINARY),
-      binary_value_(std::move(in_blob)) {}
+    : type_(Type::BINARY), binary_value_(std::move(in_blob)) {}
 
-Value::Value(const DictStorage& in_dict)
-    : dict_type_(Type::DICTIONARY), dict_() {
+Value::Value(const DictStorage& in_dict) : type_(Type::DICTIONARY), dict_() {
   dict_.reserve(in_dict.size());
   for (const auto& it : in_dict) {
     dict_.try_emplace(dict_.end(), it.first,
@@ -203,18 +195,16 @@ Value::Value(const DictStorage& in_dict)
 }
 
 Value::Value(DictStorage&& in_dict) noexcept
-    : dict_type_(Type::DICTIONARY),
-      dict_(std::move(in_dict)) {}
+    : type_(Type::DICTIONARY), dict_(std::move(in_dict)) {}
 
-Value::Value(const ListStorage& in_list) : list_type_(Type::LIST), list_() {
+Value::Value(const ListStorage& in_list) : type_(Type::LIST), list_() {
   list_.reserve(in_list.size());
   for (const auto& val : in_list)
     list_.emplace_back(val.Clone());
 }
 
 Value::Value(ListStorage&& in_list) noexcept
-    : list_type_(Type::LIST),
-      list_(std::move(in_list)) {}
+    : type_(Type::LIST), list_(std::move(in_list)) {}
 
 Value& Value::operator=(Value&& that) noexcept {
   InternalCleanup();
@@ -223,6 +213,10 @@ Value& Value::operator=(Value&& that) noexcept {
   return *this;
 }
 
+double Value::AsDoubleInternal() const {
+  return bit_cast<double>(double_value_);
+}
+
 Value Value::Clone() const {
   switch (type_) {
     case Type::NONE:
@@ -232,7 +226,7 @@ Value Value::Clone() const {
     case Type::INTEGER:
       return Value(int_value_);
     case Type::DOUBLE:
-      return Value(double_value_);
+      return Value(AsDoubleInternal());
     case Type::STRING:
       return Value(string_value_);
     case Type::BINARY:
@@ -277,7 +271,7 @@ int Value::GetInt() const {
 
 double Value::GetDouble() const {
   if (is_double())
-    return double_value_;
+    return AsDoubleInternal();
   if (is_int())
     return int_value_;
   CHECK(false);
@@ -342,9 +336,10 @@ base::Optional<double> Value::FindDoubleKey(StringPiece 
key) const {
   const Value* result = FindKey(key);
   if (result) {
     if (result->is_int())
-      return base::make_optional(static_cast<double>(result->int_value_));
-    if (result->is_double())
-      return base::make_optional(result->double_value_);
+      return static_cast<double>(result->int_value_);
+    if (result->is_double()) {
+      return result->AsDoubleInternal();
+    }
   }
   return base::nullopt;
 }
@@ -601,7 +596,7 @@ bool Value::GetAsInteger(int* out_value) const {
 
 bool Value::GetAsDouble(double* out_value) const {
   if (out_value && is_double()) {
-    *out_value = double_value_;
+    *out_value = AsDoubleInternal();
     return true;
   }
   if (out_value && is_int()) {
@@ -696,7 +691,7 @@ bool operator==(const Value& lhs, const Value& rhs) {
     case Value::Type::INTEGER:
       return lhs.int_value_ == rhs.int_value_;
     case Value::Type::DOUBLE:
-      return lhs.double_value_ == rhs.double_value_;
+      return lhs.AsDoubleInternal() == rhs.AsDoubleInternal();
     case Value::Type::STRING:
       return lhs.string_value_ == rhs.string_value_;
     case Value::Type::BINARY:
@@ -741,7 +736,7 @@ bool operator<(const Value& lhs, const Value& rhs) {
     case Value::Type::INTEGER:
       return lhs.int_value_ < rhs.int_value_;
     case Value::Type::DOUBLE:
-      return lhs.double_value_ < rhs.double_value_;
+      return lhs.AsDoubleInternal() < rhs.AsDoubleInternal();
     case Value::Type::STRING:
       return lhs.string_value_ < rhs.string_value_;
     case Value::Type::BINARY:
diff --git a/base/values.h b/base/values.h
index 486fe7ff3976..c455936d4961 100644
--- a/base/values.h
+++ b/base/values.h
@@ -83,6 +83,8 @@ class BASE_EXPORT Value {
   using BlobStorage = std::vector<uint8_t>;
   using DictStorage = flat_map<std::string, std::unique_ptr<Value>>;
   using ListStorage = std::vector<Value>;
+  // See technical note below explaining why this is used.
+  using DoubleStorage = struct { alignas(4) char v[sizeof(double)]; };
 
   enum class Type {
     NONE = 0,
@@ -111,7 +113,10 @@ class BASE_EXPORT Value {
   static std::unique_ptr<Value> ToUniquePtrValue(Value val);
 
   Value(Value&& that) noexcept;
-  Value() noexcept;  // A null value.
+  Value() noexcept {}  // A null value
+  // Fun fact: using '= default' above instead of '{}' does not work because
+  // the compiler complains that the default constructor was deleted since
+  // the inner union contains fields with non-default constructors.
 
   // Value's copy constructor and copy assignment operator are deleted. Use 
this
   // to obtain a deep copy explicitly.
@@ -405,82 +410,29 @@ class BASE_EXPORT Value {
   size_t EstimateMemoryUsage() const;
 
  protected:
-  // Technical note:
-  // The naive way to implement a tagged union leads to wasted bytes
-  // in the object on CPUs like ARM ones, which impose an 8-byte alignment
-  // for double values. I.e. if one does something like:
+  // Special case for doubles, which are aligned to 8 bytes on some
+  // 32-bit architectures. In this case, a simple declaration as a
+  // double member would make the whole union 8 byte-aligned, which
+  // would also force 4 bytes of wasted padding space before it in
+  // the Value layout.
   //
-  //    struct TaggedValue {
-  //      int type_;                    // size = 1, align = 4
-  //      union {
-  //        bool bool_value_;           // size = 1, align = 1
-  //        int int_value_;             // size = 4, align = 4
-  //        double double_value_;       // size = 8, align = 8
-  //        std::string string_value_;  // size = 12, align = 4  (32-bit)
-  //      };
-  //    };
-  //
-  // The end result is that the union will have an alignment of 8, and a size
-  // of 16, due to 4 extra padding bytes following |string_value_| to respect
-  // the alignment requirement.
-  //
-  // As a consequence, the struct TaggedValue will have a size of 24 bytes,
-  // due to the size of the union (16), the size of |type_| (4) and 4 bytes
-  // of padding between |type_| and the union to respect its alignment.
-  //
-  // This means 8 bytes of unused memory per instance on 32-bit ARM!
-  //
-  // To reclaim these, a union of structs is used instead, in order to ensure
-  // that |double_value_| below is always located at an offset that is a
-  // multiple of 8, relative to the start of the overall data structure.
-  //
-  // Each struct must declare its own |type_| field, which must have a 
different
-  // name, to appease the C++ compiler.
-  //
-  // Using this technique sizeof(base::Value) == 16 on 32-bit ARM instead
-  // of 24, without losing any information. Results are unchanged for x86,
-  // x86_64 and arm64 (16, 32 and 32 bytes respectively).
+  // To override this, store the value as an array of 32-bit integers, and
+  // perform the appropriate bit casts when reading / writing to it.
+  Type type_ = Type::NONE;
+
   union {
-    struct {
-      // TODO(crbug.com/646113): Make these private once DictionaryValue and
-      // ListValue are properly inlined.
-      Type type_ : 8;
-    };
-    struct {
-      Type bool_type_ : 8;
-      bool bool_value_;
-    };
-    struct {
-      Type int_type_ : 8;
-      int int_value_;
-    };
-    struct {
-      Type double_type_ : 8;
-      // Subtle: On architectures that require it, the compiler will ensure
-      // that |double_value_|'s offset is a multiple of 8 (e.g. 32-bit ARM).
-      // See technical note above to understand why it is important.
-      double double_value_;
-    };
-    struct {
-      Type string_type_ : 8;
-      std::string string_value_;
-    };
-    struct {
-      Type binary_type_ : 8;
-      BlobStorage binary_value_;
-    };
-    struct {
-      Type dict_type_ : 8;
-      DictStorage dict_;
-    };
-    struct {
-      Type list_type_ : 8;
-      ListStorage list_;
-    };
+    bool bool_value_;
+    int int_value_;
+    DoubleStorage double_value_;
+    std::string string_value_;
+    BlobStorage binary_value_;
+    DictStorage dict_;
+    ListStorage list_;
   };
 
  private:
   friend class ValuesTest_SizeOfValue_Test;
+  double AsDoubleInternal() const;
   void InternalMoveConstructFrom(Value&& that);
   void InternalCleanup();
 
diff --git a/base/values_unittest.cc b/base/values_unittest.cc
index 2dd1c76afaa9..f3536a8612b1 100644
--- a/base/values_unittest.cc
+++ b/base/values_unittest.cc
@@ -26,45 +26,89 @@
 
 namespace base {
 
-// Test is currently incorrect on Windows x86.
-#if !defined(OS_WIN) || !defined(ARCH_CPU_X86)
+// Ensure that base::Value is as small as possible, i.e. that there is
+// no wasted space after the inner value due to alignment constraints.
+// Distinguish between the 'header' that includes |type_| and and the inner
+// value that follows it, which can be a bool, int, double, string, blob, list
+// or dict.
+//
+// This test is only enabled when NDEBUG is defined. This way the test will not
+// fail in debug builds that sometimes contain larger versions of the standard
+// containers used inside base::Value.
+#if defined(NDEBUG)
+
+static size_t AlignSizeTo(size_t size, size_t alignment) {
+  EXPECT_TRUE((alignment & (alignment - 1)) == 0)
+      << "Alignment " << alignment << " is not a power of 2!";
+  return (size + (alignment - 1u)) & ~(alignment - 1u);
+}
+
 TEST(ValuesTest, SizeOfValue) {
-  // Ensure that base::Value is as small as possible, i.e. that there is
-  // no wasted space after the inner value due to alignment constraints.
-  // Distinguish between the 'header' that includes |type_| and and the inner
-  // value that follows it, which can be a bool, int, double, string, blob, 
list
-  // or dict.
-#define INNER_TYPES_LIST(X)            \
-  X(bool, bool_value_)                 \
-  X(int, int_value_)                   \
-  X(double, double_value_)             \
-  X(std::string, string_value_)        \
-  X(Value::BlobStorage, binary_value_) \
-  X(Value::ListStorage, list_)         \
+#define INNER_TYPES_LIST(X)              \
+  X(bool, bool_value_)                   \
+  X(int, int_value_)                     \
+  X(Value::DoubleStorage, double_value_) \
+  X(std::string, string_value_)          \
+  X(Value::BlobStorage, binary_value_)   \
+  X(Value::ListStorage, list_)           \
   X(Value::DictStorage, dict_)
 
-#define INNER_STRUCT_LIMIT(type, value) offsetof(Value, value) + sizeof(type),
+#define INNER_FIELD_ALIGNMENT(type, value) alignof(type),
+
+  // The maximum alignment of each inner struct value field inside base::Value
+  size_t max_inner_value_alignment =
+      std::max({INNER_TYPES_LIST(INNER_FIELD_ALIGNMENT)});
+
+  // Check that base::Value has the smallest alignment possible. This would
+  // fail if the header would contain something that has a larger alignment
+  // than necessary.
+  EXPECT_EQ(max_inner_value_alignment, alignof(Value));
+
+  // Find the offset of each inner value. Which should normally not be
+  // larger than 4. Note that we use std::max(4, ...) because bool_value_
+  // could be stored just after the |bool_type_| field, with an offset of
+  // 1, and that would be ok.
+#define INNER_VALUE_START_OFFSET(type, value) offsetof(Value, value),
+
+  size_t min_inner_value_offset =
+      std::min({INNER_TYPES_LIST(INNER_VALUE_START_OFFSET)});
 
-  // Return the maximum size in bytes of each inner struct inside base::Value
-  size_t max_inner_struct_limit =
-      std::max({INNER_TYPES_LIST(INNER_STRUCT_LIMIT)});
+  // Inner fields may contain pointers, which have an alignment of 8
+  // on most 64-bit platforms.
+  size_t expected_min_offset = alignof(void*);
+
+  EXPECT_EQ(expected_min_offset, min_inner_value_offset);
 
   // Ensure that base::Value is not larger than necessary, i.e. that there is
-  // no un-necessary padding afte the structs due to alignment constraints of
+  // no un-necessary padding after the structs due to alignment constraints of
   // one of the inner fields.
-  EXPECT_EQ(max_inner_struct_limit, sizeof(Value));
-  if (max_inner_struct_limit != sizeof(Value)) {
+#define INNER_STRUCT_END_OFFSET(type, value) \
+  offsetof(Value, value) + sizeof(type),
+
+  // The maximum size in bytes of each inner struct inside base::Value,
+  size_t max_inner_struct_end_offset =
+      std::max({INNER_TYPES_LIST(INNER_STRUCT_END_OFFSET)});
+
+  // The expected value size.
+  size_t expected_value_size =
+      AlignSizeTo(max_inner_struct_end_offset, alignof(Value));
+
+  EXPECT_EQ(expected_value_size, sizeof(Value));
+  if (min_inner_value_offset != expected_min_offset ||
+      expected_value_size != sizeof(Value)) {
     // The following are useful to understand what's wrong when the EXPECT_EQ()
-    // above actually fails.
-#define PRINT_INNER_FIELD_INFO(x, y) \
-  LOG(INFO) << #y " type=" #x " size=" << sizeof(x) << " align=" << alignof(x);
+    // above actually fail.
+#define PRINT_INNER_FIELD_INFO(x, y)                           \
+  LOG(INFO) << #y " type=" #x " offset=" << offsetof(Value, y) \
+            << " size=" << sizeof(x) << " align=" << alignof(x);
 
     LOG(INFO) << "Value size=" << sizeof(Value) << " align=" << alignof(Value);
     INNER_TYPES_LIST(PRINT_INNER_FIELD_INFO)
-    LOG(INFO) << "max_inner_struct_limit=" << max_inner_struct_limit;
+    LOG(INFO) << "max_inner_struct_end_offset=" << max_inner_struct_end_offset;
   }
 }
-#endif
+
+#endif  // NDEBUG
 
 TEST(ValuesTest, TestNothrow) {
   static_assert(std::is_nothrow_move_constructible<Value>::value,
-- 
2.21.0

++++++ 06-basevalue.patch ++++++
>From 7685422a90e1da829cb32d685a4b970d30738098 Mon Sep 17 00:00:00 2001
From: Jose Dapena Paz <[email protected]>
Date: Wed, 3 Apr 2019 18:35:04 +0000
Subject: [PATCH] base: Value::Type enum class size should be 8-bit.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

GCC is complaining because, when base::Type is used to declare the different
variants of Type in its union, they are forced to take 8-bit, that is smaller
than the enum class default size (same as int).

So this change sets explicitely the enum class underlying type to be unsigned
char.

BUG=chromium:819294

Change-Id: I1765e2503e2c3d3675c73ecb0f7f5bc33456e6f0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1550366
Commit-Queue: José Dapena Paz <[email protected]>
Reviewed-by: Jan Wilken Dörrie <[email protected]>
Cr-Commit-Position: refs/heads/master@{#647382}
---
 base/values.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/base/values.h b/base/values.h
index c455936d4961..14b76acec02f 100644
--- a/base/values.h
+++ b/base/values.h
@@ -86,7 +86,7 @@ class BASE_EXPORT Value {
   // See technical note below explaining why this is used.
   using DoubleStorage = struct { alignas(4) char v[sizeof(double)]; };
 
-  enum class Type {
+  enum class Type : unsigned char {
     NONE = 0,
     BOOLEAN,
     INTEGER,
-- 
2.21.0

++++++ chromium-73.0.3683.103.tar.xz -> chromium-74.0.3729.108.tar.xz ++++++
/work/SRC/openSUSE:Factory/chromium/chromium-73.0.3683.103.tar.xz 
/work/SRC/openSUSE:Factory/.chromium.new.5148/chromium-74.0.3729.108.tar.xz 
differ: char 25, line 1

++++++ chromium-gcc.patch ++++++
--- /var/tmp/diff_new_pack.yvyoKb/_old  2019-05-02 19:18:04.373500496 +0200
+++ /var/tmp/diff_new_pack.yvyoKb/_new  2019-05-02 19:18:04.389500525 +0200
@@ -1,430 +1,12 @@
-From 2c3b57cafbbb38c13a519c9d2fda8b65691d9564 Mon Sep 17 00:00:00 2001
-From: Raphael Kubo da Costa <[email protected]>
-Date: Thu, 7 Feb 2019 22:55:37 +0000
-Subject: [PATCH] allocator shim: Swap ALIGN_LINKAGE and SHIM_ALWAYS_EXPORT's
- positions
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This fixes the GCC build. GCC seems to be stricter with the position of the
-linkage specification, so just swap the terms to prevent an error that looks
-like:
-
-In file included from ../../base/allocator/allocator_shim.cc:333:
-../../base/allocator/allocator_shim_override_cpp_symbols.h:39:30: error: 
expected unqualified-id before string constant
- #define ALIGN_LINKAGE extern "C"
-                              ^~~
-../../base/allocator/allocator_shim_override_cpp_symbols.h:99:20: note: in 
expansion of macro ‘ALIGN_LINKAGE’
- SHIM_ALWAYS_EXPORT ALIGN_LINKAGE void* ALIGN_NEW(std::size_t size,
-                    ^~~~~~~~~~~~~
-
-Bug: 819294
-Change-Id: I0aa16ea88cead42e83796a1c86afad8b447ddc50
-Reviewed-on: https://chromium-review.googlesource.com/c/1458256
-Auto-Submit: Raphael Kubo da Costa <[email protected]>
-Reviewed-by: Thomas Anderson <[email protected]>
-Reviewed-by: Primiano Tucci <[email protected]>
-Commit-Queue: Raphael Kubo da Costa <[email protected]>
-Cr-Commit-Position: refs/heads/master@{#630084}
----
- .../allocator_shim_override_cpp_symbols.h     | 20 +++++++++----------
- 1 file changed, 10 insertions(+), 10 deletions(-)
-
-Index: 
chromium-73.0.3683.75/base/allocator/allocator_shim_override_cpp_symbols.h
+Index: 
chromium-74.0.3729.108/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
 ===================================================================
---- 
chromium-73.0.3683.75.orig/base/allocator/allocator_shim_override_cpp_symbols.h
-+++ chromium-73.0.3683.75/base/allocator/allocator_shim_override_cpp_symbols.h
-@@ -96,57 +96,57 @@ SHIM_ALWAYS_EXPORT void operator delete[
-   ShimCppDelete(p);
- }
+--- 
chromium-74.0.3729.108.orig/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
++++ 
chromium-74.0.3729.108/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
+@@ -20,6 +20,7 @@
+ 
+ #include <memory>
+ #include <utility>
++#include <cstring>
  
--SHIM_ALWAYS_EXPORT ALIGN_LINKAGE void* ALIGN_NEW(std::size_t size,
-+ALIGN_LINKAGE SHIM_ALWAYS_EXPORT void* ALIGN_NEW(std::size_t size,
-                                                  ALIGN_VAL_T alignment) {
-   return ShimCppAlignedNew(size, static_cast<size_t>(alignment));
- }
- 
--SHIM_ALWAYS_EXPORT ALIGN_LINKAGE void* ALIGN_NEW_NOTHROW(
-+ALIGN_LINKAGE SHIM_ALWAYS_EXPORT void* ALIGN_NEW_NOTHROW(
-     std::size_t size,
-     ALIGN_VAL_T alignment,
-     const std::nothrow_t&) __THROW {
-   return ShimCppAlignedNew(size, static_cast<size_t>(alignment));
- }
- 
--SHIM_ALWAYS_EXPORT ALIGN_LINKAGE void ALIGN_DEL(void* p, ALIGN_VAL_T) __THROW 
{
-+ALIGN_LINKAGE SHIM_ALWAYS_EXPORT void ALIGN_DEL(void* p, ALIGN_VAL_T) __THROW 
{
-   ShimCppDelete(p);
- }
- 
--SHIM_ALWAYS_EXPORT ALIGN_LINKAGE void ALIGN_DEL_SIZED(void* p,
-+ALIGN_LINKAGE SHIM_ALWAYS_EXPORT void ALIGN_DEL_SIZED(void* p,
-                                                       std::size_t size,
-                                                       ALIGN_VAL_T) __THROW {
-   ShimCppDelete(p);
- }
- 
--SHIM_ALWAYS_EXPORT ALIGN_LINKAGE void
-+ALIGN_LINKAGE SHIM_ALWAYS_EXPORT void
- ALIGN_DEL_NOTHROW(void* p, ALIGN_VAL_T, const std::nothrow_t&) __THROW {
-   ShimCppDelete(p);
- }
- 
--SHIM_ALWAYS_EXPORT ALIGN_LINKAGE void* ALIGN_NEW_ARR(std::size_t size,
-+ALIGN_LINKAGE SHIM_ALWAYS_EXPORT void* ALIGN_NEW_ARR(std::size_t size,
-                                                      ALIGN_VAL_T alignment) {
-   return ShimCppAlignedNew(size, static_cast<size_t>(alignment));
- }
- 
--SHIM_ALWAYS_EXPORT ALIGN_LINKAGE void* ALIGN_NEW_ARR_NOTHROW(
-+ALIGN_LINKAGE SHIM_ALWAYS_EXPORT void* ALIGN_NEW_ARR_NOTHROW(
-     std::size_t size,
-     ALIGN_VAL_T alignment,
-     const std::nothrow_t&) __THROW {
-   return ShimCppAlignedNew(size, static_cast<size_t>(alignment));
- }
- 
--SHIM_ALWAYS_EXPORT ALIGN_LINKAGE void ALIGN_DEL_ARR(void* p,
-+ALIGN_LINKAGE SHIM_ALWAYS_EXPORT void ALIGN_DEL_ARR(void* p,
-                                                     ALIGN_VAL_T) __THROW {
-   ShimCppDelete(p);
- }
- 
--SHIM_ALWAYS_EXPORT ALIGN_LINKAGE void ALIGN_DEL_ARR_SIZED(void* p,
-+ALIGN_LINKAGE SHIM_ALWAYS_EXPORT void ALIGN_DEL_ARR_SIZED(void* p,
-                                                           std::size_t size,
-                                                           ALIGN_VAL_T) 
__THROW {
-   ShimCppDelete(p);
- }
- 
--SHIM_ALWAYS_EXPORT ALIGN_LINKAGE void
-+ALIGN_LINKAGE SHIM_ALWAYS_EXPORT void
- ALIGN_DEL_ARR_NOTHROW(void* p, ALIGN_VAL_T, const std::nothrow_t&) __THROW {
-   ShimCppDelete(p);
- }
-Index: chromium-73.0.3683.75/media/learning/common/labelled_example.cc
-===================================================================
---- chromium-73.0.3683.75.orig/media/learning/common/labelled_example.cc
-+++ chromium-73.0.3683.75/media/learning/common/labelled_example.cc
-@@ -59,7 +59,8 @@ bool LabelledExample::operator<(const La
- LabelledExample& LabelledExample::operator=(const LabelledExample& rhs) =
-     default;
- 
--LabelledExample& LabelledExample::operator=(LabelledExample&& rhs) = default;
-+LabelledExample& LabelledExample::operator=(LabelledExample&& rhs) noexcept =
-+    default;
- 
- TrainingData::TrainingData() = default;
- 
-Index: chromium-73.0.3683.75/media/learning/common/labelled_example.h
-===================================================================
---- chromium-73.0.3683.75.orig/media/learning/common/labelled_example.h
-+++ chromium-73.0.3683.75/media/learning/common/labelled_example.h
-@@ -40,7 +40,7 @@ struct COMPONENT_EXPORT(LEARNING_COMMON)
-   bool operator<(const LabelledExample& rhs) const;
- 
-   LabelledExample& operator=(const LabelledExample& rhs);
--  LabelledExample& operator=(LabelledExample&& rhs);
-+  LabelledExample& operator=(LabelledExample&& rhs) noexcept;
- 
-   // Observed feature values.
-   // Note that to interpret these values, you probably need to have the
-Index: chromium-73.0.3683.75/media/learning/common/value.cc
-===================================================================
---- chromium-73.0.3683.75.orig/media/learning/common/value.cc
-+++ chromium-73.0.3683.75/media/learning/common/value.cc
-@@ -23,6 +23,12 @@ Value::Value(const std::string& x) : val
- 
- Value::Value(const Value& other) : value_(other.value_) {}
- 
-+Value::Value(Value&& rhs) noexcept = default;
-+
-+Value& Value::operator=(const Value& rhs) = default;
-+
-+Value& Value::operator=(Value&& rhs) noexcept = default;
-+
- bool Value::operator==(const Value& rhs) const {
-   return value_ == rhs.value_;
- }
-Index: chromium-73.0.3683.75/media/learning/common/value.h
-===================================================================
---- chromium-73.0.3683.75.orig/media/learning/common/value.h
-+++ chromium-73.0.3683.75/media/learning/common/value.h
-@@ -38,6 +38,10 @@ class COMPONENT_EXPORT(LEARNING_COMMON)
-   explicit Value(const std::string& x);
- 
-   Value(const Value& other);
-+  Value(Value&&) noexcept;
-+
-+  Value& operator=(const Value&);
-+  Value& operator=(Value&&) noexcept;
- 
-   bool operator==(const Value& rhs) const;
-   bool operator!=(const Value& rhs) const;
-Index: chromium-73.0.3683.75/ui/gfx/color_utils.cc
-===================================================================
---- chromium-73.0.3683.75.orig/ui/gfx/color_utils.cc
-+++ chromium-73.0.3683.75/ui/gfx/color_utils.cc
-@@ -431,7 +431,7 @@ SkColor SetDarkestColorForTesting(SkColo
-   // GetContrastRatio(kWhiteLuminance, g_luminance_midpoint).  The formula 
below
-   // can be verified by plugging it into how GetContrastRatio() operates.
-   g_luminance_midpoint =
--      std::sqrtf((dark_luminance + 0.05f) * (kWhiteLuminance + 0.05f)) - 
0.05f;
-+      std::sqrt((dark_luminance + 0.05f) * (kWhiteLuminance + 0.05f)) - 0.05f;
- 
-   return previous_darkest_color;
- }
-Index: 
chromium-73.0.3683.75/net/third_party/quic/platform/impl/quic_flags_impl.cc
-===================================================================
---- 
chromium-73.0.3683.75.orig/net/third_party/quic/platform/impl/quic_flags_impl.cc
-+++ chromium-73.0.3683.75/net/third_party/quic/platform/impl/quic_flags_impl.cc
-@@ -5,6 +5,7 @@
- #include "net/third_party/quic/platform/impl/quic_flags_impl.h"
- 
- #include <algorithm>
-+#include <initializer_list>
- #include <iostream>
- #include <set>
- 
-@@ -153,9 +154,9 @@ std::string QuicFlagRegistry::GetHelp()
- template <>
- bool TypedQuicFlagHelper<bool>::SetFlag(const std::string& s) const {
-   static const base::NoDestructor<std::set<std::string>> kTrueValues(
--      {"", "1", "t", "true", "y", "yes"});
-+      std::initializer_list<std::string>({"", "1", "t", "true", "y", "yes"}));
-   static const base::NoDestructor<std::set<std::string>> kFalseValues(
--      {"0", "f", "false", "n", "no"});
-+      std::initializer_list<std::string>({"0", "f", "false", "n", "no"}));
-   if (kTrueValues->find(base::ToLowerASCII(s)) != kTrueValues->end()) {
-     *flag_ = true;
-     return true;
-Index: 
chromium-73.0.3683.75/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
-===================================================================
---- 
chromium-73.0.3683.75.orig/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
-+++ 
chromium-73.0.3683.75/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
-@@ -1769,12 +1769,12 @@ void BaseRenderingContext2D::putImageDat
-       CanvasColorParams(ColorParams().ColorSpace(), PixelFormat(), 
kNonOpaque);
-   if (data_color_params.NeedsColorConversion(context_color_params) ||
-       PixelFormat() == kF16CanvasPixelFormat) {
--    base::CheckedNumeric<size_t> data_length = data->Size().Area();
--    data_length *= context_color_params.BytesPerPixel();
--    if (!data_length.IsValid())
-+    size_t data_length;
-+    if (!base::CheckMul(data->Size().Area(),
-+                        context_color_params.BytesPerPixel())
-+             .AssignIfValid(&data_length))
-       return;
--    std::unique_ptr<uint8_t[]> converted_pixels(
--        new uint8_t[data_length.ValueOrDie()]);
-+    std::unique_ptr<uint8_t[]> converted_pixels(new uint8_t[data_length]);
-     if (data->ImageDataInCanvasColorSettings(
-             ColorParams().ColorSpace(), PixelFormat(), converted_pixels.get(),
-             kRGBAColorType)) {
-Index: 
chromium-73.0.3683.75/chrome/browser/media/router/providers/cast/cast_activity_manager.cc
-===================================================================
---- 
chromium-73.0.3683.75.orig/chrome/browser/media/router/providers/cast/cast_activity_manager.cc
-+++ 
chromium-73.0.3683.75/chrome/browser/media/router/providers/cast/cast_activity_manager.cc
-@@ -803,7 +803,7 @@ CastActivityManager::DoLaunchSessionPara
-       callback(std::move(callback)) {}
- 
- CastActivityManager::DoLaunchSessionParams::DoLaunchSessionParams(
--    DoLaunchSessionParams&& other) noexcept = default;
-+    DoLaunchSessionParams&& other) = default;
- 
- CastActivityManager::DoLaunchSessionParams::~DoLaunchSessionParams() = 
default;
- 
-Index: 
chromium-73.0.3683.75/chrome/browser/media/router/providers/cast/cast_activity_manager.h
-===================================================================
---- 
chromium-73.0.3683.75.orig/chrome/browser/media/router/providers/cast/cast_activity_manager.h
-+++ 
chromium-73.0.3683.75/chrome/browser/media/router/providers/cast/cast_activity_manager.h
-@@ -295,7 +295,7 @@ class CastActivityManager : public cast_
-         const url::Origin& origin,
-         int tab_id,
-         mojom::MediaRouteProvider::CreateRouteCallback callback);
--    DoLaunchSessionParams(DoLaunchSessionParams&& other) noexcept;
-+    DoLaunchSessionParams(DoLaunchSessionParams&& other);
-     ~DoLaunchSessionParams();
-     DoLaunchSessionParams& operator=(DoLaunchSessionParams&&) = delete;
- 
-Index: 
chromium-73.0.3683.75/chrome/browser/ui/views/extensions/extension_popup.cc
-===================================================================
---- 
chromium-73.0.3683.75.orig/chrome/browser/ui/views/extensions/extension_popup.cc
-+++ chromium-73.0.3683.75/chrome/browser/ui/views/extensions/extension_popup.cc
-@@ -8,7 +8,6 @@
- #include "chrome/browser/devtools/devtools_window.h"
- #include "chrome/browser/extensions/extension_view_host.h"
- #include "chrome/browser/ui/browser.h"
--#include "chrome/browser/ui/tabs/tab_strip_model.h"
- #include "content/public/browser/devtools_agent_host.h"
- #include "content/public/browser/notification_details.h"
- #include "content/public/browser/notification_source.h"
-Index: 
chromium-73.0.3683.75/chrome/browser/ui/views/extensions/extension_popup.h
-===================================================================
---- 
chromium-73.0.3683.75.orig/chrome/browser/ui/views/extensions/extension_popup.h
-+++ chromium-73.0.3683.75/chrome/browser/ui/views/extensions/extension_popup.h
-@@ -9,6 +9,7 @@
- #include "base/compiler_specific.h"
- #include "base/macros.h"
- #include "base/scoped_observer.h"
-+#include "chrome/browser/ui/tabs/tab_strip_model.h"
- #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
- #include "chrome/browser/ui/views/extensions/extension_view_views.h"
- #include "content/public/browser/devtools_agent_host_observer.h"
-Index: 
chromium-73.0.3683.75/chrome/browser/ui/views/toolbar/extension_toolbar_menu_view.h
-===================================================================
---- 
chromium-73.0.3683.75.orig/chrome/browser/ui/views/toolbar/extension_toolbar_menu_view.h
-+++ 
chromium-73.0.3683.75/chrome/browser/ui/views/toolbar/extension_toolbar_menu_view.h
-@@ -8,6 +8,7 @@
- #include "base/macros.h"
- #include "base/memory/weak_ptr.h"
- #include "base/scoped_observer.h"
-+#include "chrome/browser/ui/toolbar/toolbar_actions_bar.h"
- #include "chrome/browser/ui/toolbar/toolbar_actions_bar_observer.h"
- #include "chrome/browser/ui/views/toolbar/app_menu_observer.h"
- #include "ui/views/controls/scroll_view.h"
-@@ -15,7 +16,6 @@
- class AppMenu;
- class Browser;
- class BrowserActionsContainer;
--class ToolbarActionsBar;
- 
- namespace views {
- class MenuItemView;
-Index: chromium-73.0.3683.75/content/public/browser/desktop_media_id.h
-===================================================================
---- chromium-73.0.3683.75.orig/content/public/browser/desktop_media_id.h
-+++ chromium-73.0.3683.75/content/public/browser/desktop_media_id.h
-@@ -41,16 +41,16 @@ struct CONTENT_EXPORT DesktopMediaID {
-   static aura::Window* GetAuraWindowById(const DesktopMediaID& id);
- #endif  // defined(USE_AURA)
- 
--  constexpr DesktopMediaID() = default;
-+  DesktopMediaID() = default;
- 
--  constexpr DesktopMediaID(Type type, Id id) : type(type), id(id) {}
-+  DesktopMediaID(Type type, Id id) : type(type), id(id) {}
- 
--  constexpr DesktopMediaID(Type type,
-+  DesktopMediaID(Type type,
-                            Id id,
-                            WebContentsMediaCaptureId web_contents_id)
-       : type(type), id(id), web_contents_id(web_contents_id) {}
- 
--  constexpr DesktopMediaID(Type type, Id id, bool audio_share)
-+  DesktopMediaID(Type type, Id id, bool audio_share)
-       : type(type), id(id), audio_share(audio_share) {}
- 
-   // Operators so that DesktopMediaID can be used with STL containers.
-Index: 
chromium-73.0.3683.75/extensions/browser/api/declarative_webrequest/webrequest_action.cc
-===================================================================
---- 
chromium-73.0.3683.75.orig/extensions/browser/api/declarative_webrequest/webrequest_action.cc
-+++ 
chromium-73.0.3683.75/extensions/browser/api/declarative_webrequest/webrequest_action.cc
-@@ -578,7 +578,7 @@ base::Optional<EventResponseDelta> WebRe
-   CHECK(request_data.stage & stages());
-   EventResponseDelta result(extension_id, extension_install_time);
-   result.cancel = true;
--  return result;
-+  return base::make_optional(std::move(result));
- }
- 
- //
-@@ -613,7 +613,7 @@ base::Optional<EventResponseDelta> WebRe
-     return base::nullopt;
-   EventResponseDelta result(extension_id, extension_install_time);
-   result.new_url = redirect_url_;
--  return result;
-+  return base::make_optional(std::move(result));
- }
- 
- //
-@@ -642,7 +642,7 @@ WebRequestRedirectToTransparentImageActi
-   CHECK(request_data.stage & stages());
-   EventResponseDelta result(extension_id, extension_install_time);
-   result.new_url = GURL(kTransparentImageUrl);
--  return result;
-+  return base::make_optional(std::move(result));
- }
- 
- //
-@@ -671,7 +671,7 @@ WebRequestRedirectToEmptyDocumentAction:
-   CHECK(request_data.stage & stages());
-   EventResponseDelta result(extension_id, extension_install_time);
-   result.new_url = GURL(kEmptyDocumentUrl);
--  return result;
-+  return base::make_optional(std::move(result));
- }
- 
- //
-@@ -773,7 +773,7 @@ base::Optional<EventResponseDelta> WebRe
- 
-   EventResponseDelta result(extension_id, extension_install_time);
-   result.new_url = GURL(new_url);
--  return result;
-+  return base::make_optional(std::move(result));
- }
- 
- //
-@@ -813,7 +813,7 @@ WebRequestSetRequestHeaderAction::Create
-   CHECK(request_data.stage & stages());
-   EventResponseDelta result(extension_id, extension_install_time);
-   result.modified_request_headers.SetHeader(name_, value_);
--  return result;
-+  return base::make_optional(std::move(result));
- }
- 
- //
-@@ -851,7 +851,7 @@ WebRequestRemoveRequestHeaderAction::Cre
-   CHECK(request_data.stage & stages());
-   EventResponseDelta result(extension_id, extension_install_time);
-   result.deleted_request_headers.push_back(name_);
--  return result;
-+  return base::make_optional(std::move(result));
- }
- 
- //
-@@ -900,7 +900,7 @@ WebRequestAddResponseHeaderAction::Creat
- 
-   EventResponseDelta result(extension_id, extension_install_time);
-   result.added_response_headers.push_back(make_pair(name_, value_));
--  return result;
-+  return base::make_optional(std::move(result));
- }
- 
- //
-@@ -954,7 +954,7 @@ WebRequestRemoveResponseHeaderAction::Cr
-       continue;
-     result.deleted_response_headers.push_back(make_pair(name_, 
current_value));
-   }
--  return result;
-+  return base::make_optional(std::move(result));
- }
- 
- //
-@@ -1039,7 +1039,7 @@ base::Optional<EventResponseDelta> WebRe
-   EventResponseDelta result(extension_id, extension_install_time);
-   result.request_cookie_modifications.push_back(
-       request_cookie_modification_.Clone());
--  return result;
-+  return base::make_optional(std::move(result));
- }
- 
- //
-@@ -1087,7 +1087,7 @@ base::Optional<EventResponseDelta> WebRe
-   EventResponseDelta result(extension_id, extension_install_time);
-   result.response_cookie_modifications.push_back(
-       response_cookie_modification_.Clone());
--  return result;
-+  return base::make_optional(std::move(result));
- }
- 
- //
-@@ -1127,7 +1127,7 @@ WebRequestSendMessageToExtensionAction::
-   CHECK(request_data.stage & stages());
-   EventResponseDelta result(extension_id, extension_install_time);
-   result.messages_to_extension.insert(message_);
--  return result;
-+  return base::make_optional(std::move(result));
- }
- 
- }  // namespace extensions
+ #include "absl/memory/memory.h"
+ #include "modules/desktop_capture/desktop_capture_options.h"

++++++ chromium-non-void-return.patch ++++++
++++ 2641 lines (skipped)
++++ between /work/SRC/openSUSE:Factory/chromium/chromium-non-void-return.patch
++++ and 
/work/SRC/openSUSE:Factory/.chromium.new.5148/chromium-non-void-return.patch

++++++ chromium-old-glibc.patch ++++++
--- /var/tmp/diff_new_pack.yvyoKb/_old  2019-05-02 19:18:04.865501391 +0200
+++ /var/tmp/diff_new_pack.yvyoKb/_new  2019-05-02 19:18:04.877501413 +0200
@@ -1,8 +1,8 @@
-Index: chromium-73.0.3673.0/gpu/config/gpu_info.cc
+Index: chromium-74.0.3729.108/gpu/config/gpu_info.cc
 ===================================================================
---- chromium-73.0.3673.0.orig/gpu/config/gpu_info.cc
-+++ chromium-73.0.3673.0/gpu/config/gpu_info.cc
-@@ -112,15 +112,15 @@ GPUInfo::GPUDevice::GPUDevice()
+--- chromium-74.0.3729.108.orig/gpu/config/gpu_info.cc
++++ chromium-74.0.3729.108/gpu/config/gpu_info.cc
+@@ -177,15 +177,15 @@ GPUInfo::GPUDevice::GPUDevice()
  
  GPUInfo::GPUDevice::GPUDevice(const GPUInfo::GPUDevice& other) = default;
  
@@ -21,11 +21,11 @@
  
  GPUInfo::GPUInfo()
      : optimus(false),
-Index: chromium-73.0.3673.0/components/policy/core/common/policy_map.cc
+Index: chromium-74.0.3729.108/components/policy/core/common/policy_map.cc
 ===================================================================
---- chromium-73.0.3673.0.orig/components/policy/core/common/policy_map.cc
-+++ chromium-73.0.3673.0/components/policy/core/common/policy_map.cc
-@@ -17,8 +17,8 @@ PolicyMap::Entry::Entry() = default;
+--- chromium-74.0.3729.108.orig/components/policy/core/common/policy_map.cc
++++ chromium-74.0.3729.108/components/policy/core/common/policy_map.cc
+@@ -29,8 +29,8 @@ PolicyMap::Entry::Entry(
  
  PolicyMap::Entry::~Entry() = default;
  
@@ -36,10 +36,10 @@
  
  PolicyMap::Entry PolicyMap::Entry::DeepCopy() const {
    Entry copy;
-Index: chromium-73.0.3673.0/components/search_provider_logos/logo_common.cc
+Index: chromium-74.0.3729.108/components/search_provider_logos/logo_common.cc
 ===================================================================
---- chromium-73.0.3673.0.orig/components/search_provider_logos/logo_common.cc
-+++ chromium-73.0.3673.0/components/search_provider_logos/logo_common.cc
+--- chromium-74.0.3729.108.orig/components/search_provider_logos/logo_common.cc
++++ chromium-74.0.3729.108/components/search_provider_logos/logo_common.cc
 @@ -12,24 +12,24 @@ const int64_t kMaxTimeToLiveMS = INT64_C
  
  LogoMetadata::LogoMetadata() = default;
@@ -71,11 +71,26 @@
  LogoCallbacks::~LogoCallbacks() = default;
  
  }  // namespace search_provider_logos
-Index: chromium-73.0.3673.0/components/signin/core/browser/account_info.cc
+Index: chromium-74.0.3729.108/components/signin/core/browser/account_info.cc
 ===================================================================
---- chromium-73.0.3673.0.orig/components/signin/core/browser/account_info.cc
-+++ chromium-73.0.3673.0/components/signin/core/browser/account_info.cc
-@@ -28,11 +28,11 @@ AccountInfo::~AccountInfo() = default;
+--- chromium-74.0.3729.108.orig/components/signin/core/browser/account_info.cc
++++ chromium-74.0.3729.108/components/signin/core/browser/account_info.cc
+@@ -46,12 +46,12 @@ CoreAccountInfo::~CoreAccountInfo() = de
+ 
+ CoreAccountInfo::CoreAccountInfo(const CoreAccountInfo& other) = default;
+ 
+-CoreAccountInfo::CoreAccountInfo(CoreAccountInfo&& other) noexcept = default;
++CoreAccountInfo::CoreAccountInfo(CoreAccountInfo&& other) = default;
+ 
+ CoreAccountInfo& CoreAccountInfo::operator=(const CoreAccountInfo& other) =
+     default;
+ 
+-CoreAccountInfo& CoreAccountInfo::operator=(CoreAccountInfo&& other) noexcept 
=
++CoreAccountInfo& CoreAccountInfo::operator=(CoreAccountInfo&& other) =
+     default;
+ 
+ bool CoreAccountInfo::IsEmpty() const {
+@@ -64,11 +64,11 @@ AccountInfo::~AccountInfo() = default;
  
  AccountInfo::AccountInfo(const AccountInfo& other) = default;
  
@@ -88,11 +103,11 @@
 +AccountInfo& AccountInfo::operator=(AccountInfo&& other) = default;
  
  bool AccountInfo::IsEmpty() const {
-   return account_id.empty() && email.empty() && gaia.empty() &&
-Index: chromium-73.0.3673.0/chrome/common/media_router/media_sink.cc
+   return CoreAccountInfo::IsEmpty() && hosted_domain.empty() &&
+Index: chromium-74.0.3729.108/chrome/common/media_router/media_sink.cc
 ===================================================================
---- chromium-73.0.3673.0.orig/chrome/common/media_router/media_sink.cc
-+++ chromium-73.0.3673.0/chrome/common/media_router/media_sink.cc
+--- chromium-74.0.3729.108.orig/chrome/common/media_router/media_sink.cc
++++ chromium-74.0.3729.108/chrome/common/media_router/media_sink.cc
 @@ -19,12 +19,12 @@ MediaSink::MediaSink(const MediaSink::Id
        provider_id_(provider_id) {}
  

++++++ old-libva.patch ++++++
Index: chromium-74.0.3729.108/media/gpu/vaapi/vaapi_wrapper.cc
===================================================================
--- chromium-74.0.3729.108.orig/media/gpu/vaapi/vaapi_wrapper.cc
+++ chromium-74.0.3729.108/media/gpu/vaapi/vaapi_wrapper.cc
@@ -286,9 +286,6 @@ bool VADisplayState::Initialize() {
 }
 
 bool VADisplayState::InitializeOnce() {
-  static_assert(VA_MAJOR_VERSION >= 1 && VA_MINOR_VERSION >= 1,
-                "Requires VA-API >= 1.1.0");
-
   switch (gl::GetGLImplementation()) {
     case gl::kGLImplementationEGLGLES2:
       va_display_ = vaGetDisplayDRM(drm_fd_.get());
Index: chromium-74.0.3729.108/media/gpu/vaapi/vaapi_jpeg_decode_accelerator.cc
===================================================================
--- chromium-74.0.3729.108.orig/media/gpu/vaapi/vaapi_jpeg_decode_accelerator.cc
+++ chromium-74.0.3729.108/media/gpu/vaapi/vaapi_jpeg_decode_accelerator.cc
@@ -29,6 +29,10 @@
 #include "third_party/libyuv/include/libyuv.h"
 #include "ui/gfx/geometry/size.h"
 
+#ifndef VA_FOURCC_I420
+#define VA_FOURCC_I420 0x30323449
+#endif
+
 namespace media {
 
 namespace {
Index: chromium-74.0.3729.108/media/gpu/vaapi/vaapi_jpeg_decoder.cc
===================================================================
--- chromium-74.0.3729.108.orig/media/gpu/vaapi/vaapi_jpeg_decoder.cc
+++ chromium-74.0.3729.108/media/gpu/vaapi/vaapi_jpeg_decoder.cc
@@ -19,6 +19,10 @@
 #include "media/gpu/vaapi/vaapi_utils.h"
 #include "media/gpu/vaapi/vaapi_wrapper.h"
 
+#ifndef VA_FOURCC_I420
+#define VA_FOURCC_I420 0x30323449
+#endif
+
 namespace media {
 
 namespace {
++++++ quic.patch ++++++
description: fix gcc compile error with substreams_ initializer list
author: Michael Gilbert <[email protected]>

--- a/net/third_party/quic/core/quic_crypto_stream.cc
+++ b/net/third_party/quic/core/quic_crypto_stream.cc
@@ -28,9 +28,9 @@ QuicCryptoStream::QuicCryptoStream(QuicS
                  session,
                  /*is_static=*/true,
                  BIDIRECTIONAL),
-      substreams_{{this, ENCRYPTION_NONE},
-                  {this, ENCRYPTION_ZERO_RTT},
-                  {this, ENCRYPTION_FORWARD_SECURE}} {
+     substreams_{std::make_unique<CryptoSubstream>(this, ENCRYPTION_NONE),
+                 std::make_unique<CryptoSubstream>(this, ENCRYPTION_ZERO_RTT),
+                 std::make_unique<CryptoSubstream>(this, 
ENCRYPTION_FORWARD_SECURE)} {
   // The crypto stream is exempt from connection level flow control.
   DisableConnectionFlowControlForThisStream();
 }
@@ -57,7 +57,7 @@ void QuicCryptoStream::OnCryptoFrame(con
   QUIC_BUG_IF(session()->connection()->transport_version() < QUIC_VERSION_47)
       << "Versions less than 47 shouldn't receive CRYPTO frames";
   EncryptionLevel level = session()->connection()->last_decrypted_level();
-  substreams_[level].sequencer.OnCryptoFrame(frame);
+  substreams_[level]->sequencer.OnCryptoFrame(frame);
 }
 
 void QuicCryptoStream::OnStreamFrame(const QuicStreamFrame& frame) {
@@ -79,7 +79,7 @@ void QuicCryptoStream::OnDataAvailable()
     OnDataAvailableInSequencer(sequencer(), level);
     return;
   }
-  OnDataAvailableInSequencer(&substreams_[level].sequencer, level);
+  OnDataAvailableInSequencer(&substreams_[level]->sequencer, level);
 }
 
 void QuicCryptoStream::OnDataAvailableInSequencer(
@@ -133,7 +133,7 @@ void QuicCryptoStream::WriteCryptoData(E
   }
   // Append |data| to the send buffer for this encryption level.
   struct iovec iov(QuicUtils::MakeIovec(data));
-  QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
+  QuicStreamSendBuffer* send_buffer = &substreams_[level]->send_buffer;
   QuicStreamOffset offset = send_buffer->stream_offset();
   send_buffer->SaveStreamData(&iov, /*iov_count=*/1, /*iov_offset=*/0,
                               data.length());
@@ -160,7 +160,7 @@ void QuicCryptoStream::OnSuccessfulVersi
 bool QuicCryptoStream::OnCryptoFrameAcked(const QuicCryptoFrame& frame,
                                           QuicTime::Delta ack_delay_time) {
   QuicByteCount newly_acked_length = 0;
-  if (!substreams_[frame.level].send_buffer.OnStreamDataAcked(
+  if (!substreams_[frame.level]->send_buffer.OnStreamDataAcked(
           frame.offset, frame.data_length, &newly_acked_length)) {
     CloseConnectionWithDetails(QUIC_INTERNAL_ERROR,
                                "Trying to ack unsent crypto data.");
@@ -178,7 +178,7 @@ void QuicCryptoStream::NeuterUnencrypted
     }
     return;
   }
-  QuicStreamSendBuffer* send_buffer = 
&substreams_[ENCRYPTION_NONE].send_buffer;
+  QuicStreamSendBuffer* send_buffer = 
&substreams_[ENCRYPTION_NONE]->send_buffer;
   // TODO(nharper): Consider adding a Clear() method to QuicStreamSendBuffer to
   // replace the following code.
   QuicIntervalSet<QuicStreamOffset> to_ack = send_buffer->bytes_acked();
@@ -207,7 +207,7 @@ bool QuicCryptoStream::HasPendingCryptoR
   }
   for (EncryptionLevel level :
        {ENCRYPTION_NONE, ENCRYPTION_ZERO_RTT, ENCRYPTION_FORWARD_SECURE}) {
-    if (substreams_[level].send_buffer.HasPendingRetransmission()) {
+    if (substreams_[level]->send_buffer.HasPendingRetransmission()) {
       return true;
     }
   }
@@ -221,7 +221,7 @@ void QuicCryptoStream::WritePendingCrypt
       session()->connection()->encryption_level();
   for (EncryptionLevel level :
        {ENCRYPTION_NONE, ENCRYPTION_ZERO_RTT, ENCRYPTION_FORWARD_SECURE}) {
-    QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
+    QuicStreamSendBuffer* send_buffer = &substreams_[level]->send_buffer;
     session()->connection()->SetDefaultEncryptionLevel(level);
     while (send_buffer->HasPendingRetransmission()) {
       auto pending = send_buffer->NextPendingRetransmission();
@@ -326,13 +326,13 @@ uint64_t QuicCryptoStream::crypto_bytes_
   if (session()->connection()->transport_version() < QUIC_VERSION_47) {
     return stream_bytes_read();
   }
-  return substreams_[ENCRYPTION_NONE].sequencer.NumBytesConsumed() +
-         substreams_[ENCRYPTION_ZERO_RTT].sequencer.NumBytesConsumed() +
-         substreams_[ENCRYPTION_FORWARD_SECURE].sequencer.NumBytesConsumed();
+  return substreams_[ENCRYPTION_NONE]->sequencer.NumBytesConsumed() +
+         substreams_[ENCRYPTION_ZERO_RTT]->sequencer.NumBytesConsumed() +
+         substreams_[ENCRYPTION_FORWARD_SECURE]->sequencer.NumBytesConsumed();
 }
 
 uint64_t QuicCryptoStream::BytesReadOnLevel(EncryptionLevel level) const {
-  return substreams_[level].sequencer.NumBytesConsumed();
+  return substreams_[level]->sequencer.NumBytesConsumed();
 }
 
 bool QuicCryptoStream::WriteCryptoFrame(EncryptionLevel level,
@@ -341,14 +341,14 @@ bool QuicCryptoStream::WriteCryptoFrame(
                                         QuicDataWriter* writer) {
   QUIC_BUG_IF(session()->connection()->transport_version() < QUIC_VERSION_47)
       << "Versions less than 47 don't write CRYPTO frames (2)";
-  return substreams_[level].send_buffer.WriteStreamData(offset, data_length,
+  return substreams_[level]->send_buffer.WriteStreamData(offset, data_length,
                                                         writer);
 }
 
 void QuicCryptoStream::OnCryptoFrameLost(QuicCryptoFrame* crypto_frame) {
   QUIC_BUG_IF(session()->connection()->transport_version() < QUIC_VERSION_47)
       << "Versions less than 47 don't lose CRYPTO frames";
-  substreams_[crypto_frame->level].send_buffer.OnStreamDataLost(
+  substreams_[crypto_frame->level]->send_buffer.OnStreamDataLost(
       crypto_frame->offset, crypto_frame->data_length);
 }
 
@@ -358,7 +358,7 @@ void QuicCryptoStream::RetransmitData(Qu
   QuicIntervalSet<QuicStreamOffset> retransmission(
       crypto_frame->offset, crypto_frame->offset + crypto_frame->data_length);
   QuicStreamSendBuffer* send_buffer =
-      &substreams_[crypto_frame->level].send_buffer;
+      &substreams_[crypto_frame->level]->send_buffer;
   retransmission.Difference(send_buffer->bytes_acked());
   if (retransmission.Empty()) {
     return;
@@ -389,7 +389,7 @@ bool QuicCryptoStream::IsFrameOutstandin
     // the wrong transport version.
     return false;
   }
-  return substreams_[level].send_buffer.IsStreamDataOutstanding(offset, 
length);
+  return substreams_[level]->send_buffer.IsStreamDataOutstanding(offset, 
length);
 }
 
 bool QuicCryptoStream::IsWaitingForAcks() const {
@@ -398,7 +398,7 @@ bool QuicCryptoStream::IsWaitingForAcks(
   }
   for (EncryptionLevel level :
        {ENCRYPTION_NONE, ENCRYPTION_ZERO_RTT, ENCRYPTION_FORWARD_SECURE}) {
-    if (substreams_[level].send_buffer.stream_bytes_outstanding()) {
+    if (substreams_[level]->send_buffer.stream_bytes_outstanding()) {
       return true;
     }
   }
--- a/net/third_party/quic/core/quic_crypto_stream.h
+++ b/net/third_party/quic/core/quic_crypto_stream.h
@@ -166,7 +166,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoStre
 
   // Keeps state for data sent/received in CRYPTO frames at each encryption
   // level.
-  CryptoSubstream substreams_[NUM_ENCRYPTION_LEVELS];
+  std::unique_ptr<CryptoSubstream> substreams_[NUM_ENCRYPTION_LEVELS];
 };
 
 }  // namespace quic

Reply via email to