First round of fixing up implicit 64->32 bit conversions
diff --git a/Makefile b/Makefile
index 5a3f1ea..21f3011 100644
--- a/Makefile
+++ b/Makefile
@@ -231,6 +231,10 @@
 CXX11_CHECK_CMD = $(CXX) -std=c++11 -o $(TMPOUT) -c test/build/c++11.cc
 HAS_CXX11 = $(shell $(CXX11_CHECK_CMD) 2> /dev/null && echo true || echo false)
 
+# Detect if -Wshorten-64-to-32 is a thing
+SHORTEN_64_TO_32_CHECK_CMD = $(CC) -Wshorten-64-to-32 test/build/empty.c
+HAS_SHORTEN_64_TO_32 = $(shell $(SHORTEN_64_TO_32_CHECK_CMD) 2> /dev/null && echo true || echo false)
+
 # The HOST compiler settings are used to compile the protoc plugins.
 # In most cases, you won't have to change anything, but if you are
 # cross-compiling, you can override these variables from GNU make's
@@ -246,6 +250,9 @@
 endif
 
 CFLAGS += -std=c89 -pedantic -Wsign-conversion
+ifeq ($(HAS_SHORTEN_64_TO_32),true)
+CFLAGS += -Wshorten-64-to-32
+endif
 ifeq ($(HAS_CXX11),true)
 CXXFLAGS += -std=c++11
 else
diff --git a/include/grpc/support/port_platform.h b/include/grpc/support/port_platform.h
index d098155..69709f8 100644
--- a/include/grpc/support/port_platform.h
+++ b/include/grpc/support/port_platform.h
@@ -318,6 +318,7 @@
 
 /* INT64_MAX is unavailable on some platforms. */
 #define GPR_INT64_MAX (gpr_int64)(~(gpr_uint64)0 >> 1)
+#define GPR_UINT32_MAX (~(gpr_uint32)0)
 
 /* maximum alignment needed for any type on this platform, rounded up to a
    power of two */
diff --git a/include/grpc/support/slice_buffer.h b/include/grpc/support/slice_buffer.h
index 04db003..321ba28 100644
--- a/include/grpc/support/slice_buffer.h
+++ b/include/grpc/support/slice_buffer.h
@@ -77,7 +77,7 @@
 void gpr_slice_buffer_addn(gpr_slice_buffer *sb, gpr_slice *slices, size_t n);
 /* add a very small (less than 8 bytes) amount of data to the end of a slice
    buffer: returns a pointer into which to add the data */
-gpr_uint8 *gpr_slice_buffer_tiny_add(gpr_slice_buffer *sb, unsigned len);
+gpr_uint8 *gpr_slice_buffer_tiny_add(gpr_slice_buffer *sb, size_t len);
 /* pop the last buffer, but don't unref it */
 void gpr_slice_buffer_pop(gpr_slice_buffer *sb);
 /* clear a slice buffer, unref all elements */
diff --git a/src/core/channel/channel_args.c b/src/core/channel/channel_args.c
index 31ce3a8..591135c 100644
--- a/src/core/channel/channel_args.c
+++ b/src/core/channel/channel_args.c
@@ -132,7 +132,7 @@
   for (i = 0; i < a->num_args; ++i) {
     if (a->args[i].type == GRPC_ARG_INTEGER &&
         !strcmp(GRPC_COMPRESSION_ALGORITHM_ARG, a->args[i].key)) {
-      return a->args[i].value.integer;
+      return (grpc_compression_algorithm)a->args[i].value.integer;
       break;
     }
   }
