diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 6e3ddbdc..fd079e6c 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -1443,7 +1443,11 @@
     # Favor size over speed.
     # TODO(crbug.com/718650): Fix -Os in PNaCl compiler and remove the is_nacl
     # guard above.
-    cflags = [ "-Os" ] + common_optimize_on_cflags
+    if (is_clang) {
+      cflags = [ "-Oz" ] + common_optimize_on_cflags
+    } else {
+      cflags = [ "-Os" ] + common_optimize_on_cflags
+    }
   } else {
     cflags = [ "-O2" ] + common_optimize_on_cflags
   }
@@ -1460,7 +1464,11 @@
     # Favor size over speed.
     # TODO(crbug.com/718650): Fix -Os in PNaCl compiler and remove the is_nacl
     # guard above.
-    cflags = [ "-Os" ] + common_optimize_on_cflags
+    if (is_clang) {
+      cflags = [ "-Oz" ] + common_optimize_on_cflags
+    } else {
+      cflags = [ "-Os" ] + common_optimize_on_cflags
+    }
   } else if (optimize_for_fuzzing) {
     cflags = [ "-O1" ] + common_optimize_on_cflags
   } else {
@@ -1480,7 +1488,11 @@
   } else if (is_android && !android_full_debug) {
     # On Android we kind of optimize some things that don't affect debugging
     # much even when optimization is disabled to get the binary size down.
-    cflags = [ "-Os" ]
+    if (is_clang) {
+      cflags = [ "-Oz" ] + common_optimize_on_cflags
+    } else {
+      cflags = [ "-Os" ] + common_optimize_on_cflags
+    }
   } else {
     cflags = [ "-O0" ]
     ldflags = []
diff --git a/net/quic/core/crypto/crypto_handshake_message.cc b/net/quic/core/crypto/crypto_handshake_message.cc
index 220c46a..0d0813a 100644
--- a/net/quic/core/crypto/crypto_handshake_message.cc
+++ b/net/quic/core/crypto/crypto_handshake_message.cc
@@ -79,9 +79,9 @@
   tag_value_map_.erase(tag);
 }
 
-QuicErrorCode CryptoHandshakeMessage::GetTaglist(QuicTag tag,
-                                                 const QuicTag** out_tags,
-                                                 size_t* out_len) const {
+QuicErrorCode CryptoHandshakeMessage::GetTaglist(
+    QuicTag tag,
+    QuicTagVector* out_tags) const {
   QuicTagValueMap::const_iterator it = tag_value_map_.find(tag);
   QuicErrorCode ret = QUIC_NO_ERROR;
 
@@ -92,13 +92,17 @@
   }
 
   if (ret != QUIC_NO_ERROR) {
-    *out_tags = nullptr;
-    *out_len = 0;
+    out_tags->clear();
     return ret;
   }
 
-  *out_tags = reinterpret_cast<const QuicTag*>(it->second.data());
-  *out_len = it->second.size() / sizeof(QuicTag);
+  size_t num_tags = it->second.size() / sizeof(QuicTag);
+  out_tags->resize(num_tags);
+  for (size_t i = 0; i < num_tags; ++i) {
+    QuicTag tag;
+    memcpy(&tag, it->second.data() + i * sizeof(tag), sizeof(tag));
+    (*out_tags)[i] = tag;
+  }
   return ret;
 }
 
diff --git a/net/quic/core/crypto/crypto_handshake_message.h b/net/quic/core/crypto/crypto_handshake_message.h
index 6275faad4..f646ce59 100644
--- a/net/quic/core/crypto/crypto_handshake_message.h
+++ b/net/quic/core/crypto/crypto_handshake_message.h
@@ -73,13 +73,8 @@
 
   // GetTaglist finds an element with the given tag containing zero or more
   // tags. If such a tag doesn't exist, it returns an error code. Otherwise it
-  // sets |out_tags| and |out_len| to point to the array of tags and returns
-  // QUIC_NO_ERROR.  The array points into the CryptoHandshakeMessage and is
-  // valid only for as long as the CryptoHandshakeMessage exists and is not
-  // modified.
-  QuicErrorCode GetTaglist(QuicTag tag,
-                           const QuicTag** out_tags,
-                           size_t* out_len) const;
+  // populates |out_tags| with the tags and returns QUIC_NO_ERROR.
+  QuicErrorCode GetTaglist(QuicTag tag, QuicTagVector* out_tags) const;
 
   bool GetStringPiece(QuicTag tag, QuicStringPiece* out) const;
   bool HasStringPiece(QuicTag tag) const;
