diff --git a/gcc/builtins.c b/gcc/builtins.c
index 3e57eb03af0..894d62359b4 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -180,6 +180,7 @@ static rtx expand_builtin_memory_chk (tree, rtx, machine_mode,
 static void maybe_emit_chk_warning (tree, enum built_in_function);
 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
 static tree fold_builtin_object_size (tree, tree);
+static tree fold_builtin_dyn_object_size (tree, tree);
 
 unsigned HOST_WIDE_INT target_newline;
 unsigned HOST_WIDE_INT target_percent;
@@ -7910,6 +7911,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode,
       return const0_rtx;
 
     case BUILT_IN_OBJECT_SIZE:
+    case BUILT_IN_DYN_OBJECT_SIZE:
       return expand_builtin_object_size (exp);
 
     case BUILT_IN_MEMCPY_CHK:
@@ -9318,6 +9320,9 @@ fold_builtin_2 (location_t loc, tree expr, tree fndecl, tree arg0, tree arg1)
     case BUILT_IN_OBJECT_SIZE:
       return fold_builtin_object_size (arg0, arg1);
 
+    case BUILT_IN_DYN_OBJECT_SIZE:
+      return fold_builtin_dyn_object_size (arg0, arg1);
+
     case BUILT_IN_ATOMIC_ALWAYS_LOCK_FREE:
       return fold_builtin_atomic_always_lock_free (arg0, arg1);
 
@@ -9964,7 +9969,10 @@ fold_builtin_next_arg (tree exp, bool va_start_p)
 }
 
 
-/* Expand a call EXP to __builtin_object_size.  */
+/* Expand a call EXP to __builtin_object_size or
+   __builtin_dynamic_object_size.  If the builtin survived up to this point
+   then it means we have failed to get an object size, so replace the call with
+   0 or -1 depending on the object size type argument.  */
 
 static rtx
 expand_builtin_object_size (tree exp)
@@ -10250,27 +10258,40 @@ maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
 		access_write_only);
 }
 
-/* Fold a call to __builtin_object_size with arguments PTR and OST,
-   if possible.  */
+/* Validate arguments to __builtin_object_size and
+   __builtin_dynamic_object_size.  If both arguments are valid, return the
+   object size type in OSTP.  */
 
-static tree
-fold_builtin_object_size (tree ptr, tree ost)
+static bool
+valid_object_size_args (const tree ptr, tree ost, int *ostp)
 {
-  unsigned HOST_WIDE_INT bytes;
-  int object_size_type;
-
   if (!validate_arg (ptr, POINTER_TYPE)
       || !validate_arg (ost, INTEGER_TYPE))
-    return NULL_TREE;
+    return false;
 
   STRIP_NOPS (ost);
 
   if (TREE_CODE (ost) != INTEGER_CST
       || tree_int_cst_sgn (ost) < 0
       || compare_tree_int (ost, 3) > 0)
-    return NULL_TREE;
+    return false;
 
-  object_size_type = tree_to_shwi (ost);
+  *ostp = tree_to_shwi (ost);
+
+  return true;
+}
+
+/* Fold a call to __builtin_object_size with arguments PTR and OST,
+   if possible.  */
+
+static tree
+fold_builtin_object_size (tree ptr, tree ost)
+{
+  unsigned HOST_WIDE_INT bytes;
+  int object_size_type;
+
+  if (!valid_object_size_args (ptr, ost, &object_size_type))
+    return NULL_TREE;
 
   /* __builtin_object_size doesn't evaluate side-effects in its arguments;
      if there are any side-effects, it returns (size_t) -1 for types 0 and 1
@@ -10297,6 +10318,26 @@ fold_builtin_object_size (tree ptr, tree ost)
   return NULL_TREE;
 }
 
+/* Fold a call to __builtin_dynamic_object_size with arguments PTR and OST,
+   if possible.  */
+
+static tree
+fold_builtin_dyn_object_size (tree ptr, tree ost)
+{
+  int object_size_type;
+
+  if (!valid_object_size_args (ptr, ost, &object_size_type))
+    return NULL_TREE;
+
+  /* __builtin_dynamic_object_size doesn't evaluate side-effects in its
+     arguments; if there are any side-effects, it returns (size_t) -1 for types
+     0 and 1 and (size_t) 0 for types 2 and 3.  */
+  if (TREE_SIDE_EFFECTS (ptr))
+    return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0);
+
+  return NULL_TREE;
+}
+
 /* Builtins with folding operations that operate on "..." arguments
    need special handling; we need to store the arguments in a convenient
    data structure before attempting any folding.  Fortunately there are
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 45a09b4d42d..ae94caab921 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -972,6 +972,7 @@ DEF_BUILTIN_STUB (BUILT_IN_STRNCMP_EQ, "__builtin_strncmp_eq")
 
 /* Object size checking builtins.  */
 DEF_GCC_BUILTIN	       (BUILT_IN_OBJECT_SIZE, "object_size", BT_FN_SIZE_CONST_PTR_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN	       (BUILT_IN_DYN_OBJECT_SIZE, "dynamic_object_size", BT_FN_SIZE_CONST_PTR_INT, ATTR_NOTHROW_LEAF_LIST)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_MEMCPY_CHK, "__memcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_MEMMOVE_CHK, "__memmove_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_MEMPCPY_CHK, "__mempcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RETNONNULL_NOTHROW_LEAF)