diff --git a/src/core/channel/compress_filter.c b/src/core/channel/compress_filter.c
index 0b85c7b..8e06094 100644
--- a/src/core/channel/compress_filter.c
+++ b/src/core/channel/compress_filter.c
@@ -142,8 +142,9 @@
     grpc_stream_op *sop = &send_ops->ops[i];
     switch (sop->type) {
       case GRPC_OP_BEGIN_MESSAGE:
+        GPR_ASSERT(calld->slices.length <= GPR_UINT32_MAX);
         grpc_sopb_add_begin_message(
-            &new_send_ops, calld->slices.length,
+            &new_send_ops, (gpr_uint32)calld->slices.length,
             sop->data.begin_message.flags | GRPC_WRITE_INTERNAL_COMPRESS);
         break;
       case GRPC_OP_SLICE:
diff --git a/src/core/compression/message_compress.c b/src/core/compression/message_compress.c
index 7856f40..01db713 100644
--- a/src/core/compression/message_compress.c
+++ b/src/core/compression/message_compress.c
@@ -49,19 +49,23 @@
   int flush;
   size_t i;
   gpr_slice outbuf = gpr_slice_malloc(OUTPUT_BLOCK_SIZE);
+  const uInt uint_max = ~(uInt)0;
 
-  zs->avail_out = GPR_SLICE_LENGTH(outbuf);
+  GPR_ASSERT(GPR_SLICE_LENGTH(outbuf) <= uint_max);
+  zs->avail_out = (uInt)GPR_SLICE_LENGTH(outbuf);
   zs->next_out = GPR_SLICE_START_PTR(outbuf);
   flush = Z_NO_FLUSH;
   for (i = 0; i < input->count; i++) {
     if (i == input->count - 1) flush = Z_FINISH;
-    zs->avail_in = GPR_SLICE_LENGTH(input->slices[i]);
+    GPR_ASSERT(GPR_SLICE_LENGTH(input->slices[i]) <= uint_max);
+    zs->avail_in = (uInt)GPR_SLICE_LENGTH(input->slices[i]);
     zs->next_in = GPR_SLICE_START_PTR(input->slices[i]);
     do {
       if (zs->avail_out == 0) {
         gpr_slice_buffer_add_indexed(output, outbuf);
         outbuf = gpr_slice_malloc(OUTPUT_BLOCK_SIZE);
-        zs->avail_out = GPR_SLICE_LENGTH(outbuf);
+        GPR_ASSERT(GPR_SLICE_LENGTH(outbuf) <= uint_max);
+        zs->avail_out = (uInt)GPR_SLICE_LENGTH(outbuf);
         zs->next_out = GPR_SLICE_START_PTR(outbuf);
       }
       r = flate(zs, flush);
diff --git a/src/core/iomgr/alarm.c b/src/core/iomgr/alarm.c
index e317934..515b96f 100644
--- a/src/core/iomgr/alarm.c
+++ b/src/core/iomgr/alarm.c
@@ -145,7 +145,7 @@
   alarm->prev->next = alarm->next;
 }
 
-static void swap_adjacent_shards_in_queue(size_t first_shard_queue_index) {
+static void swap_adjacent_shards_in_queue(gpr_uint32 first_shard_queue_index) {
   shard_type *temp;
   temp = g_shard_queue[first_shard_queue_index];
   g_shard_queue[first_shard_queue_index] =
@@ -355,7 +355,7 @@
     gpr_mu_lock(drop_mu);
   }
 
-  return n;
+  return (int)n;
 }
 
 int grpc_alarm_check(gpr_mu *drop_mu, gpr_timespec now, gpr_timespec *next) {
diff --git a/src/core/iomgr/alarm_heap.c b/src/core/iomgr/alarm_heap.c
index 7bafdff..769142e 100644
--- a/src/core/iomgr/alarm_heap.c
+++ b/src/core/iomgr/alarm_heap.c
@@ -45,7 +45,7 @@
    its argument. */
 static void adjust_upwards(grpc_alarm **first, gpr_uint32 i, grpc_alarm *t) {
   while (i > 0) {
-    gpr_uint32 parent = (i - 1u) / 2u;
+    gpr_uint32 parent = (gpr_uint32)(((int)i - 1) / 2);
     if (gpr_time_cmp(first[parent]->deadline, t->deadline) >= 0) break;
     first[i] = first[parent];
     first[i]->heap_index = i;
@@ -94,7 +94,7 @@
 
 static void note_changed_priority(grpc_alarm_heap *heap, grpc_alarm *alarm) {
   gpr_uint32 i = alarm->heap_index;
-  gpr_uint32 parent = (i - 1u) / 2u;
+  gpr_uint32 parent = (gpr_uint32)(((int)i - 1) / 2);
   if (gpr_time_cmp(heap->alarms[parent]->deadline, alarm->deadline) < 0) {
     adjust_upwards(heap->alarms, i, alarm);
   } else {
diff --git a/src/core/iomgr/tcp_client_posix.c b/src/core/iomgr/tcp_client_posix.c
index 7ca0a60..c3668f6 100644
--- a/src/core/iomgr/tcp_client_posix.c
+++ b/src/core/iomgr/tcp_client_posix.c
@@ -229,7 +229,8 @@
   }
 
   do {
-    err = connect(fd, addr, addr_len);
+    GPR_ASSERT(addr_len < ~(socklen_t)0);
+    err = connect(fd, addr, (socklen_t)addr_len);
   } while (err < 0 && errno == EINTR);
 
   addr_str = grpc_sockaddr_to_uri(addr);
diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c
index 6b81090..bcbd0af 100644
--- a/src/core/iomgr/tcp_server_posix.c
+++ b/src/core/iomgr/tcp_server_posix.c
@@ -83,7 +83,7 @@
     struct sockaddr sockaddr;
     struct sockaddr_un un;
   } addr;
-  int addr_len;
+  size_t addr_len;
   grpc_iomgr_closure read_closure;
   grpc_iomgr_closure destroyed_closure;
 } server_port;
@@ -236,7 +236,7 @@
     char *end;
     long i = strtol(buf, &end, 10);
     if (i > 0 && i <= INT_MAX && end && *end == 0) {
-      n = i;
+      n = (int)i;
     }
   }
   fclose(fp);
@@ -274,7 +274,8 @@
     goto error;
   }
 
-  if (bind(fd, addr, addr_len) < 0) {
+  GPR_ASSERT(addr_len < ~(socklen_t)0);
+  if (bind(fd, addr, (socklen_t)addr_len) < 0) {
     char *addr_str;
     grpc_sockaddr_to_string(&addr_str, addr, 0);
     gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, strerror(errno));
diff --git a/src/core/iomgr/udp_server.c b/src/core/iomgr/udp_server.c
index 95ae698..ed9eee8 100644
--- a/src/core/iomgr/udp_server.c
+++ b/src/core/iomgr/udp_server.c
@@ -78,7 +78,7 @@
     struct sockaddr sockaddr;
     struct sockaddr_un un;
   } addr;
-  int addr_len;
+  size_t addr_len;
   grpc_iomgr_closure read_closure;
   grpc_iomgr_closure destroyed_closure;
   grpc_udp_server_read_cb read_cb;
@@ -242,7 +242,8 @@
 #endif
   }
 
-  if (bind(fd, addr, addr_len) < 0) {
+  GPR_ASSERT(addr_len < ~(socklen_t)0);
+  if (bind(fd, addr, (socklen_t)addr_len) < 0) {
     char *addr_str;
     grpc_sockaddr_to_string(&addr_str, addr, 0);
     gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, strerror(errno));
@@ -431,7 +432,7 @@
 /* TODO(rjshade): Add a test for this method. */
 void grpc_udp_server_write(server_port *sp, const char *buffer, size_t buf_len,
                            const struct sockaddr *peer_address) {
-  int rc;
+  ssize_t rc;
   rc = sendto(sp->fd, buffer, buf_len, 0, peer_address, sizeof(peer_address));
   if (rc < 0) {
     gpr_log(GPR_ERROR, "Unable to send data: %s", strerror(errno));
diff --git a/src/core/iomgr/wakeup_fd_pipe.c b/src/core/iomgr/wakeup_fd_pipe.c
index bd643e8..902034e 100644
--- a/src/core/iomgr/wakeup_fd_pipe.c
+++ b/src/core/iomgr/wakeup_fd_pipe.c
@@ -56,7 +56,7 @@
 
 static void pipe_consume(grpc_wakeup_fd *fd_info) {
   char buf[128];
-  int r;
+  ssize_t r;
 
   for (;;) {
     r = read(fd_info->read_fd, buf, sizeof(buf));
diff --git a/src/core/security/jwt_verifier.c b/src/core/security/jwt_verifier.c
index 03f8c37..790f217 100644
--- a/src/core/security/jwt_verifier.c
+++ b/src/core/security/jwt_verifier.c
@@ -33,6 +33,7 @@
 
 #include "src/core/security/jwt_verifier.h"
 
+#include <limits.h>
 #include <string.h>
 
 #include "src/core/httpcli/httpcli.h"
@@ -412,7 +413,9 @@
   X509 *x509 = NULL;
   EVP_PKEY *result = NULL;
   BIO *bio = BIO_new(BIO_s_mem());
-  BIO_write(bio, x509_str, strlen(x509_str));
+  size_t len = strlen(x509_str);
+  GPR_ASSERT(len < INT_MAX);
+  BIO_write(bio, x509_str, (int)len);
   x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
   if (x509 == NULL) {
     gpr_log(GPR_ERROR, "Unable to parse x509 cert.");
@@ -439,7 +442,8 @@
     gpr_log(GPR_ERROR, "Invalid base64 for big num.");
     return NULL;
   }
-  result = BN_bin2bn(GPR_SLICE_START_PTR(bin), GPR_SLICE_LENGTH(bin), NULL);
+  result =
+      BN_bin2bn(GPR_SLICE_START_PTR(bin), (int)GPR_SLICE_LENGTH(bin), NULL);
   gpr_slice_unref(bin);
   return result;
 }
diff --git a/src/core/support/slice_buffer.c b/src/core/support/slice_buffer.c
index 6482ef9..8873d45 100644
--- a/src/core/support/slice_buffer.c
+++ b/src/core/support/slice_buffer.c
@@ -69,7 +69,7 @@
   }
 }
 
-gpr_uint8 *gpr_slice_buffer_tiny_add(gpr_slice_buffer *sb, unsigned n) {
+gpr_uint8 *gpr_slice_buffer_tiny_add(gpr_slice_buffer *sb, size_t n) {
   gpr_slice *back;
   gpr_uint8 *out;
 
diff --git a/src/core/support/stack_lockfree.c b/src/core/support/stack_lockfree.c
index 0d4b4be..180ba19 100644
--- a/src/core/support/stack_lockfree.c
+++ b/src/core/support/stack_lockfree.c
@@ -123,13 +123,13 @@
 #ifndef NDEBUG
   /* Check for double push */
   {
-    int pushed_index = entry / (8 * sizeof(gpr_atm));
-    int pushed_bit = entry % (8 * sizeof(gpr_atm));
+    int pushed_index = entry / (int)(8 * sizeof(gpr_atm));
+    int pushed_bit = entry % (int)(8 * sizeof(gpr_atm));
     gpr_atm old_val;
 
     old_val = gpr_atm_no_barrier_fetch_add(&stack->pushed[pushed_index],
                                            (gpr_atm)(1UL << pushed_bit));
-    GPR_ASSERT((old_val & (1UL << pushed_bit)) == 0);
+    GPR_ASSERT((old_val & (gpr_atm)(1UL << pushed_bit)) == 0);
   }
 #endif
 
@@ -167,7 +167,7 @@
 
     old_val = gpr_atm_no_barrier_fetch_add(&stack->pushed[pushed_index],
                                            -(gpr_atm)(1UL << pushed_bit));
-    GPR_ASSERT((old_val & (1UL << pushed_bit)) != 0);
+    GPR_ASSERT((old_val & (gpr_atm)(1UL << pushed_bit)) != 0);
   }
 #endif
 
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index 6ece563..c96df77 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -508,7 +508,7 @@
   if (call->status[source].is_set) return;
 
   call->status[source].is_set = 1;
-  call->status[source].code = status;
+  call->status[source].code = (grpc_status_code)status;
   call->error_status_set = status != GRPC_STATUS_OK;
 
   if (status != GRPC_STATUS_OK && !grpc_bbq_empty(&call->incoming_queue)) {
@@ -604,7 +604,7 @@
   int completing_requests = 0;
   int start_op = 0;
   int i;
-  const gpr_uint32 MAX_RECV_PEEK_AHEAD = 65536;
+  const size_t MAX_RECV_PEEK_AHEAD = 65536;
   size_t buffered_bytes;
   int cancel_alarm = 0;
 
@@ -1107,10 +1107,12 @@
     /* fall through intended */
     case WRITE_STATE_STARTED:
       if (is_op_live(call, GRPC_IOREQ_SEND_MESSAGE)) {
+        size_t length;
         data = call->request_data[GRPC_IOREQ_SEND_MESSAGE];
         flags = call->request_flags[GRPC_IOREQ_SEND_MESSAGE];
-        grpc_sopb_add_begin_message(
-            &call->send_ops, grpc_byte_buffer_length(data.send_message), flags);
+        length = grpc_byte_buffer_length(data.send_message);
+        GPR_ASSERT(length <= GPR_UINT32_MAX);
+        grpc_sopb_add_begin_message(&call->send_ops, (gpr_uint32)length, flags);
         copy_byte_buffer_to_stream_ops(data.send_message, &call->send_ops);
         op->send_ops = &call->send_ops;
         call->last_send_contains |= 1 << GRPC_IOREQ_SEND_MESSAGE;
@@ -1243,7 +1245,7 @@
     }
     if (op == GRPC_IOREQ_SEND_STATUS) {
       set_status_code(call, STATUS_FROM_SERVER_STATUS,
-                      reqs[i].data.send_status.code);
+                      (gpr_uint32)reqs[i].data.send_status.code);
       if (reqs[i].data.send_status.details) {
         set_status_details(call, STATUS_FROM_SERVER_STATUS,
                            GRPC_MDSTR_REF(reqs[i].data.send_status.details));
@@ -1333,7 +1335,7 @@
 
   GPR_ASSERT(status != GRPC_STATUS_OK);
 
-  set_status_code(c, STATUS_FROM_API_OVERRIDE, status);
+  set_status_code(c, STATUS_FROM_API_OVERRIDE, (gpr_uint32)status);
   set_status_details(c, STATUS_FROM_API_OVERRIDE, details);
 
   c->cancel_with_status = status;
diff --git a/src/core/surface/server.c b/src/core/surface/server.c
index c3d8046..3d404f7 100644
--- a/src/core/surface/server.c
+++ b/src/core/surface/server.c
@@ -33,6 +33,7 @@
 
 #include "src/core/surface/server.h"
 
+#include <limits.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -804,7 +805,7 @@
   server->request_freelist =
       gpr_stack_lockfree_create(server->max_requested_calls);
   for (i = 0; i < (size_t)server->max_requested_calls; i++) {
-    gpr_stack_lockfree_push(server->request_freelist, i);
+    gpr_stack_lockfree_push(server->request_freelist, (int)i);
   }
   request_matcher_init(&server->unregistered_request_matcher,
                        server->max_requested_calls);
@@ -896,7 +897,7 @@
   grpc_mdstr *host;
   grpc_mdstr *method;
   gpr_uint32 hash;
-  gpr_uint32 slots;
+  size_t slots;
   gpr_uint32 probes;
   gpr_uint32 max_probes = 0;
   grpc_transport_op op;
@@ -949,7 +950,8 @@
       crm->host = host;
       crm->method = method;
     }
-    chand->registered_method_slots = slots;
+    GPR_ASSERT(slots <= GPR_UINT32_MAX);
+    chand->registered_method_slots = (gpr_uint32)slots;
     chand->registered_method_max_probes = max_probes;
   }
 
@@ -970,7 +972,7 @@
   op.set_accept_stream_user_data = chand;
   op.on_connectivity_state_change = &chand->channel_connectivity_changed;
   op.connectivity_state = &chand->connectivity_state;
-  op.disconnect = gpr_atm_acq_load(&s->shutdown_flag);
+  op.disconnect = gpr_atm_acq_load(&s->shutdown_flag) != 0;
   grpc_transport_perform_op(transport, &op);
 }
 
@@ -1256,8 +1258,9 @@
 
   if (rc >= server->requested_calls &&
       rc < server->requested_calls + server->max_requested_calls) {
+    GPR_ASSERT(rc - server->requested_calls <= INT_MAX);
     gpr_stack_lockfree_push(server->request_freelist,
-                            rc - server->requested_calls);
+                            (int)(rc - server->requested_calls));
   } else {
     gpr_free(req);
   }
diff --git a/src/core/transport/chttp2/frame_goaway.c b/src/core/transport/chttp2/frame_goaway.c
index d40e6fd..1a6d80d 100644
--- a/src/core/transport/chttp2/frame_goaway.c
+++ b/src/core/transport/chttp2/frame_goaway.c
@@ -143,7 +143,7 @@
         transport_parsing->goaway_received = 1;
         transport_parsing->goaway_last_stream_index = p->last_stream_id;
         gpr_slice_unref(transport_parsing->goaway_text);
-        transport_parsing->goaway_error = p->error_code;
+        transport_parsing->goaway_error = (grpc_status_code)p->error_code;
         transport_parsing->goaway_text =
             gpr_slice_new(p->debug_data, p->debug_length, gpr_free);
         p->debug_data = NULL;
@@ -160,7 +160,9 @@
                                gpr_slice_buffer *slice_buffer) {
   gpr_slice header = gpr_slice_malloc(9 + 4 + 4);
   gpr_uint8 *p = GPR_SLICE_START_PTR(header);
-  gpr_uint32 frame_length = 4 + 4 + GPR_SLICE_LENGTH(debug_data);
+  gpr_uint32 frame_length;
+  GPR_ASSERT(GPR_SLICE_LENGTH(debug_data) < GPR_UINT32_MAX - 4 - 4);
+  frame_length = 4 + 4 + (gpr_uint32)GPR_SLICE_LENGTH(debug_data);
 
   /* frame header: length */
   *p++ = frame_length >> 16;
diff --git a/src/core/transport/chttp2/frame_settings.c b/src/core/transport/chttp2/frame_settings.c
index 927ae55..f70776b 100644
--- a/src/core/transport/chttp2/frame_settings.c
+++ b/src/core/transport/chttp2/frame_settings.c
@@ -76,7 +76,7 @@
 gpr_slice grpc_chttp2_settings_create(gpr_uint32 *old, const gpr_uint32 *new,
                                       gpr_uint32 force_mask, size_t count) {
   size_t i;
-  size_t n = 0;
+  gpr_uint32 n = 0;
   gpr_slice output;
   gpr_uint8 *p;
 
diff --git a/src/core/transport/chttp2/hpack_parser.c b/src/core/transport/chttp2/hpack_parser.c
index f806f59..93a452f 100644
--- a/src/core/transport/chttp2/hpack_parser.c
+++ b/src/core/transport/chttp2/hpack_parser.c
@@ -1085,7 +1085,8 @@
 static void append_bytes(grpc_chttp2_hpack_parser_string *str,
                          const gpr_uint8 *data, size_t length) {
   if (length + str->length > str->capacity) {
-    str->capacity = str->length + length;
+    GPR_ASSERT(str->length + length <= GPR_UINT32_MAX);
+    str->capacity = (gpr_uint32)(str->length + length);
     str->str = gpr_realloc(str->str, str->capacity);
   }
   memcpy(str->str + str->length, data, length);
diff --git a/src/core/transport/chttp2/parsing.c b/src/core/transport/chttp2/parsing.c
index b0f884e..a29987a 100644
--- a/src/core/transport/chttp2/parsing.c
+++ b/src/core/transport/chttp2/parsing.c
@@ -131,7 +131,7 @@
      published later */
   if (transport_parsing->goaway_received) {
     grpc_chttp2_add_incoming_goaway(transport_global,
-                                    transport_parsing->goaway_error,
+                                    (gpr_uint32)transport_parsing->goaway_error,
                                     transport_parsing->goaway_text);
     transport_parsing->goaway_text = gpr_empty_slice();
     transport_parsing->goaway_received = 0;
@@ -212,7 +212,7 @@
     if (stream_parsing->saw_rst_stream) {
       stream_global->cancelled = 1;
       stream_global->cancelled_status = grpc_chttp2_http2_error_to_grpc_status(
-          stream_parsing->rst_stream_reason);
+          (grpc_chttp2_error_code)stream_parsing->rst_stream_reason);
       if (stream_parsing->rst_stream_reason == GRPC_CHTTP2_NO_ERROR) {
         stream_global->published_cancelled = 1;
       }
diff --git a/src/core/transport/chttp2/stream_encoder.c b/src/core/transport/chttp2/stream_encoder.c
index bcae93d..8c30af6 100644
--- a/src/core/transport/chttp2/stream_encoder.c
+++ b/src/core/transport/chttp2/stream_encoder.c
@@ -74,8 +74,9 @@
 } framer_state;
 
 /* fills p (which is expected to be 9 bytes long) with a data frame header */
-static void fill_header(gpr_uint8 *p, gpr_uint8 type, gpr_uint32 id,
-                        gpr_uint32 len, gpr_uint8 flags) {
+static void fill_header(gpr_uint8 *p, gpr_uint8 type, gpr_uint32 id, size_t len,
+                        gpr_uint8 flags) {
+  GPR_ASSERT(len < 16777316);
   *p++ = len >> 16;
   *p++ = len >> 8;
   *p++ = len;
@@ -185,8 +186,8 @@
   gpr_uint32 key_hash = elem->key->hash;
   gpr_uint32 elem_hash = GRPC_MDSTR_KV_HASH(key_hash, elem->value->hash);
   gpr_uint32 new_index = c->tail_remote_index + c->table_elems + 1;
-  gpr_uint32 elem_size = 32 + GPR_SLICE_LENGTH(elem->key->slice) +
-                         GPR_SLICE_LENGTH(elem->value->slice);
+  size_t elem_size = 32 + GPR_SLICE_LENGTH(elem->key->slice) +
+                     GPR_SLICE_LENGTH(elem->value->slice);
   grpc_mdelem *elem_to_unref;
 
   /* Reserve space for this element in the remote table: if this overflows
@@ -270,7 +271,7 @@
 
 static void emit_indexed(grpc_chttp2_hpack_compressor *c, gpr_uint32 index,
                          framer_state *st) {
-  size_t len = GRPC_CHTTP2_VARINT_LENGTH(index, 1);
+  gpr_uint32 len = GRPC_CHTTP2_VARINT_LENGTH(index, 1);
   GRPC_CHTTP2_WRITE_VARINT(index, 1, 0x80, add_tiny_header_data(st, len), len);
 }
 
@@ -291,11 +292,13 @@
   gpr_uint32 len_pfx = GRPC_CHTTP2_VARINT_LENGTH(key_index, 2);
   gpr_uint8 huffman_prefix;
   gpr_slice value_slice = get_wire_value(elem, &huffman_prefix);
-  gpr_uint32 len_val = GPR_SLICE_LENGTH(value_slice);
-  gpr_uint32 len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1);
+  size_t len_val = GPR_SLICE_LENGTH(value_slice);
+  gpr_uint32 len_val_len;
+  GPR_ASSERT(len_val <= GPR_UINT32_MAX);
+  len_val_len = GRPC_CHTTP2_VARINT_LENGTH((gpr_uint32)len_val, 1);
   GRPC_CHTTP2_WRITE_VARINT(key_index, 2, 0x40,
                            add_tiny_header_data(st, len_pfx), len_pfx);
-  GRPC_CHTTP2_WRITE_VARINT(len_val, 1, 0x00,
+  GRPC_CHTTP2_WRITE_VARINT((gpr_uint32)len_val, 1, 0x00,
                            add_tiny_header_data(st, len_val_len), len_val_len);
   add_header_data(st, gpr_slice_ref(value_slice));
 }
@@ -306,23 +309,27 @@
   gpr_uint32 len_pfx = GRPC_CHTTP2_VARINT_LENGTH(key_index, 4);
   gpr_uint8 huffman_prefix;
   gpr_slice value_slice = get_wire_value(elem, &huffman_prefix);
-  gpr_uint32 len_val = GPR_SLICE_LENGTH(value_slice);
-  gpr_uint32 len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1);
+  size_t len_val = GPR_SLICE_LENGTH(value_slice);
+  gpr_uint32 len_val_len;
+  GPR_ASSERT(len_val <= GPR_UINT32_MAX);
+  len_val_len = GRPC_CHTTP2_VARINT_LENGTH((gpr_uint32)len_val, 1);
   GRPC_CHTTP2_WRITE_VARINT(key_index, 4, 0x00,
                            add_tiny_header_data(st, len_pfx), len_pfx);
-  GRPC_CHTTP2_WRITE_VARINT(len_val, 1, 0x00,
+  GRPC_CHTTP2_WRITE_VARINT((gpr_uint32)len_val, 1, 0x00,
                            add_tiny_header_data(st, len_val_len), len_val_len);
   add_header_data(st, gpr_slice_ref(value_slice));
 }
 
 static void emit_lithdr_incidx_v(grpc_chttp2_hpack_compressor *c,
                                  grpc_mdelem *elem, framer_state *st) {
-  gpr_uint32 len_key = GPR_SLICE_LENGTH(elem->key->slice);
+  gpr_uint32 len_key = (gpr_uint32)GPR_SLICE_LENGTH(elem->key->slice);
   gpr_uint8 huffman_prefix;
   gpr_slice value_slice = get_wire_value(elem, &huffman_prefix);
-  gpr_uint32 len_val = GPR_SLICE_LENGTH(value_slice);
+  gpr_uint32 len_val = (gpr_uint32)GPR_SLICE_LENGTH(value_slice);
   gpr_uint32 len_key_len = GRPC_CHTTP2_VARINT_LENGTH(len_key, 1);
   gpr_uint32 len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1);
+  GPR_ASSERT(len_key <= GPR_UINT32_MAX);
+  GPR_ASSERT(GPR_SLICE_LENGTH(value_slice) <= GPR_UINT32_MAX);
   *add_tiny_header_data(st, 1) = 0x40;
   GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00,
                            add_tiny_header_data(st, len_key_len), len_key_len);
@@ -334,12 +341,14 @@
 
 static void emit_lithdr_noidx_v(grpc_chttp2_hpack_compressor *c,
                                 grpc_mdelem *elem, framer_state *st) {
-  gpr_uint32 len_key = GPR_SLICE_LENGTH(elem->key->slice);
+  gpr_uint32 len_key = (gpr_uint32)GPR_SLICE_LENGTH(elem->key->slice);
   gpr_uint8 huffman_prefix;
   gpr_slice value_slice = get_wire_value(elem, &huffman_prefix);
-  gpr_uint32 len_val = GPR_SLICE_LENGTH(value_slice);
+  gpr_uint32 len_val = (gpr_uint32)GPR_SLICE_LENGTH(value_slice);
   gpr_uint32 len_key_len = GRPC_CHTTP2_VARINT_LENGTH(len_key, 1);
   gpr_uint32 len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1);
+  GPR_ASSERT(len_key <= GPR_UINT32_MAX);
+  GPR_ASSERT(GPR_SLICE_LENGTH(value_slice) <= GPR_UINT32_MAX);
   *add_tiny_header_data(st, 1) = 0x00;
   GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00,
                            add_tiny_header_data(st, len_key_len), len_key_len);
@@ -565,7 +574,7 @@
   framer_state st;
   gpr_slice slice;
   grpc_stream_op *op;
-  gpr_uint32 max_take_size;
+  size_t max_take_size;
   gpr_uint32 curop = 0;
   gpr_uint32 unref_op;
   grpc_mdctx *mdctx = compressor->mdctx;
diff --git a/src/core/transport/chttp2/timeout_encoding.c b/src/core/transport/chttp2/timeout_encoding.c
index 40fcdc2..8a9b290 100644
--- a/src/core/transport/chttp2/timeout_encoding.c
+++ b/src/core/transport/chttp2/timeout_encoding.c
@@ -123,7 +123,7 @@
     enc_nanos(buffer, timeout.tv_nsec);
   } else if (timeout.tv_sec < 1000 && timeout.tv_nsec != 0) {
     enc_micros(buffer,
-               timeout.tv_sec * 1000000 +
+               (int)(timeout.tv_sec * 1000000) +
                    (timeout.tv_nsec / 1000 + (timeout.tv_nsec % 1000 != 0)));
   } else {
     enc_seconds(buffer, timeout.tv_sec + (timeout.tv_nsec != 0));
diff --git a/src/core/transport/chttp2/writing.c b/src/core/transport/chttp2/writing.c
index ac79044..c015e82 100644
--- a/src/core/transport/chttp2/writing.c
+++ b/src/core/transport/chttp2/writing.c
@@ -32,10 +32,13 @@
  */
 
 #include "src/core/transport/chttp2/internal.h"
-#include "src/core/transport/chttp2/http2_errors.h"
+
+#include <limits.h>
 
 #include <grpc/support/log.h>
 
+#include "src/core/transport/chttp2/http2_errors.h"
+
 static void finalize_outbuf(grpc_chttp2_transport_writing *transport_writing);
 
 int grpc_chttp2_unlocking_check_writes(
@@ -78,12 +81,13 @@
     stream_writing->send_closed = GRPC_DONT_SEND_CLOSED;
 
     if (stream_global->outgoing_sopb) {
-      window_delta =
-          grpc_chttp2_preencode(stream_global->outgoing_sopb->ops,
-                                &stream_global->outgoing_sopb->nops,
-                                GPR_MIN(transport_global->outgoing_window,
-                                        stream_global->outgoing_window),
-                                &stream_writing->sopb);
+      window_delta = grpc_chttp2_preencode(
+          stream_global->outgoing_sopb->ops,
+          &stream_global->outgoing_sopb->nops,
+          (gpr_uint32)GPR_MIN(GPR_MIN(transport_global->outgoing_window,
+                                      stream_global->outgoing_window),
+                              GPR_UINT32_MAX),
+          &stream_writing->sopb);
       GRPC_CHTTP2_FLOWCTL_TRACE_TRANSPORT(
           "write", transport_global, outgoing_window, -(gpr_int64)window_delta);
       GRPC_CHTTP2_FLOWCTL_TRACE_STREAM("write", transport_global, stream_global,
diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c
index c1a3c04..c803305 100644
--- a/src/core/transport/chttp2_transport.c
+++ b/src/core/transport/chttp2_transport.c
@@ -692,7 +692,8 @@
           op->max_recv_bytes - stream_global->max_recv_bytes);
       stream_global->unannounced_incoming_window +=
           op->max_recv_bytes - stream_global->max_recv_bytes;
-      stream_global->max_recv_bytes = op->max_recv_bytes;
+      stream_global->max_recv_bytes =
+          (gpr_uint32)(GPR_MIN(op->max_recv_bytes, GPR_UINT32_MAX));
     }
     grpc_chttp2_incoming_metadata_live_op_buffer_end(
         &stream_global->outstanding_metadata);
@@ -761,7 +762,7 @@
     t->global.sent_goaway = 1;
     grpc_chttp2_goaway_append(
         t->global.last_incoming_stream_id,
-        grpc_chttp2_grpc_status_to_http2_error(op->goaway_status),
+        (gpr_uint32)grpc_chttp2_grpc_status_to_http2_error(op->goaway_status),
         gpr_slice_ref(*op->goaway_message), &t->global.qbuf);
     close_transport = !grpc_chttp2_has_streams(t);
   }
@@ -829,8 +830,9 @@
 
   new_stream_count = grpc_chttp2_stream_map_size(&t->parsing_stream_map) +
                      grpc_chttp2_stream_map_size(&t->new_stream_map);
+  GPR_ASSERT(new_stream_count <= GPR_UINT32_MAX);
   if (new_stream_count != t->global.concurrent_stream_count) {
-    t->global.concurrent_stream_count = new_stream_count;
+    t->global.concurrent_stream_count = (gpr_uint32)new_stream_count;
     maybe_start_some_streams(&t->global);
   }
 }
@@ -943,7 +945,8 @@
     gpr_slice_buffer_add(
         &transport_global->qbuf,
         grpc_chttp2_rst_stream_create(
-            stream_global->id, grpc_chttp2_grpc_status_to_http2_error(status)));
+            stream_global->id,
+            (gpr_uint32)grpc_chttp2_grpc_status_to_http2_error(status)));
   }
   grpc_chttp2_list_add_read_write_state_changed(transport_global,
                                                 stream_global);
@@ -989,11 +992,11 @@
   *p++ = 's';
   if (status < 10) {
     *p++ = 1;
-    *p++ = '0' + status;
+    *p++ = (gpr_uint8)('0' + status);
   } else {
     *p++ = 2;
-    *p++ = '0' + (status / 10);
-    *p++ = '0' + (status % 10);
+    *p++ = (gpr_uint8)('0' + (status / 10));
+    *p++ = (gpr_uint8)('0' + (status % 10));
   }
   GPR_ASSERT(p == GPR_SLICE_END_PTR(status_hdr));
   len += GPR_SLICE_LENGTH(status_hdr);
@@ -1121,7 +1124,7 @@
     grpc_chttp2_stream_map_move_into(&t->new_stream_map,
                                      &t->parsing_stream_map);
     t->global.concurrent_stream_count =
-        grpc_chttp2_stream_map_size(&t->parsing_stream_map);
+        (gpr_uint32)grpc_chttp2_stream_map_size(&t->parsing_stream_map);
     if (t->parsing.initial_window_update != 0) {
       grpc_chttp2_stream_map_for_each(&t->parsing_stream_map,
                                       update_global_window, t);
diff --git a/src/core/transport/transport.h b/src/core/transport/transport.h
index 92c1f38..6e1ec2f 100644
--- a/src/core/transport/transport.h
+++ b/src/core/transport/transport.h
@@ -75,7 +75,7 @@
   /** The number of bytes this peer is currently prepared to receive.
       These bytes will be eventually used to replenish per-stream flow control
       windows. */
-  gpr_uint32 max_recv_bytes;
+  size_t max_recv_bytes;
   grpc_iomgr_closure *on_done_recv;
 
   grpc_pollset *bind_pollset;
diff --git a/src/core/tsi/fake_transport_security.c b/src/core/tsi/fake_transport_security.c
index a813c30..b1a9751 100644
--- a/src/core/tsi/fake_transport_security.c
+++ b/src/core/tsi/fake_transport_security.c
@@ -100,7 +100,7 @@
 
 static tsi_result tsi_fake_handshake_message_from_string(
     const char* msg_string, tsi_fake_handshake_message* msg) {
-  int i;
+  tsi_fake_handshake_message i;
   for (i = 0; i < TSI_FAKE_HANDSHAKE_MESSAGE_MAX; i++) {
     if (strncmp(msg_string, tsi_fake_handshake_message_strings[i],
                 strlen(tsi_fake_handshake_message_strings[i])) == 0) {
@@ -219,7 +219,7 @@
   frame->offset = 0;
   frame->size = bytes_size + TSI_FAKE_FRAME_HEADER_SIZE;
   if (!tsi_fake_frame_ensure_size(frame)) return TSI_OUT_OF_RESOURCES;
-  store32_little_endian(frame->size, frame->data);
+  store32_little_endian((gpr_uint32)frame->size, frame->data);
   memcpy(frame->data + TSI_FAKE_FRAME_HEADER_SIZE, bytes, bytes_size);
   tsi_fake_frame_reset(frame, 1 /* needs draining */);
   return TSI_OK;
@@ -266,7 +266,7 @@
   if (frame->size == 0) {
     /* New frame, create a header. */
     size_t written_in_frame_size = 0;
-    store32_little_endian(impl->max_frame_size, frame_header);
+    store32_little_endian((gpr_uint32)impl->max_frame_size, frame_header);
     written_in_frame_size = TSI_FAKE_FRAME_HEADER_SIZE;
     result = fill_frame_from_bytes(frame_header, &written_in_frame_size, frame);
     if (result != TSI_INCOMPLETE_DATA) {
@@ -303,7 +303,8 @@
     frame->size = frame->offset;
     frame->offset = 0;
     frame->needs_draining = 1;
-    store32_little_endian(frame->size, frame->data); /* Overwrite header. */
+    store32_little_endian((gpr_uint32)frame->size,
+                          frame->data); /* Overwrite header. */
   }
   result = drain_frame_to_bytes(protected_output_frames,
                                 protected_output_frames_size, frame);
diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c
index 6add492..99ce7ec 100644
--- a/src/core/tsi/ssl_transport_security.c
+++ b/src/core/tsi/ssl_transport_security.c
@@ -291,7 +291,7 @@
 
   for (i = 0; i < subject_alt_name_count; i++) {
     GENERAL_NAME* subject_alt_name =
-        sk_GENERAL_NAME_value(subject_alt_names, i);
+        sk_GENERAL_NAME_value(subject_alt_names, (int)i);
     /* Filter out the non-dns entries names. */
     if (subject_alt_name->type == GEN_DNS) {
       unsigned char* dns_name = NULL;
@@ -366,7 +366,10 @@
 /* Performs an SSL_read and handle errors. */
 static tsi_result do_ssl_read(SSL* ssl, unsigned char* unprotected_bytes,
                               size_t* unprotected_bytes_size) {
-  int read_from_ssl = SSL_read(ssl, unprotected_bytes, *unprotected_bytes_size);
+  int read_from_ssl;
+  GPR_ASSERT(*unprotected_bytes_size <= INT_MAX);
+  read_from_ssl =
+      SSL_read(ssl, unprotected_bytes, (int)*unprotected_bytes_size);
   if (read_from_ssl == 0) {
     gpr_log(GPR_ERROR, "SSL_read returned 0 unexpectedly.");
     return TSI_INTERNAL_ERROR;
@@ -400,8 +403,10 @@
 /* Performs an SSL_write and handle errors. */
 static tsi_result do_ssl_write(SSL* ssl, unsigned char* unprotected_bytes,
                                size_t unprotected_bytes_size) {
-  int ssl_write_result =
-      SSL_write(ssl, unprotected_bytes, unprotected_bytes_size);
+  int ssl_write_result;
+  GPR_ASSERT(unprotected_bytes_size <= INT_MAX);
+  ssl_write_result =
+      SSL_write(ssl, unprotected_bytes, (int)unprotected_bytes_size);
   if (ssl_write_result < 0) {
     ssl_write_result = SSL_get_error(ssl, ssl_write_result);
     if (ssl_write_result == SSL_ERROR_WANT_READ) {
@@ -423,7 +428,9 @@
     size_t pem_cert_chain_size) {
   tsi_result result = TSI_OK;
   X509* certificate = NULL;
-  BIO* pem = BIO_new_mem_buf((void*)pem_cert_chain, pem_cert_chain_size);
+  BIO* pem;
+  GPR_ASSERT(pem_cert_chain_size <= INT_MAX);
+  pem = BIO_new_mem_buf((void*)pem_cert_chain, (int)pem_cert_chain_size);
   if (pem == NULL) return TSI_OUT_OF_RESOURCES;
 
   do {
@@ -464,7 +471,9 @@
                                           size_t pem_key_size) {
   tsi_result result = TSI_OK;
   EVP_PKEY* private_key = NULL;
-  BIO* pem = BIO_new_mem_buf((void*)pem_key, pem_key_size);
+  BIO* pem;
+  GPR_ASSERT(pem_key_size <= INT_MAX);
+  pem = BIO_new_mem_buf((void*)pem_key, (int)pem_key_size);
   if (pem == NULL) return TSI_OUT_OF_RESOURCES;
   do {
     private_key = PEM_read_bio_PrivateKey(pem, NULL, NULL, "");
@@ -491,8 +500,11 @@
   size_t num_roots = 0;
   X509* root = NULL;
   X509_NAME* root_name = NULL;
-  BIO* pem = BIO_new_mem_buf((void*)pem_roots, pem_roots_size);
-  X509_STORE* root_store = SSL_CTX_get_cert_store(context);
+  BIO* pem;
+  X509_STORE* root_store;
+  GPR_ASSERT(pem_roots_size <= INT_MAX);
+  pem = BIO_new_mem_buf((void*)pem_roots, (int)pem_roots_size);
+  root_store = SSL_CTX_get_cert_store(context);
   if (root_store == NULL) return TSI_INVALID_ARGUMENT;
   if (pem == NULL) return TSI_OUT_OF_RESOURCES;
   if (root_names != NULL) {
@@ -592,7 +604,9 @@
     const unsigned char* pem_cert, size_t pem_cert_size, tsi_peer* peer) {
   tsi_result result = TSI_OK;
   X509* cert = NULL;
-  BIO* pem = BIO_new_mem_buf((void*)pem_cert, pem_cert_size);
+  BIO* pem;
+  GPR_ASSERT(pem_cert_size <= INT_MAX);
+  pem = BIO_new_mem_buf((void*)pem_cert, (int)pem_cert_size);
   if (pem == NULL) return TSI_OUT_OF_RESOURCES;
 
   cert = PEM_read_bio_X509(pem, NULL, NULL, "");
@@ -657,8 +671,9 @@
   int pending_in_ssl = BIO_pending(impl->from_ssl);
   if (pending_in_ssl > 0) {
     *unprotected_bytes_size = 0;
+    GPR_ASSERT(*protected_output_frames_size <= INT_MAX);
     read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames,
-                             *protected_output_frames_size);
+                             (int)*protected_output_frames_size);
     if (read_from_ssl < 0) {
       gpr_log(GPR_ERROR,
               "Could not read from BIO even though some data is pending");
@@ -684,8 +699,9 @@
   result = do_ssl_write(impl->ssl, impl->buffer, impl->buffer_size);
   if (result != TSI_OK) return result;
 
+  GPR_ASSERT(*protected_output_frames_size <= INT_MAX);
   read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames,
-                           *protected_output_frames_size);
+                           (int)*protected_output_frames_size);
   if (read_from_ssl < 0) {
     gpr_log(GPR_ERROR, "Could not read from BIO after SSL_write.");
     return TSI_INTERNAL_ERROR;
@@ -715,8 +731,9 @@
   *still_pending_size = (size_t)pending;
   if (*still_pending_size == 0) return TSI_OK;
 
+  GPR_ASSERT(*protected_output_frames_size <= INT_MAX);
   read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames,
-                           *protected_output_frames_size);
+                           (int)*protected_output_frames_size);
   if (read_from_ssl <= 0) {
     gpr_log(GPR_ERROR, "Could not read from BIO after SSL_write.");
     return TSI_INTERNAL_ERROR;
@@ -751,8 +768,9 @@
   *unprotected_bytes_size = output_bytes_size - output_bytes_offset;
 
   /* Then, try to write some data to ssl. */
+  GPR_ASSERT(*protected_frames_bytes_size <= INT_MAX);
   written_into_ssl = BIO_write(impl->into_ssl, protected_frames_bytes,
-                               *protected_frames_bytes_size);
+                               (int)*protected_frames_bytes_size);
   if (written_into_ssl < 0) {
     gpr_log(GPR_ERROR, "Sending protected frame to ssl failed with %d",
             written_into_ssl);
@@ -792,7 +810,8 @@
       *bytes_size > INT_MAX) {
     return TSI_INVALID_ARGUMENT;
   }
-  bytes_read_from_ssl = BIO_read(impl->from_ssl, bytes, *bytes_size);
+  GPR_ASSERT(*bytes_size <= INT_MAX);
+  bytes_read_from_ssl = BIO_read(impl->from_ssl, bytes, (int)*bytes_size);
   if (bytes_read_from_ssl < 0) {
     *bytes_size = 0;
     if (!BIO_should_retry(impl->from_ssl)) {
@@ -822,7 +841,9 @@
   if (bytes == NULL || bytes_size == 0 || *bytes_size > INT_MAX) {
     return TSI_INVALID_ARGUMENT;
   }
-  bytes_written_into_ssl_size = BIO_write(impl->into_ssl, bytes, *bytes_size);
+  GPR_ASSERT(*bytes_size <= INT_MAX);
+  bytes_written_into_ssl_size =
+      BIO_write(impl->into_ssl, bytes, (int)*bytes_size);
   if (bytes_written_into_ssl_size < 0) {
     gpr_log(GPR_ERROR, "Could not write to memory BIO.");
     impl->result = TSI_INTERNAL_ERROR;
@@ -1044,9 +1065,9 @@
 static int select_protocol_list(const unsigned char** out,
                                 unsigned char* outlen,
                                 const unsigned char* client_list,
-                                unsigned int client_list_len,
+                                size_t client_list_len,
                                 const unsigned char* server_list,
-                                unsigned int server_list_len) {
+                                size_t server_list_len) {
   const unsigned char* client_current = client_list;
   while ((unsigned int)(client_current - client_list) < client_list_len) {
     unsigned char client_current_len = *(client_current++);
@@ -1219,7 +1240,8 @@
   tsi_ssl_server_handshaker_factory* factory =
       (tsi_ssl_server_handshaker_factory*)arg;
   *out = factory->alpn_protocol_list;
-  *outlen = factory->alpn_protocol_list_length;
+  GPR_ASSERT(factory->alpn_protocol_list_length <= UINT_MAX);
+  *outlen = (unsigned int)factory->alpn_protocol_list_length;
   return SSL_TLSEXT_ERR_OK;
 }
 
@@ -1277,8 +1299,10 @@
         break;
       }
 #if TSI_OPENSSL_ALPN_SUPPORT
-      if (SSL_CTX_set_alpn_protos(ssl_context, impl->alpn_protocol_list,
-                                  impl->alpn_protocol_list_length)) {
+      GPR_ASSERT(impl->alpn_protocol_list_length < UINT_MAX);
+      if (SSL_CTX_set_alpn_protos(
+              ssl_context, impl->alpn_protocol_list,
+              (unsigned int)impl->alpn_protocol_list_length)) {
         gpr_log(GPR_ERROR, "Could not set alpn protocol list to context.");
         result = TSI_INVALID_ARGUMENT;
         break;
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 7964018..d6bcb54 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -247,6 +247,10 @@
   CXX11_CHECK_CMD = $(CXX) -std=c++11 -o $(TMPOUT) -c test/build/c++11.cc
   HAS_CXX11 = $(shell $(CXX11_CHECK_CMD) 2> /dev/null && echo true || echo false)
 
+  # Detect if -Wshorten-64-to-32 is a thing
+  SHORTEN_64_TO_32_CHECK_CMD = $(CC) -Wshorten-64-to-32 test/build/empty.c
+  HAS_SHORTEN_64_TO_32 = $(shell $(SHORTEN_64_TO_32_CHECK_CMD) 2> /dev/null && echo true || echo false)
+
   # The HOST compiler settings are used to compile the protoc plugins.
   # In most cases, you won't have to change anything, but if you are
   # cross-compiling, you can override these variables from GNU make's
@@ -262,6 +266,9 @@
   endif
 
   CFLAGS += -std=c89 -pedantic -Wsign-conversion
+  ifeq ($(HAS_SHORTEN_64_TO_32),true)
+  CFLAGS += -Wshorten-64-to-32
+  endif
   ifeq ($(HAS_CXX11),true)
   CXXFLAGS += -std=c++11
   else
diff --git a/test/build/empty.c b/test/build/empty.c
new file mode 100644
index 0000000..58e4698
--- /dev/null
+++ b/test/build/empty.c
@@ -0,0 +1,34 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+int main(void) {}
diff --git a/test/core/compression/message_compress_test.c b/test/core/compression/message_compress_test.c
index 495841c..98da6a1 100644
--- a/test/core/compression/message_compress_test.c
+++ b/test/core/compression/message_compress_test.c
@@ -149,7 +149,7 @@
 static void test_bad_data(void) {
   gpr_slice_buffer input;
   gpr_slice_buffer output;
-  int i;
+  grpc_compression_algorithm i;
 
   gpr_slice_buffer_init(&input);
   gpr_slice_buffer_init(&output);
diff --git a/test/core/fling/server.c b/test/core/fling/server.c
index 64f9573..5aace03 100644
--- a/test/core/fling/server.c
+++ b/test/core/fling/server.c
@@ -197,7 +197,7 @@
   grpc_test_init(1, fake_argv);
 
   grpc_init();
-  srand(clock());
+  srand((unsigned)clock());
 
   cl = gpr_cmdline_create("fling server");
   gpr_cmdline_add_string(cl, "bind", "Bind host:port", &addr);
diff --git a/test/core/iomgr/fd_posix_test.c b/test/core/iomgr/fd_posix_test.c
index 8bba87d..af66ef0 100644
--- a/test/core/iomgr/fd_posix_test.c
+++ b/test/core/iomgr/fd_posix_test.c
@@ -419,7 +419,7 @@
   int flags;
   int sv[2];
   char data;
-  int result;
+  ssize_t result;
   grpc_iomgr_closure first_closure;
   grpc_iomgr_closure second_closure;
 
diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c
index c91752b..8c96424 100644
--- a/test/core/iomgr/udp_server_test.c
+++ b/test/core/iomgr/udp_server_test.c
@@ -53,7 +53,7 @@
 
 static void on_read(int fd, grpc_udp_server_cb new_transport_cb, void *cb_arg) {
   char read_buffer[512];
-  int byte_count;
+  ssize_t byte_count;
 
   gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
   byte_count = recv(fd, read_buffer, sizeof(read_buffer), 0);
diff --git a/test/core/support/murmur_hash_test.c b/test/core/support/murmur_hash_test.c
index 1e5279f..1762486 100644
--- a/test/core/support/murmur_hash_test.c
+++ b/test/core/support/murmur_hash_test.c
@@ -57,8 +57,8 @@
      the seed */
 
   for (i = 0; i < 256; i++) {
-    key[i] = (uint8_t)i;
-    hashes[i] = hash(key, i, 256u - i);
+    key[i] = (gpr_uint8)i;
+    hashes[i] = hash(key, i, (gpr_uint32)(256u - i));
   }
 
   /* Then hash the result array */
diff --git a/test/core/support/stack_lockfree_test.c b/test/core/support/stack_lockfree_test.c
index 4a2a053..0f49e6f 100644
--- a/test/core/support/stack_lockfree_test.c
+++ b/test/core/support/stack_lockfree_test.c
@@ -62,7 +62,7 @@
   /* Now add repeatedly more items and check them */
   for (i = 1; i < size; i *= 2) {
     for (j = 0; j <= i; j++) {
-      GPR_ASSERT(gpr_stack_lockfree_push(stack, j) == (j == 0));
+      GPR_ASSERT(gpr_stack_lockfree_push(stack, (int)j) == (j == 0));
     }
     for (j = 0; j <= i; j++) {
       GPR_ASSERT(gpr_stack_lockfree_pop(stack) == (int)(i - j));
@@ -118,7 +118,7 @@
   stack = gpr_stack_lockfree_create(size);
   for (i = 0; i < nth; i++) {
     args[i].stack = stack;
-    args[i].stack_size = size;
+    args[i].stack_size = (int)size;
     args[i].nthreads = nth;
     args[i].rank = i;
     args[i].sum = 0;
@@ -137,7 +137,8 @@
 }
 
 static void test_mt() {
-  size_t size, nth;
+  size_t size;
+  int nth;
   for (nth = 1; nth < MAX_THREADS; nth++) {
     for (size = 128; size < MAX_STACK_SIZE; size *= 2) {
       test_mt_sized(size, nth);
diff --git a/test/core/transport/chttp2/hpack_table_test.c b/test/core/transport/chttp2/hpack_table_test.c
index ec0a569..aa3e273 100644
--- a/test/core/transport/chttp2/hpack_table_test.c
+++ b/test/core/transport/chttp2/hpack_table_test.c
@@ -49,7 +49,7 @@
   GPR_ASSERT(gpr_slice_str_cmp(mdstr->slice, str) == 0);
 }
 
-static void assert_index(const grpc_chttp2_hptbl *tbl, size_t idx,
+static void assert_index(const grpc_chttp2_hptbl *tbl, gpr_uint32 idx,
                          const char *key, const char *value) {
   grpc_mdelem *md = grpc_chttp2_hptbl_lookup(tbl, idx);
   assert_str(tbl, md->key, key);
diff --git a/test/core/transport/chttp2/stream_encoder_test.c b/test/core/transport/chttp2/stream_encoder_test.c
index 4bb503b..a723b90 100644
--- a/test/core/transport/chttp2/stream_encoder_test.c
+++ b/test/core/transport/chttp2/stream_encoder_test.c
@@ -75,8 +75,8 @@
   gpr_slice_buffer_init(&output);
   grpc_sopb_init(&encops);
   GPR_ASSERT(expect_window_used ==
-             grpc_chttp2_preencode(g_sopb.ops, &g_sopb.nops, window_available,
-                                   &encops));
+             grpc_chttp2_preencode(g_sopb.ops, &g_sopb.nops,
+                                   (gpr_uint32)window_available, &encops));
   grpc_chttp2_encode(encops.ops, encops.nops, eof, 0xdeadbeef, &g_compressor,
                      &output);
   encops.nops = 0;
diff --git a/test/core/transport/chttp2/stream_map_test.c b/test/core/transport/chttp2/stream_map_test.c
index 72aaafd..81fb80f 100644
--- a/test/core/transport/chttp2/stream_map_test.c
+++ b/test/core/transport/chttp2/stream_map_test.c
@@ -82,9 +82,9 @@
 }
 
 /* test add & lookup */
-static void test_basic_add_find(size_t n) {
+static void test_basic_add_find(gpr_uint32 n) {
   grpc_chttp2_stream_map map;
-  size_t i;
+  gpr_uint32 i;
   size_t got;
 
   LOG_TEST("test_basic_add_find");
@@ -107,15 +107,15 @@
 
 /* verify that for_each gets the right values during test_delete_evens_XXX */
 static void verify_for_each(void *user_data, gpr_uint32 stream_id, void *ptr) {
-  size_t *for_each_check = user_data;
+  gpr_uint32 *for_each_check = user_data;
   GPR_ASSERT(ptr);
   GPR_ASSERT(*for_each_check == stream_id);
   *for_each_check += 2;
 }
 
-static void check_delete_evens(grpc_chttp2_stream_map *map, size_t n) {
-  size_t for_each_check = 1;
-  size_t i;
+static void check_delete_evens(grpc_chttp2_stream_map *map, gpr_uint32 n) {
+  gpr_uint32 for_each_check = 1;
+  gpr_uint32 i;
   size_t got;
 
   GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(map, 0));
@@ -139,9 +139,9 @@
 
 /* add a bunch of keys, delete the even ones, and make sure the map is
    consistent */
-static void test_delete_evens_sweep(size_t n) {
+static void test_delete_evens_sweep(gpr_uint32 n) {
   grpc_chttp2_stream_map map;
-  size_t i;
+  gpr_uint32 i;
 
   LOG_TEST("test_delete_evens_sweep");
   gpr_log(GPR_INFO, "n = %d", n);
@@ -152,7 +152,8 @@
   }
   for (i = 1; i <= n; i++) {
     if ((i & 1) == 0) {
-      GPR_ASSERT((void *)i == grpc_chttp2_stream_map_delete(&map, i));
+      GPR_ASSERT((void *)(gpr_uintptr)i ==
+                 grpc_chttp2_stream_map_delete(&map, i));
     }
   }
   check_delete_evens(&map, n);
@@ -161,9 +162,9 @@
 
 /* add a bunch of keys, delete the even ones immediately, and make sure the map
    is consistent */
-static void test_delete_evens_incremental(size_t n) {
+static void test_delete_evens_incremental(gpr_uint32 n) {
   grpc_chttp2_stream_map map;
-  size_t i;
+  gpr_uint32 i;
 
   LOG_TEST("test_delete_evens_incremental");
   gpr_log(GPR_INFO, "n = %d", n);
@@ -181,10 +182,10 @@
 
 /* add a bunch of keys, delete old ones after some time, ensure the
    backing array does not grow */
-static void test_periodic_compaction(size_t n) {
+static void test_periodic_compaction(gpr_uint32 n) {
   grpc_chttp2_stream_map map;
-  size_t i;
-  size_t del;
+  gpr_uint32 i;
+  gpr_uint32 del;
 
   LOG_TEST("test_periodic_compaction");
   gpr_log(GPR_INFO, "n = %d", n);
@@ -192,10 +193,11 @@
   grpc_chttp2_stream_map_init(&map, 16);
   GPR_ASSERT(map.capacity == 16);
   for (i = 1; i <= n; i++) {
-    grpc_chttp2_stream_map_add(&map, i, (void *)i);
+    grpc_chttp2_stream_map_add(&map, i, (void *)(gpr_uintptr)i);
     if (i > 8) {
       del = i - 8;
-      GPR_ASSERT((void *)del == grpc_chttp2_stream_map_delete(&map, del));
+      GPR_ASSERT((void *)(gpr_uintptr)del ==
+                 grpc_chttp2_stream_map_delete(&map, del));
     }
   }
   GPR_ASSERT(map.capacity == 16);
@@ -203,9 +205,9 @@
 }
 
 int main(int argc, char **argv) {
-  size_t n = 1;
-  size_t prev = 1;
-  size_t tmp;
+  gpr_uint32 n = 1;
+  gpr_uint32 prev = 1;
+  gpr_uint32 tmp;
 
   grpc_test_init(argc, argv);
 
diff --git a/tools/codegen/core/gen_hpack_tables.c b/tools/codegen/core/gen_hpack_tables.c
index 555f1e7..dec0e2f 100644
--- a/tools/codegen/core/gen_hpack_tables.c
+++ b/tools/codegen/core/gen_hpack_tables.c
@@ -127,7 +127,9 @@
 /* represents a set of symbols as an array of booleans indicating inclusion */
 typedef struct { char included[GRPC_CHTTP2_NUM_HUFFSYMS]; } symset;
 /* represents a lookup table indexed by a nibble */
-typedef struct { int values[16]; } nibblelut;
+typedef struct { unsigned values[16]; } nibblelut;
+
+#define NOT_SET (~(unsigned)0)
 
 /* returns a symset that includes all possible symbols */
 static symset symset_all(void) {
@@ -148,7 +150,7 @@
   nibblelut x;
   int i;
   for (i = 0; i < 16; i++) {
-    x.values[i] = -1;
+    x.values[i] = NOT_SET;
   }
   return x;
 }
@@ -168,7 +170,7 @@
 /* global table of discovered huffman decoding states */
 static struct {
   /* the bit offset that this state starts at */
-  int bitofs;
+  unsigned bitofs;
   /* the set of symbols that this state started with */
   symset syms;
 
@@ -177,13 +179,13 @@
   /* lookup table for what to emit */
   nibblelut emit;
 } huffstates[MAXHUFFSTATES];
-static int nhuffstates = 0;
+static unsigned nhuffstates = 0;
 
 /* given a number of decoded bits and a set of symbols that are live,
    return the index into the decoder table for this state.
    set isnew to 1 if this state was previously undiscovered */
-static int state_index(int bitofs, symset syms, int *isnew) {
-  int i;
+static unsigned state_index(unsigned bitofs, symset syms, unsigned *isnew) {
+  unsigned i;
   for (i = 0; i < nhuffstates; i++) {
     if (huffstates[i].bitofs != bitofs) continue;
     if (0 != memcmp(huffstates[i].syms.included, syms.included,
@@ -211,24 +213,24 @@
    emit    - the symbol to emit on this nibble (or -1 if no symbol has been
              found)
    syms    - the set of symbols that could be matched */
-static void build_dec_tbl(int state, int nibble, int nibbits, unsigned bitofs,
-                          int emit, symset syms) {
-  int i;
+static void build_dec_tbl(unsigned state, unsigned nibble, int nibbits,
+                          unsigned bitofs, unsigned emit, symset syms) {
+  unsigned i;
   unsigned bit;
 
   /* If we have four bits in the nibble we're looking at, then we can fill in
      a slot in the lookup tables. */
   if (nibbits == 4) {
-    int isnew;
+    unsigned isnew;
     /* Find the state that we are in: this may be a new state, in which case
        we recurse to fill it in, or we may have already seen this state, in
        which case the recursion terminates */
-    int st = state_index(bitofs, syms, &isnew);
-    GPR_ASSERT(huffstates[state].next.values[nibble] == -1);
+    unsigned st = state_index(bitofs, syms, &isnew);
+    GPR_ASSERT(huffstates[state].next.values[nibble] == NOT_SET);
     huffstates[state].next.values[nibble] = st;
     huffstates[state].emit.values[nibble] = emit;
     if (isnew) {
-      build_dec_tbl(st, 0, 0, bitofs, -1, syms);
+      build_dec_tbl(st, 0, 0, bitofs, NOT_SET, syms);
     }
     return;
   }
@@ -290,8 +292,9 @@
 }
 
 static void generate_huff_tables(void) {
-  int i;
-  build_dec_tbl(state_index(0, symset_all(), &i), 0, 0, 0, -1, symset_all());
+  unsigned i;
+  build_dec_tbl(state_index(0, symset_all(), &i), 0, 0, 0, NOT_SET,
+                symset_all());
 
   nctbl = 0;
   printf("static const gpr_uint8 next_tbl[%d] = {", nhuffstates);