diff --git a/net/quic/core/crypto/crypto_server_test.cc b/net/quic/core/crypto/crypto_server_test.cc
index 13a040e..1ca1e1e 100644
--- a/net/quic/core/crypto/crypto_server_test.cc
+++ b/net/quic/core/crypto/crypto_server_test.cc
@@ -216,11 +216,10 @@
   };
 
   void CheckServerHello(const CryptoHandshakeMessage& server_hello) {
-    const QuicTag* versions;
-    size_t num_versions;
-    server_hello.GetTaglist(kVER, &versions, &num_versions);
-    ASSERT_EQ(supported_versions_.size(), num_versions);
-    for (size_t i = 0; i < num_versions; ++i) {
+    QuicTagVector versions;
+    server_hello.GetTaglist(kVER, &versions);
+    ASSERT_EQ(supported_versions_.size(), versions.size());
+    for (size_t i = 0; i < versions.size(); ++i) {
       EXPECT_EQ(QuicVersionToQuicTag(supported_versions_[i]), versions[i]);
     }
 
@@ -340,15 +339,13 @@
   void CheckRejectReasons(
       const HandshakeFailureReason* expected_handshake_failures,
       size_t expected_count) {
-    const uint32_t* reject_reasons;
-    size_t num_reject_reasons;
+    QuicTagVector reject_reasons;
     static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync");
-    QuicErrorCode error_code =
-        out_.GetTaglist(kRREJ, &reject_reasons, &num_reject_reasons);
+    QuicErrorCode error_code = out_.GetTaglist(kRREJ, &reject_reasons);
     ASSERT_EQ(QUIC_NO_ERROR, error_code);
 
-    EXPECT_EQ(expected_count, num_reject_reasons);
-    for (size_t i = 0; i < num_reject_reasons; ++i) {
+    EXPECT_EQ(expected_count, reject_reasons.size());
+    for (size_t i = 0; i < reject_reasons.size(); ++i) {
       EXPECT_EQ(expected_handshake_failures[i], reject_reasons[i]);
     }
   }
diff --git a/net/quic/core/crypto/crypto_utils.cc b/net/quic/core/crypto/crypto_utils.cc
index 0e005bff2..382acc7 100644
--- a/net/quic/core/crypto/crypto_utils.cc
+++ b/net/quic/core/crypto/crypto_utils.cc
@@ -188,17 +188,14 @@
     return QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
   }
 
-  const QuicTag* supported_version_tags;
-  size_t num_supported_versions;
-
-  if (server_hello.GetTaglist(kVER, &supported_version_tags,
-                              &num_supported_versions) != QUIC_NO_ERROR) {
+  QuicTagVector supported_version_tags;
+  if (server_hello.GetTaglist(kVER, &supported_version_tags) != QUIC_NO_ERROR) {
     *error_details = "server hello missing version list";
     return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
   }
   if (!negotiated_versions.empty()) {
-    bool mismatch = num_supported_versions != negotiated_versions.size();
-    for (size_t i = 0; i < num_supported_versions && !mismatch; ++i) {
+    bool mismatch = supported_version_tags.size() != negotiated_versions.size();
+    for (size_t i = 0; i < supported_version_tags.size() && !mismatch; ++i) {
       mismatch = QuicTagToQuicVersion(supported_version_tags[i]) !=
                  negotiated_versions[i];
     }
diff --git a/net/quic/core/crypto/quic_crypto_client_config.cc b/net/quic/core/crypto/quic_crypto_client_config.cc
index 2a80d68..fcd630ac 100644
--- a/net/quic/core/crypto/quic_crypto_client_config.cc
+++ b/net/quic/core/crypto/quic_crypto_client_config.cc
@@ -527,13 +527,10 @@
 
   out->SetStringPiece(kCertificateSCTTag, "");
 
-  const QuicTag* their_aeads;
-  const QuicTag* their_key_exchanges;
-  size_t num_their_aeads, num_their_key_exchanges;
-  if (scfg->GetTaglist(kAEAD, &their_aeads, &num_their_aeads) !=
-          QUIC_NO_ERROR ||
-      scfg->GetTaglist(kKEXS, &their_key_exchanges, &num_their_key_exchanges) !=
-          QUIC_NO_ERROR) {
+  QuicTagVector their_aeads;
+  QuicTagVector their_key_exchanges;
+  if (scfg->GetTaglist(kAEAD, &their_aeads) != QUIC_NO_ERROR ||
+      scfg->GetTaglist(kKEXS, &their_key_exchanges) != QUIC_NO_ERROR) {
     *error_details = "Missing AEAD or KEXS";
     return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
   }
@@ -544,10 +541,11 @@
   // Key exchange: the client does more work than the server, so favor the
   // client's preference.
   size_t key_exchange_index;
-  if (!FindMutualQuicTag(aead, their_aeads, num_their_aeads, &out_params->aead,
-                         nullptr) ||
-      !FindMutualQuicTag(kexs, their_key_exchanges, num_their_key_exchanges,
-                         &out_params->key_exchange, &key_exchange_index)) {
+  if (!FindMutualQuicTag(aead, their_aeads.data(), their_aeads.size(),
+                         &out_params->aead, nullptr) ||
+      !FindMutualQuicTag(kexs, their_key_exchanges.data(),
+                         their_key_exchanges.size(), &out_params->key_exchange,
+                         &key_exchange_index)) {
     *error_details = "Unsupported AEAD or KEXS";
     return QUIC_CRYPTO_NO_SUPPORT;
   }
@@ -556,13 +554,13 @@
 
   if (!tb_key_params.empty() &&
       server_id.privacy_mode() == PRIVACY_MODE_DISABLED) {
-    const QuicTag* their_tbkps;
-    size_t num_their_tbkps;
-    switch (scfg->GetTaglist(kTBKP, &their_tbkps, &num_their_tbkps)) {
+    QuicTagVector their_tbkps;
+    switch (scfg->GetTaglist(kTBKP, &their_tbkps)) {
       case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
         break;
       case QUIC_NO_ERROR:
-        if (FindMutualQuicTag(tb_key_params, their_tbkps, num_their_tbkps,
+        if (FindMutualQuicTag(tb_key_params, their_tbkps.data(),
+                              their_tbkps.size(),
                               &out_params->token_binding_key_param, nullptr)) {
           out->SetVector(kTBKP,
                          QuicTagVector{out_params->token_binding_key_param});
diff --git a/net/quic/core/crypto/quic_crypto_server_config.cc b/net/quic/core/crypto/quic_crypto_server_config.cc
index f0f40a0..072085ea 100644
--- a/net/quic/core/crypto/quic_crypto_server_config.cc
+++ b/net/quic/core/crypto/quic_crypto_server_config.cc
@@ -694,12 +694,8 @@
 
   // No need to get a new proof if one was already generated.
   if (!signed_config->chain) {
-    const QuicTag* tag_ptr;
-    size_t num_tags;
     QuicTagVector connection_options;
-    if (client_hello.GetTaglist(kCOPT, &tag_ptr, &num_tags) == QUIC_NO_ERROR) {
-      connection_options.assign(tag_ptr, tag_ptr + num_tags);
-    }
+    client_hello.GetTaglist(kCOPT, &connection_options);
     std::unique_ptr<ProcessClientHelloCallback> cb(
         new ProcessClientHelloCallback(
             this, validate_chlo_result, reject_only, connection_id,
@@ -790,39 +786,35 @@
     return;
   }
 
-  const QuicTag* their_aeads;
-  const QuicTag* their_key_exchanges;
-  size_t num_their_aeads, num_their_key_exchanges;
-  if (client_hello.GetTaglist(kAEAD, &their_aeads, &num_their_aeads) !=
-          QUIC_NO_ERROR ||
-      client_hello.GetTaglist(kKEXS, &their_key_exchanges,
-                              &num_their_key_exchanges) != QUIC_NO_ERROR ||
-      num_their_aeads != 1 || num_their_key_exchanges != 1) {
+  QuicTagVector their_aeads;
+  QuicTagVector their_key_exchanges;
+  if (client_hello.GetTaglist(kAEAD, &their_aeads) != QUIC_NO_ERROR ||
+      client_hello.GetTaglist(kKEXS, &their_key_exchanges) != QUIC_NO_ERROR ||
+      their_aeads.size() != 1 || their_key_exchanges.size() != 1) {
     helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
                 "Missing or invalid AEAD or KEXS");
     return;
   }
 
   size_t key_exchange_index;
-  if (!FindMutualQuicTag(requested_config->aead, their_aeads, num_their_aeads,
-                         &params->aead, nullptr) ||
-      !FindMutualQuicTag(requested_config->kexs, their_key_exchanges,
-                         num_their_key_exchanges, &params->key_exchange,
+  if (!FindMutualQuicTag(requested_config->aead, their_aeads.data(),
+                         their_aeads.size(), &params->aead, nullptr) ||
+      !FindMutualQuicTag(requested_config->kexs, their_key_exchanges.data(),
+                         their_key_exchanges.size(), &params->key_exchange,
                          &key_exchange_index)) {
     helper.Fail(QUIC_CRYPTO_NO_SUPPORT, "Unsupported AEAD or KEXS");
     return;
   }
 
   if (!requested_config->tb_key_params.empty()) {
-    const QuicTag* their_tbkps;
-    size_t num_their_tbkps;
-    switch (client_hello.GetTaglist(kTBKP, &their_tbkps, &num_their_tbkps)) {
+    QuicTagVector their_tbkps;
+    switch (client_hello.GetTaglist(kTBKP, &their_tbkps)) {
       case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
         break;
       case QUIC_NO_ERROR:
-        if (FindMutualQuicTag(requested_config->tb_key_params, their_tbkps,
-                              num_their_tbkps, &params->token_binding_key_param,
-                              nullptr)) {
+        if (FindMutualQuicTag(requested_config->tb_key_params,
+                              their_tbkps.data(), their_tbkps.size(),
+                              &params->token_binding_key_param, nullptr)) {
           break;
         }
       default:
@@ -1266,12 +1258,8 @@
                                     Perspective::IS_SERVER);
   bool need_proof = true;
   need_proof = !signed_config->chain;
-  const QuicTag* tag_ptr;
-  size_t num_tags;
   QuicTagVector connection_options;
-  if (client_hello.GetTaglist(kCOPT, &tag_ptr, &num_tags) == QUIC_NO_ERROR) {
-    connection_options.assign(tag_ptr, tag_ptr + num_tags);
-  }
+  client_hello.GetTaglist(kCOPT, &connection_options);
 
   if (need_proof) {
     // Make an async call to GetProof and setup the callback to trampoline
@@ -1623,31 +1611,24 @@
   }
   config->id = scid.as_string();
 
-  const QuicTag* aead_tags;
-  size_t aead_len;
-  if (msg->GetTaglist(kAEAD, &aead_tags, &aead_len) != QUIC_NO_ERROR) {
+  if (msg->GetTaglist(kAEAD, &config->aead) != QUIC_NO_ERROR) {
     QUIC_LOG(WARNING) << "Server config message is missing AEAD";
     return nullptr;
   }
-  config->aead = std::vector<QuicTag>(aead_tags, aead_tags + aead_len);
 
-  const QuicTag* kexs_tags;
-  size_t kexs_len;
-  if (msg->GetTaglist(kKEXS, &kexs_tags, &kexs_len) != QUIC_NO_ERROR) {
+  QuicTagVector kexs_tags;
+  if (msg->GetTaglist(kKEXS, &kexs_tags) != QUIC_NO_ERROR) {
     QUIC_LOG(WARNING) << "Server config message is missing KEXS";
     return nullptr;
   }
 
-  const QuicTag* tbkp_tags;
-  size_t tbkp_len;
   QuicErrorCode err;
-  if ((err = msg->GetTaglist(kTBKP, &tbkp_tags, &tbkp_len)) !=
+  if ((err = msg->GetTaglist(kTBKP, &config->tb_key_params)) !=
           QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND &&
       err != QUIC_NO_ERROR) {
     QUIC_LOG(WARNING) << "Server config message is missing or has invalid TBKP";
     return nullptr;
   }
-  config->tb_key_params = std::vector<QuicTag>(tbkp_tags, tbkp_tags + tbkp_len);
 
   QuicStringPiece orbit;
   if (!msg->GetStringPiece(kORBT, &orbit)) {
@@ -1664,26 +1645,24 @@
   static_assert(sizeof(config->orbit) == kOrbitSize, "incorrect orbit size");
   memcpy(config->orbit, orbit.data(), sizeof(config->orbit));
 
-  if (kexs_len != protobuf->key_size()) {
-    QUIC_LOG(WARNING) << "Server config has " << kexs_len
+  if (kexs_tags.size() != protobuf->key_size()) {
+    QUIC_LOG(WARNING) << "Server config has " << kexs_tags.size()
                       << " key exchange methods configured, but "
                       << protobuf->key_size() << " private keys";
     return nullptr;
   }
 
-  const QuicTag* proof_demand_tags;
-  size_t num_proof_demand_tags;
-  if (msg->GetTaglist(kPDMD, &proof_demand_tags, &num_proof_demand_tags) ==
-      QUIC_NO_ERROR) {
-    for (size_t i = 0; i < num_proof_demand_tags; i++) {
-      if (proof_demand_tags[i] == kCHID) {
+  QuicTagVector proof_demand_tags;
+  if (msg->GetTaglist(kPDMD, &proof_demand_tags) == QUIC_NO_ERROR) {
+    for (QuicTag tag : proof_demand_tags) {
+      if (tag == kCHID) {
         config->channel_id_enabled = true;
         break;
       }
     }
   }
 
-  for (size_t i = 0; i < kexs_len; i++) {
+  for (size_t i = 0; i < kexs_tags.size(); i++) {
     const QuicTag tag = kexs_tags[i];
     string private_key;
 
@@ -1941,18 +1920,15 @@
 
 bool QuicCryptoServerConfig::ClientDemandsX509Proof(
     const CryptoHandshakeMessage& client_hello) const {
-  const QuicTag* their_proof_demands;
-  size_t num_their_proof_demands;
+  QuicTagVector their_proof_demands;
 
-  if (client_hello.GetTaglist(kPDMD, &their_proof_demands,
-                              &num_their_proof_demands) != QUIC_NO_ERROR) {
+  if (client_hello.GetTaglist(kPDMD, &their_proof_demands) != QUIC_NO_ERROR) {
     return false;
   }
 
-  for (size_t i = 0; i < num_their_proof_demands; i++) {
-    switch (their_proof_demands[i]) {
-      case kX509:
-        return true;
+  for (const QuicTag tag : their_proof_demands) {
+    if (tag == kX509) {
+      return true;
     }
   }
   return false;
diff --git a/net/quic/core/crypto/quic_crypto_server_config_test.cc b/net/quic/core/crypto/quic_crypto_server_config_test.cc
index 6c14076..381c82b 100644
--- a/net/quic/core/crypto/quic_crypto_server_config_test.cc
+++ b/net/quic/core/crypto/quic_crypto_server_config_test.cc
@@ -39,10 +39,8 @@
 
   // The default configuration should have AES-GCM and at least one ChaCha20
   // cipher.
-  const QuicTag* aead_tags;
-  size_t aead_len;
-  ASSERT_EQ(QUIC_NO_ERROR, message->GetTaglist(kAEAD, &aead_tags, &aead_len));
-  std::vector<QuicTag> aead(aead_tags, aead_tags + aead_len);
+  QuicTagVector aead;
+  ASSERT_EQ(QUIC_NO_ERROR, message->GetTaglist(kAEAD, &aead));
   EXPECT_THAT(aead, ::testing::Contains(kAESG));
   EXPECT_LE(1u, aead.size());
 }
diff --git a/net/quic/core/quic_config.cc b/net/quic/core/quic_config.cc
index 7453708..c6bab4f 100644
--- a/net/quic/core/quic_config.cc
+++ b/net/quic/core/quic_config.cc
@@ -232,10 +232,8 @@
     HelloType hello_type,
     string* error_details) {
   DCHECK(error_details != nullptr);
-  const QuicTag* received_tags;
-  size_t received_tags_length;
-  QuicErrorCode error =
-      peer_hello.GetTaglist(tag_, &received_tags, &received_tags_length);
+  QuicTagVector values;
+  QuicErrorCode error = peer_hello.GetTaglist(tag_, &values);
   switch (error) {
     case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
       if (presence_ == PRESENCE_OPTIONAL) {
@@ -246,9 +244,8 @@
     case QUIC_NO_ERROR:
       QUIC_DVLOG(1) << "Received Connection Option tags from receiver.";
       has_receive_values_ = true;
-      for (size_t i = 0; i < received_tags_length; ++i) {
-        receive_values_.push_back(received_tags[i]);
-      }
+      receive_values_.insert(receive_values_.end(), values.begin(),
+                             values.end());
       break;
     default:
       *error_details = "Bad " + QuicTagToString(tag_);
diff --git a/net/quic/core/quic_crypto_client_stream.cc b/net/quic/core/quic_crypto_client_stream.cc
index 837ebeb..7f1cd9ef 100644
--- a/net/quic/core/quic_crypto_client_stream.cc
+++ b/net/quic/core/quic_crypto_client_stream.cc
@@ -391,13 +391,11 @@
     return;
   }
 
-  const uint32_t* reject_reasons;
-  size_t num_reject_reasons;
+  QuicTagVector reject_reasons;
   static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync");
-  if (in->GetTaglist(kRREJ, &reject_reasons, &num_reject_reasons) ==
-      QUIC_NO_ERROR) {
+  if (in->GetTaglist(kRREJ, &reject_reasons) == QUIC_NO_ERROR) {
     uint32_t packed_error = 0;
-    for (size_t i = 0; i < num_reject_reasons; ++i) {
+    for (size_t i = 0; i < reject_reasons.size(); ++i) {
       // HANDSHAKE_OK is 0 and don't report that as error.
       if (reject_reasons[i] == HANDSHAKE_OK || reject_reasons[i] >= 32) {
         continue;
@@ -663,14 +661,12 @@
   if (!scfg) {  // scfg may be null then we send an inchoate CHLO.
     return false;
   }
-  const QuicTag* their_proof_demands;
-  size_t num_their_proof_demands;
-  if (scfg->GetTaglist(kPDMD, &their_proof_demands, &num_their_proof_demands) !=
-      QUIC_NO_ERROR) {
+  QuicTagVector their_proof_demands;
+  if (scfg->GetTaglist(kPDMD, &their_proof_demands) != QUIC_NO_ERROR) {
     return false;
   }
-  for (size_t i = 0; i < num_their_proof_demands; i++) {
-    if (their_proof_demands[i] == kCHID) {
+  for (const QuicTag tag : their_proof_demands) {
+    if (tag == kCHID) {
       return true;
     }
   }
diff --git a/net/quic/core/quic_crypto_server_stream.cc b/net/quic/core/quic_crypto_server_stream.cc
index 6912d2f..61fbaab 100644
--- a/net/quic/core/quic_crypto_server_stream.cc
+++ b/net/quic/core/quic_crypto_server_stream.cc
@@ -64,15 +64,13 @@
 // static
 bool QuicCryptoServerStreamBase::DoesPeerSupportStatelessRejects(
     const CryptoHandshakeMessage& message) {
-  const QuicTag* received_tags;
-  size_t received_tags_length;
-  QuicErrorCode error =
-      message.GetTaglist(kCOPT, &received_tags, &received_tags_length);
+  QuicTagVector received_tags;
+  QuicErrorCode error = message.GetTaglist(kCOPT, &received_tags);
   if (error != QUIC_NO_ERROR) {
     return false;
   }
-  for (size_t i = 0; i < received_tags_length; ++i) {
-    if (received_tags[i] == kSREJ) {
+  for (const QuicTag tag : received_tags) {
+    if (tag == kSREJ) {
       return true;
     }
   }
diff --git a/net/tools/quic/stateless_rejector_test.cc b/net/tools/quic/stateless_rejector_test.cc
index 190121cb..20fe8bc 100644
--- a/net/tools/quic/stateless_rejector_test.cc
+++ b/net/tools/quic/stateless_rejector_test.cc
@@ -239,11 +239,9 @@
   ASSERT_EQ(StatelessRejector::REJECTED, rejector_->state());
   const CryptoHandshakeMessage& reply = rejector_->reply();
   EXPECT_EQ(kSREJ, reply.tag());
-  const uint32_t* reject_reasons;
-  size_t num_reject_reasons;
-  EXPECT_EQ(QUIC_NO_ERROR,
-            reply.GetTaglist(kRREJ, &reject_reasons, &num_reject_reasons));
-  EXPECT_EQ(1u, num_reject_reasons);
+  QuicTagVector reject_reasons;
+  EXPECT_EQ(QUIC_NO_ERROR, reply.GetTaglist(kRREJ, &reject_reasons));
+  EXPECT_EQ(1u, reject_reasons.size());
   EXPECT_EQ(INVALID_EXPECTED_LEAF_CERTIFICATE,
             static_cast<HandshakeFailureReason>(reject_reasons[0]));
 }
diff --git a/third_party/expat/BUILD.gn b/third_party/expat/BUILD.gn
index a2c2d0c..1ae296d 100644
--- a/third_party/expat/BUILD.gn
+++ b/third_party/expat/BUILD.gn
@@ -33,6 +33,11 @@
 
     public_configs = [ ":expat_config" ]
 
+    # TODO(thakis): Remove this once clang no longer crashes when building
+    # libexpat with -Oz.
+    configs -= [ "//build/config/compiler:default_optimization" ]
+    configs += [ "//build/config/compiler:optimize_max" ]
+
     defines = [ "_LIB" ]
     if (is_win) {
       defines += [ "COMPILED_FROM_DSP" ]