diff --git a/gcc/testsuite/g++.dg/ext/builtin-dynamic-object-size1.C b/gcc/testsuite/g++.dg/ext/builtin-dynamic-object-size1.C
new file mode 100644
index 00000000000..b11ac200751
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/builtin-dynamic-object-size1.C
@@ -0,0 +1,5 @@
+// { dg-do run }
+// { dg-options "-O2" }
+
+#define __builtin_object_size __builtin_dynamic_object_size
+#include "builtin-object-size1.C"
diff --git a/gcc/testsuite/g++.dg/ext/builtin-dynamic-object-size2.C b/gcc/testsuite/g++.dg/ext/builtin-dynamic-object-size2.C
new file mode 100644
index 00000000000..6e52cf38533
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/builtin-dynamic-object-size2.C
@@ -0,0 +1,5 @@
+// { dg-do run }
+// { dg-options "-O2" }
+
+#define __builtin_object_size __builtin_dynamic_object_size
+#include "builtin-object-size2.C"
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-alloc-size.c b/gcc/testsuite/gcc.dg/builtin-dynamic-alloc-size.c
new file mode 100644
index 00000000000..9d0eadd6be4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-alloc-size.c
@@ -0,0 +1,7 @@
+/* { dg-do compile }
+   { dg-require-effective-target alloca }
+   { dg-additional-options "-O2 -fdump-tree-optimized" } */
+
+#define __builtin_object_size __builtin_dynamic_object_size
+#include "builtin-alloc-size.c"
+/* { dg-final { scan-tree-dump-not "abort" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c
new file mode 100644
index 00000000000..2c7d2128913
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c
@@ -0,0 +1,7 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target alloca } */
+
+#define DYNAMIC_OBJECT_SIZE
+#define __builtin_object_size __builtin_dynamic_object_size
+#include "builtin-object-size-1.c"
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-10.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-10.c
new file mode 100644
index 00000000000..6db9ea8c667
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-10.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-early_dynobjsz-details -fdump-tree-dynobjsz1-details" } */
+// { dg-skip-if "packed attribute missing for drone_source_packet" { "epiphany-*-*" } }
+
+#define __builtin_object_size __builtin_dynamic_object_size
+#include "builtin-object-size-10.c"
+
+/* { dg-final { scan-tree-dump "spkt.*: maximum dynamic object size _" "early_dynobjsz" } } */
+/* { dg-final { scan-tree-dump ": maximum dynamic subobject size _" "early_dynobjsz" } } */
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-11.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-11.c
new file mode 100644
index 00000000000..65dcec9fcae
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-11.c
@@ -0,0 +1,7 @@
+/* PR48985 */
+/* { dg-do run } */
+/* { dg-options "-std=gnu89" } */
+/* { dg-skip-if "packed attribute missing for struct s" { "epiphany-*-*" } } */
+
+#define __builtin_object_size __builtin_dynamic_object_size
+#include "builtin-object-size-11.c"
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-12.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-12.c
new file mode 100644
index 00000000000..f0ce050a943
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-12.c
@@ -0,0 +1,5 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#define __builtin_object_size __builtin_dynamic_object_size
+#include "builtin-object-size-12.c"
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-13.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-13.c
new file mode 100644
index 00000000000..555e23522dc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-13.c
@@ -0,0 +1,5 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#define __builtin_object_size __builtin_dynamic_object_size
+#include "builtin-object-size-13.c"
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-14.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-14.c
new file mode 100644
index 00000000000..26207200191
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-14.c
@@ -0,0 +1,5 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#define __builtin_object_size __builtin_dynamic_object_size
+#include "builtin-object-size-14.c"
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-15.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-15.c
new file mode 100644
index 00000000000..ad4d562f777
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-15.c
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#define DYNAMIC_OBJECT_SIZE
+#define __builtin_object_size __builtin_dynamic_object_size
+#include "builtin-object-size-15.c"
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-16.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-16.c
new file mode 100644
index 00000000000..5aa256dec1a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-16.c
@@ -0,0 +1,7 @@
+/* { dg-do run } */
+/* { dg-options "-O0" } */
+
+#define DYNAMIC_OBJECT_SIZE
+#define __builtin_object_size __builtin_dynamic_object_size
+char ax2[];               /* { dg-warning "assumed to have one element" } */
+#include "builtin-object-size-16.c"
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-17.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-17.c
new file mode 100644
index 00000000000..d88317d111d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-17.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -fdump-tree-ssa" } */
+
+char ax2[];               /* { dg-warning "assumed to have one element" } */
+#define __builtin_object_size __builtin_dynamic_object_size
+#define DYNAMIC_OBJECT_SIZE
+#include "builtin-object-size-17.c"
+/* { dg-final { scan-tree-dump-not "failure_on_line" "ssa" } } */
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-18.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-18.c
new file mode 100644
index 00000000000..70c1ebcff21
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-18.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* __stpncpy_chk could return buf up to buf + 64, so
+   the minimum object size might be far smaller than 64.  */
+/* { dg-final { scan-tree-dump-not "return 64;" "optimized" } } */
+
+#define __builtin_object_size __builtin_dynamic_object_size
+#include "builtin-object-size-18.c"
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-19.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-19.c
new file mode 100644
index 00000000000..44141a38607
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-19.c
@@ -0,0 +1,104 @@
+/* PR tree-optimization/88372 - alloc_size attribute is ignored
+   on function pointers { dg-do compile }
+   { dg-options "-O2 -fdump-tree-optimized" } */
+
+#define __builtin_object_size __builtin_dynamic_object_size
+#include "builtin-object-size-18.c"
+
+typedef __SIZE_TYPE__ size_t;
+
+#define ATTR(...) __attribute__ ((__VA_ARGS__))
+#define CONCAT(x, y) x ## y
+#define CAT(x, y) CONCAT (x, y)
+#define FAILNAME(name) CAT (call_ ## name ##_on_line_, __LINE__)
+
+#define FAIL(name) do {				\
+    extern void FAILNAME (name) (void);		\
+    FAILNAME (name)();				\
+  } while (0)
+
+/* Macro to emit a call to function named
+   call_in_true_branch_not_eliminated_on_line_NNN()
+   for each call that's expected to be eliminated.  The dg-final
+   scan-tree-dump-time directive at the bottom of the test verifies
+   that no such call appears in output.  */
+#define ELIM(expr)							\
+  if (!(expr)) FAIL (in_true_branch_not_eliminated); else (void)0
+
+void sink (void*);
+
+#define T(alloc, n) do {			\
+    void *p = alloc;				\
+    sink (p);					\
+    ELIM (n == __builtin_object_size (p, 0));	\
+    ELIM (n == __builtin_object_size (p, 1));	\
+    ELIM (n == __builtin_object_size (p, 2));	\
+    ELIM (n == __builtin_object_size (p, 3));	\
+  } while (0)
+
+
+ATTR (alloc_size (1)) void* (*alloc_1_x)(size_t, size_t);
+ATTR (alloc_size (2)) void* (*alloc_x_2)(size_t, size_t);
+
+/* Verify that things work when attribute alloc_size is applied
+   to a typedef that is then used to declared a pointer.  */
+typedef ATTR (alloc_size (1, 2)) void* (alloc_1_2_t)(size_t, size_t);
+
+void test_alloc_ptr (alloc_1_2_t *alloc_1_2)
+{
+  T (alloc_1_x (0, 0), 0);
+  T (alloc_1_x (1, 0), 1);
+  T (alloc_1_x (3, 0), 3);
+  T (alloc_1_x (9, 5), 9);
+
+  T (alloc_x_2 (0, 0), 0);
+  T (alloc_x_2 (1, 0), 0);
+  T (alloc_x_2 (0, 1), 1);
+  T (alloc_x_2 (9, 5), 5);
+
+  T (alloc_1_2 (0, 0), 0);
+  T (alloc_1_2 (1, 0), 0);
+  T (alloc_1_2 (0, 1), 0);
+  T (alloc_1_2 (9, 5), 45);
+}
+
+/* Verify that object size is detected even in indirect calls via
+   function pointers to built-in allocation functions, even without
+   explicit use of attribute alloc_size on the pointers.  */
+
+typedef void *(allocfn_1) (size_t);
+typedef void *(allocfn_1_2) (size_t, size_t);
+
+static inline void *
+call_alloc (allocfn_1 *fn1, allocfn_1_2 *fn2, size_t n1, size_t n2)
+{
+  return fn1 ? fn1 (n1) : fn2 (n1, n2);
+}
+
+static inline void *
+call_malloc (size_t n)
+{
+  return call_alloc (__builtin_malloc, 0, n, 0);
+}
+
+static inline void *
+call_calloc (size_t n1, size_t n2)
+{
+  return call_alloc (0, __builtin_calloc, n1, n2);
+}
+
+void test_builtin_ptr (void)
+{
+  T (call_malloc (0), 0);
+  T (call_malloc (1), 1);
+  T (call_malloc (9), 9);
+
+  T (call_calloc (0, 0), 0);
+  T (call_calloc (0, 1), 0);
+  T (call_calloc (1, 0), 0);
+  T (call_calloc (1, 1), 1);
+  T (call_calloc (1, 3), 3);
+  T (call_calloc (2, 3), 6);
+}
+
+/* { dg-final { scan-tree-dump-not "not_eliminated" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c
new file mode 100644
index 00000000000..2f07534c11b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c
@@ -0,0 +1,7 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target alloca } */
+
+#define DYNAMIC_OBJECT_SIZE
+#define __builtin_object_size __builtin_dynamic_object_size
+#include "builtin-object-size-2.c"
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-3.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-3.c
new file mode 100644
index 00000000000..29b5b358845
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-3.c
@@ -0,0 +1,7 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target alloca } */
+
+#define DYNAMIC_OBJECT_SIZE
+#define __builtin_object_size __builtin_dynamic_object_size
+#include "builtin-object-size-3.c"
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c
new file mode 100644
index 00000000000..5ff1f16c978
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c
@@ -0,0 +1,7 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target alloca } */
+
+#define DYNAMIC_OBJECT_SIZE
+#define __builtin_object_size __builtin_dynamic_object_size
+#include "builtin-object-size-4.c"
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-6.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-6.c
new file mode 100644
index 00000000000..6a275ce5b37
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-6.c
@@ -0,0 +1,5 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#define __builtin_object_size __builtin_dynamic_object_size
+#include "builtin-object-size-6.c"
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-7.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-7.c
new file mode 100644
index 00000000000..e2a65994687
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-7.c
@@ -0,0 +1,5 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#define __builtin_object_size __builtin_dynamic_object_size
+#include "builtin-object-size-7.c"
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-8.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-8.c
new file mode 100644
index 00000000000..e7af383d9b6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-8.c
@@ -0,0 +1,5 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#define __builtin_object_size __builtin_dynamic_object_size
+#include "builtin-object-size-8.c"
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-9.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-9.c
new file mode 100644
index 00000000000..19021bc2ce9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-9.c
@@ -0,0 +1,5 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#define __builtin_object_size __builtin_dynamic_object_size
+#include "builtin-object-size-9.c"
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-1.c b/gcc/testsuite/gcc.dg/builtin-object-size-1.c
index 8cdae49a6b1..33987dd279f 100644
--- a/gcc/testsuite/gcc.dg/builtin-object-size-1.c
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-1.c
@@ -42,9 +42,17 @@ test1 (void *q, int x)
     abort ();
   if (__builtin_object_size (q, 0) != (size_t) -1)
     abort ();
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (r, 0)
+      != (x < 0
+	  ? sizeof (a) - __builtin_offsetof (struct A, a) - 9
+	  : sizeof (a) - __builtin_offsetof (struct A, c) - 1))
+    abort ();
+#else
   if (__builtin_object_size (r, 0)
       != sizeof (a) - __builtin_offsetof (struct A, a) - 9)
     abort ();
+#endif
   if (x < 6)
     r = &w[2].a[1];
   else
@@ -58,9 +66,17 @@ test1 (void *q, int x)
   if (__builtin_object_size (&y.b, 0)
       != sizeof (a) - __builtin_offsetof (struct A, b))
     abort ();
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (r, 0)
+      != (x < 6
+	  ? 2 * sizeof (w[0]) - __builtin_offsetof (struct A, a) - 1
+	  : sizeof (a) - __builtin_offsetof (struct A, a) - 6))
+    abort ();
+#else
   if (__builtin_object_size (r, 0)
       != 2 * sizeof (w[0]) - __builtin_offsetof (struct A, a) - 1)
     abort ();
+#endif
   if (x < 20)
     r = malloc (30);
   else
@@ -119,12 +135,21 @@ test1 (void *q, int x)
     abort ();
   if (__builtin_object_size (&extb[5], 0) != sizeof (extb) - 5)
     abort ();
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (var, 0) != x + 10)
+    abort ();
+  if (__builtin_object_size (var + 10, 0) != x)
+    abort ();
+  if (__builtin_object_size (&var[5], 0) != x + 5)
+    abort ();
+#else
   if (__builtin_object_size (var, 0) != (size_t) -1)
     abort ();
   if (__builtin_object_size (var + 10, 0) != (size_t) -1)
     abort ();
   if (__builtin_object_size (&var[5], 0) != (size_t) -1)
     abort ();
+#endif
   if (__builtin_object_size (zerol, 0) != 0)
     abort ();
   if (__builtin_object_size (&zerol, 0) != 0)
@@ -165,6 +190,9 @@ test2 (void)
   struct B { char buf1[10]; char buf2[10]; } a;
   char *r, buf3[20];
   int i;
+#ifdef DYNAMIC_OBJECT_SIZE
+  size_t dyn_res;
+#endif
 
   if (sizeof (a) != 20)
     return;
@@ -181,8 +209,26 @@ test2 (void)
       else if (i == l1 + 2)
 	r = &a.buf1[9];
     }
+#ifdef DYNAMIC_OBJECT_SIZE
+  dyn_res = sizeof (buf3);
+
+  for (i = 0; i < 4; ++i)
+    {
+      if (i == l1 - 1)
+	dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf1) - 1;
+      else if (i == l1)
+	dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf2) - 7;
+      else if (i == l1 + 1)
+	dyn_res = sizeof (buf3) - 5;
+      else if (i == l1 + 2)
+	dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf1) - 9;
+    }
+  if (__builtin_object_size (r, 0) != dyn_res)
+    abort ();
+#else
   if (__builtin_object_size (r, 0) != 20)
     abort ();
+#endif
   r = &buf3[20];
   for (i = 0; i < 4; ++i)
     {
@@ -195,13 +241,44 @@ test2 (void)
       else if (i == l1 + 2)
 	r = &a.buf1[9];
     }
+#ifdef DYNAMIC_OBJECT_SIZE
+  dyn_res = sizeof (buf3) - 20;
+
+  for (i = 0; i < 4; ++i)
+    {
+      if (i == l1 - 1)
+	dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf1) - 7;
+      else if (i == l1)
+	dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf2) - 7;
+      else if (i == l1 + 1)
+	dyn_res = sizeof (buf3) - 5;
+      else if (i == l1 + 2)
+	dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf1) - 9;
+    }
+  if (__builtin_object_size (r, 0) != dyn_res)
+    abort ();
+#else
   if (__builtin_object_size (r, 0) != 15)
     abort ();
+#endif
   r += 8;
+#ifdef DYNAMIC_OBJECT_SIZE
+  dyn_res -= 8;
+  if (__builtin_object_size (r, 0) != dyn_res)
+    abort ();
+  if (dyn_res >= 6)
+    {
+      if (__builtin_object_size (r + 6, 0) != dyn_res - 6)
+	abort ();
+    }
+  else if (__builtin_object_size (r + 6, 0) != 0)
+    abort ();
+#else
   if (__builtin_object_size (r, 0) != 7)
     abort ();
   if (__builtin_object_size (r + 6, 0) != 1)
     abort ();
+#endif
   r = &buf3[18];
   for (i = 0; i < 4; ++i)
     {
@@ -214,8 +291,31 @@ test2 (void)
       else if (i == l1 + 2)
 	r = &a.buf1[4];
     }
+#ifdef DYNAMIC_OBJECT_SIZE
+  dyn_res = sizeof (buf3) - 18;
+
+  for (i = 0; i < 4; ++i)
+    {
+      if (i == l1 - 1)
+	  dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf1) - 9;
+      else if (i == l1)
+	dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf2) - 9;
+      else if (i == l1 + 1)
+	dyn_res = sizeof (buf3) - 5;
+      else if (i == l1 + 2)
+	dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf1) - 4;
+    }
+  if (dyn_res >= 12)
+    {
+      if (__builtin_object_size (r + 12, 0) != dyn_res - 12)
+	abort ();
+    }
+  else if (__builtin_object_size (r + 12, 0) != 0)
+    abort ();
+#else
   if (__builtin_object_size (r + 12, 0) != 4)
     abort ();
+#endif
 }
 
 void
@@ -358,6 +458,10 @@ test5 (size_t x)
 
   for (i = 0; i < x; ++i)
     p = p + 4;
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (p, 0) != sizeof (buf) - 8 - 4 * x)
+    abort ();
+#else
   /* My understanding of ISO C99 6.5.6 is that a conforming
      program will not end up with p equal to &buf[0]
      through &buf[7], i.e. calling this function with say
@@ -367,6 +471,7 @@ test5 (size_t x)
      it would be 64 (or conservative (size_t) -1 == unknown).  */
   if (__builtin_object_size (p, 0) != sizeof (buf) - 8)
     abort ();
+#endif
   memset (p, ' ', sizeof (buf) - 8 - 4 * 4);
 }
 
@@ -380,8 +485,13 @@ test6 (size_t x)
 
   for (i = 0; i < x; ++i)
     p = p + 4;
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (p, 0) != sizeof (t) - 8 - 4 * x)
+    abort ();
+#else
   if (__builtin_object_size (p, 0) != sizeof (t) - 8)
     abort ();
+#endif
   memset (p, ' ', sizeof (t) - 8 - 4 * 4);
 }
 
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-16.c b/gcc/testsuite/gcc.dg/builtin-object-size-16.c
index 48229390bfd..67680020337 100644
--- a/gcc/testsuite/gcc.dg/builtin-object-size-16.c
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-16.c
@@ -54,7 +54,9 @@ static int nfails;
 typedef __SIZE_TYPE__ size_t;
 
 extern char ax[];
+#ifndef DYNAMIC_OBJECT_SIZE
 char ax2[];               /* { dg-warning "assumed to have one element" } */
+#endif
 
 extern char a0[0];
 static char a1[1];
@@ -114,11 +116,19 @@ test_arrays ()
   T (     4,       2,       4,       2,   &a2x2[0][0]);
   T (     0,  F1  (0),      0,       0,   &a2x2 + 1);
   T (     2,  F1 ( 2),      2,  F3 ( 2),  &a2x2[0] + 1);
+#ifdef DYNAMIC_OBJECT_SIZE
+  T (     3,  F1 ( 1),      3,  F3 ( 1),  &a2x2[0][0] + 1);
+#else
   T (     3,  F1 ( 1),      3,  F3 ( 3),  &a2x2[0][0] + 1);
+#endif
 
   T (    15,      15,      15,      15,   a3x5);
   T (    15,       5,      15,       5,   &a3x5[0][0] + 0);
+#ifdef DYNAMIC_OBJECT_SIZE
+  T (    14,  F1 ( 4),     14,  F3 ( 4),  &a3x5[0][0] + 1);
+#else
   T (    14,  F1 ( 4),     14,  F3 (14),  &a3x5[0][0] + 1);
+#endif
 
   T (     1,       1,       1,       1,   a1 + 0);
   T (     0,  F1  (0),      0,       0,   a1 + 1);
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-17.c b/gcc/testsuite/gcc.dg/builtin-object-size-17.c
index 0497bbf4505..09552a8a963 100644
--- a/gcc/testsuite/gcc.dg/builtin-object-size-17.c
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-17.c
@@ -49,7 +49,9 @@
 typedef __SIZE_TYPE__ size_t;
 
 extern char ax[];
+#ifndef DYNAMIC_OBJECT_SIZE
 char ax2[];               /* { dg-warning "assumed to have one element" } */
+#endif
 
 extern char a0[0];
 static char a1[1];
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-2.c b/gcc/testsuite/gcc.dg/builtin-object-size-2.c
index ad2dd296a9a..c7ce5e988ca 100644
--- a/gcc/testsuite/gcc.dg/builtin-object-size-2.c
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-2.c
@@ -32,6 +32,9 @@ test1 (void *q, int x)
   void *p = &a.a[3], *r;
   char var[x + 10];
   struct A vara[x + 10];
+#ifdef DYNAMIC_OBJECT_SIZE
+  size_t dyn_res;
+#endif
   if (x < 0)
     r = &a.a[9];
   else
@@ -43,8 +46,15 @@ test1 (void *q, int x)
     abort ();
   if (__builtin_object_size (q, 1) != (size_t) -1)
     abort ();
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (x < 0
+      ? __builtin_object_size (r, 1) != sizeof (a.a) - 9
+      : __builtin_object_size (r, 1) != sizeof (a.c) - 1)
+    abort ();
+#else
   if (__builtin_object_size (r, 1) != sizeof (a.c) - 1)
     abort ();
+#endif
   if (x < 6)
     r = &w[2].a[1];
   else
@@ -55,36 +65,74 @@ test1 (void *q, int x)
     abort ();
   if (__builtin_object_size (&y.b, 1) != sizeof (a.b))
     abort ();
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (x < 6
+      ? __builtin_object_size (r, 1) != sizeof (a.a) - 1
+      : __builtin_object_size (r, 1) != sizeof (a.a) - 6)
+    abort ();
+#else
   if (__builtin_object_size (r, 1) != sizeof (a.a) - 1)
     abort ();
+#endif
   if (x < 20)
     r = malloc (30);
   else
     r = calloc (2, 16);
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (x < 20
+      ? __builtin_object_size (r, 1) != 30
+      : __builtin_object_size (r, 1) != 2 * 16)
+    abort ();
+#else
   /* We may duplicate this test onto the two exit paths.  On one path
      the size will be 32, the other it will be 30.  If we don't duplicate
      this test, then the size will be 32.  */
   if (__builtin_object_size (r, 1) != 2 * 16
       && __builtin_object_size (r, 1) != 30)
     abort ();
+#endif
   if (x < 20)
     r = malloc (30);
   else
     r = calloc (2, 14);
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (x < 20
+      ? __builtin_object_size (r, 1) != 30
+      : __builtin_object_size (r, 1) != 2 * 14)
+    abort ();
+#else
   if (__builtin_object_size (r, 1) != 30)
     abort ();
+#endif
   if (x < 30)
     r = malloc (sizeof (a));
   else
     r = &a.a[3];
+#ifdef DYNAMIC_OBJECT_SIZE
+  dyn_res = x < 30 ? sizeof (a) : sizeof (a.a) - 3;
+  if (__builtin_object_size (r, 1) != dyn_res)
+    abort ();
+#else
   if (__builtin_object_size (r, 1) != sizeof (a))
     abort ();
+#endif
   r = memcpy (r, "a", 2);
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (r, 1) != dyn_res)
+    abort ();
+#else
   if (__builtin_object_size (r, 1) != sizeof (a))
     abort ();
+#endif
   r = memcpy (r + 2, "b", 2) + 2;
+#ifdef DYNAMIC_OBJECT_SIZE
+  dyn_res -= 4;
+  if (__builtin_object_size (r, 1) != dyn_res)
+    abort ();
+#else
   if (__builtin_object_size (r, 1) != sizeof (a) - 4)
     abort ();
+#endif
   r = &a.a[4];
   r = memset (r, 'a', 2);
   if (__builtin_object_size (r, 1) != sizeof (a.a) - 4)
@@ -123,6 +171,20 @@ test1 (void *q, int x)
     abort ();
   if (__builtin_object_size (&extc[5].c[3], 1) != (size_t) -1)
     abort ();
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (var, 1) != x + 10)
+    abort ();
+  if (__builtin_object_size (var + 10, 1) != x)
+    abort ();
+  if (__builtin_object_size (&var[5], 1) != x + 5)
+    abort ();
+  if (__builtin_object_size (vara, 1) != (x + 10) * sizeof (struct A))
+    abort ();
+  if (__builtin_object_size (vara + 10, 1) != x * sizeof (struct A))
+    abort ();    
+  if (__builtin_object_size (&vara[5], 1) != (x + 5) * sizeof (struct A))
+    abort ();
+#else
   if (__builtin_object_size (var, 1) != (size_t) -1)
     abort ();
   if (__builtin_object_size (var + 10, 1) != (size_t) -1)
@@ -135,6 +197,7 @@ test1 (void *q, int x)
     abort ();    
   if (__builtin_object_size (&vara[5], 1) != (size_t) -1)
     abort ();
+#endif
   if (__builtin_object_size (&vara[0].a, 1) != sizeof (vara[0].a))
     abort ();
   if (__builtin_object_size (&vara[10].a[0], 1) != sizeof (vara[0].a))
@@ -185,6 +248,9 @@ test2 (void)
   struct B { char buf1[10]; char buf2[10]; } a;
   char *r, buf3[20];
   int i;
+#ifdef DYNAMIC_OBJECT_SIZE
+  size_t dyn_res;
+#endif
 
   if (sizeof (a) != 20)
     return;
@@ -201,8 +267,26 @@ test2 (void)
       else if (i == l1 + 2)
 	r = &a.buf1[9];
     }
+#ifdef DYNAMIC_OBJECT_SIZE
+  dyn_res = sizeof (buf3);
+
+  for (i = 0; i < 4; ++i)
+    {
+      if (i == l1 - 1)
+	dyn_res = sizeof (a.buf1) - 1;
+      else if (i == l1)
+	dyn_res = sizeof (a.buf2) - 7;
+      else if (i == l1 + 1)
+	dyn_res = sizeof (buf3) - 5;
+      else if (i == l1 + 2)
+	dyn_res = sizeof (a.buf1) - 9;
+    }
+  if (__builtin_object_size (r, 1) != dyn_res)
+    abort ();
+#else
   if (__builtin_object_size (r, 1) != sizeof (buf3))
     abort ();
+#endif
   r = &buf3[20];
   for (i = 0; i < 4; ++i)
     {
@@ -215,13 +299,50 @@ test2 (void)
       else if (i == l1 + 2)
 	r = &a.buf1[9];
     }
+#ifdef DYNAMIC_OBJECT_SIZE
+  dyn_res = sizeof (buf3) - 20;
+
+  for (i = 0; i < 4; ++i)
+    {
+      if (i == l1 - 1)
+	dyn_res = sizeof (a.buf1) - 7;
+      else if (i == l1)
+	dyn_res = sizeof (a.buf2) - 7;
+      else if (i == l1 + 1)
+	dyn_res = sizeof (buf3) - 5;
+      else if (i == l1 + 2)
+	dyn_res = sizeof (a.buf1) - 9;
+    }
+  if (__builtin_object_size (r, 1) != dyn_res)
+    abort ();
+#else
   if (__builtin_object_size (r, 1) != sizeof (buf3) - 5)
     abort ();
+#endif
   r += 8;
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (dyn_res >= 8)
+    {
+      dyn_res -= 8;
+      if (__builtin_object_size (r, 1) != dyn_res)
+	abort ();
+
+      if (dyn_res >= 6)
+	{
+	  if (__builtin_object_size (r + 6, 1) != dyn_res - 6)
+	    abort ();
+	}
+      else if (__builtin_object_size (r + 6, 1) != 0)
+	abort ();
+    }
+  else if (__builtin_object_size (r, 1) != 0)
+    abort ();
+#else
   if (__builtin_object_size (r, 1) != sizeof (buf3) - 13)
     abort ();
   if (__builtin_object_size (r + 6, 1) != sizeof (buf3) - 19)
     abort ();
+#endif
 }
 
 void
@@ -339,8 +460,13 @@ test5 (size_t x)
 
   for (i = 0; i < x; ++i)
     p = p + 4;
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (p, 1) != sizeof (t.buf) - 8 - 4 * x)
+    abort ();
+#else
   if (__builtin_object_size (p, 1) != sizeof (t.buf) - 8)
     abort ();
+#endif
   memset (p, ' ', sizeof (t.buf) - 8 - 4 * 4);
 }
 
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-3.c b/gcc/testsuite/gcc.dg/builtin-object-size-3.c
index d5ca5047ee9..9533af9f058 100644
--- a/gcc/testsuite/gcc.dg/builtin-object-size-3.c
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-3.c
@@ -42,9 +42,17 @@ test1 (void *q, int x)
     abort ();
   if (__builtin_object_size (q, 2) != 0)
     abort ();
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (r, 2)
+      != (x < 0
+	  ? sizeof (a) - __builtin_offsetof (struct A, a) - 9
+	  : sizeof (a) - __builtin_offsetof (struct A, c) - 1))
+    abort ();
+#else
   if (__builtin_object_size (r, 2)
       != sizeof (a) - __builtin_offsetof (struct A, c) - 1)
     abort ();
+#endif
   if (x < 6)
     r = &w[2].a[1];
   else
@@ -58,9 +66,17 @@ test1 (void *q, int x)
   if (__builtin_object_size (&y.b, 2)
       != sizeof (a) - __builtin_offsetof (struct A, b))
     abort ();
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (r, 2)
+      != (x < 6
+	  ? 2 * sizeof (w[0]) - __builtin_offsetof (struct A, a) - 1
+	  : sizeof (a) - __builtin_offsetof (struct A, a) - 6))
+    abort ();
+#else
   if (__builtin_object_size (r, 2)
       != sizeof (a) - __builtin_offsetof (struct A, a) - 6)
     abort ();
+#endif
   if (x < 20)
     r = malloc (30);
   else
@@ -71,23 +87,45 @@ test1 (void *q, int x)
     r = malloc (30);
   else
     r = calloc (2, 14);
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (r, 2) != (x < 20 ? 30 : 2 * 14))
+    abort ();
+#else
   if (__builtin_object_size (r, 2) != 2 * 14)
     abort ();
+#endif
   if (x < 30)
     r = malloc (sizeof (a));
   else
     r = &a.a[3];
+#ifdef DYNAMIC_OBJECT_SIZE
+  size_t objsz = (x < 30 ? sizeof (a)
+		  : sizeof (a) - __builtin_offsetof (struct A, a) - 3);
+  if (__builtin_object_size (r, 2) != objsz)
+    abort ();
+#else
   if (__builtin_object_size (r, 2)
       != sizeof (a) - __builtin_offsetof (struct A, a) - 3)
     abort ();
+#endif
   r = memcpy (r, "a", 2);
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (r, 2) != objsz)
+    abort ();
+#else
   if (__builtin_object_size (r, 2)
       != sizeof (a) - __builtin_offsetof (struct A, a) - 3)
     abort ();
+#endif
   r = memcpy (r + 2, "b", 2) + 2;
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (r, 2) != objsz - 4)
+    abort ();
+#else
   if (__builtin_object_size (r, 2)
       != sizeof (a) - __builtin_offsetof (struct A, a) - 3 - 4)
     abort ();
+#endif
   r = &a.a[4];
   r = memset (r, 'a', 2);
   if (__builtin_object_size (r, 2)
@@ -118,12 +156,21 @@ test1 (void *q, int x)
     abort ();
   if (__builtin_object_size (&extb[5], 2) != sizeof (extb) - 5)
     abort ();
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (var, 2) != x + 10)
+    abort ();
+  if (__builtin_object_size (var + 10, 2) != x)
+    abort ();
+  if (__builtin_object_size (&var[5], 2) != x + 5)
+    abort ();
+#else
   if (__builtin_object_size (var, 2) != 0)
     abort ();
   if (__builtin_object_size (var + 10, 2) != 0)
     abort ();
   if (__builtin_object_size (&var[5], 2) != 0)
     abort ();
+#endif
   if (__builtin_object_size (zerol, 2) != 0)
     abort ();
   if (__builtin_object_size (&zerol, 2) != 0)
@@ -164,6 +211,9 @@ test2 (void)
   struct B { char buf1[10]; char buf2[10]; } a;
   char *r, buf3[20];
   int i;
+#ifdef DYNAMIC_OBJECT_SIZE
+  size_t dyn_res;
+#endif
 
   if (sizeof (a) != 20)
     return;
@@ -180,8 +230,26 @@ test2 (void)
       else if (i == l1 + 2)
 	r = &a.buf1[9];
     }
+#ifdef DYNAMIC_OBJECT_SIZE
+  dyn_res = sizeof (buf3);
+
+  for (i = 0; i < 4; ++i)
+    {
+      if (i == l1 - 1)
+	dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf1) - 1;
+      else if (i == l1)
+	dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf2) - 7;
+      else if (i == l1 + 1)
+	dyn_res = sizeof (buf3) - 5;
+      else if (i == l1 + 2)
+	dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf1) - 9;
+    }
+  if (__builtin_object_size (r, 2) != dyn_res)
+    abort ();
+#else
   if (__builtin_object_size (r, 2) != 3)
     abort ();
+#endif
   r = &buf3[20];
   for (i = 0; i < 4; ++i)
     {
@@ -194,8 +262,26 @@ test2 (void)
       else if (i == l1 + 2)
 	r = &a.buf1[9];
     }
+#ifdef DYNAMIC_OBJECT_SIZE
+  dyn_res = sizeof (buf3) - 20;
+
+  for (i = 0; i < 4; ++i)
+    {
+      if (i == l1 - 1)
+	dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf1) - 7;
+      else if (i == l1)
+	dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf2) - 7;
+      else if (i == l1 + 1)
+	dyn_res = sizeof (buf3) - 5;
+      else if (i == l1 + 2)
+	dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf1) - 9;
+    }
+  if (__builtin_object_size (r, 2) != dyn_res)
+    abort ();
+#else
   if (__builtin_object_size (r, 2) != 0)
     abort ();
+#endif
   r = &buf3[2];
   for (i = 0; i < 4; ++i)
     {
@@ -208,13 +294,44 @@ test2 (void)
       else if (i == l1 + 2)
 	r = &a.buf1[4];
     }
+#ifdef DYNAMIC_OBJECT_SIZE
+  dyn_res = sizeof (buf3) - 2;
+
+  for (i = 0; i < 4; ++i)
+    {
+      if (i == l1 - 1)
+	dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf1) - 1;
+      else if (i == l1)
+	dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf1) - 2;
+      else if (i == l1 + 1)
+	dyn_res = sizeof (buf3) - 5;
+      else if (i == l1 + 2)
+	dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf1) - 4;
+    }
+  if (__builtin_object_size (r, 2) != dyn_res)
+    abort ();
+#else
   if (__builtin_object_size (r, 2) != 15)
     abort ();
+#endif
   r += 8;
+#ifdef DYNAMIC_OBJECT_SIZE
+  dyn_res -= 8;
+  if (__builtin_object_size (r, 2) != dyn_res)
+    abort ();
+  if (dyn_res >= 6)
+    {
+      if (__builtin_object_size (r + 6, 2) != dyn_res - 6)
+	abort ();
+    }
+  else if (__builtin_object_size (r + 6, 2) != 0)
+    abort ();
+#else
   if (__builtin_object_size (r, 2) != 7)
     abort ();
   if (__builtin_object_size (r + 6, 2) != 1)
     abort ();
+#endif
   r = &buf3[18];
   for (i = 0; i < 4; ++i)
     {
@@ -227,8 +344,31 @@ test2 (void)
       else if (i == l1 + 2)
 	r = &a.buf1[4];
     }
+#ifdef DYNAMIC_OBJECT_SIZE
+  dyn_res = sizeof (buf3) - 18;
+
+  for (i = 0; i < 4; ++i)
+    {
+      if (i == l1 - 1)
+	  dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf1) - 9;
+      else if (i == l1)
+	dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf2) - 9;
+      else if (i == l1 + 1)
+	dyn_res = sizeof (buf3) - 5;
+      else if (i == l1 + 2)
+	dyn_res = sizeof (a) - __builtin_offsetof (struct B, buf1) - 4;
+    }
+  if (dyn_res >= 12)
+    {
+      if (__builtin_object_size (r + 12, 2) != dyn_res - 12)
+	abort ();
+    }
+  else if (__builtin_object_size (r + 12, 2) != 0)
+    abort ();
+#else
   if (__builtin_object_size (r + 12, 2) != 0)
     abort ();
+#endif
 }
 
 void
@@ -371,7 +511,11 @@ test5 (size_t x)
 
   for (i = 0; i < x; ++i)
     p = p + 4;
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (p, 2) != sizeof (buf) - 8 - 4 * x)
+#else
   if (__builtin_object_size (p, 2) != 0)
+#endif
     abort ();
   memset (p, ' ', sizeof (buf) - 8 - 4 * 4);
 }
@@ -386,7 +530,11 @@ test6 (size_t x)
 
   for (i = 0; i < x; ++i)
     p = p + 4;
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (p, 2) != sizeof (t) - 8 - 4 * x)
+#else
   if (__builtin_object_size (p, 2) != 0)
+#endif
     abort ();
   memset (p, ' ', sizeof (t) - 8 - 4 * 4);
 }
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-4.c b/gcc/testsuite/gcc.dg/builtin-object-size-4.c
index 9f159e36a0f..256cea0b3fb 100644
--- a/gcc/testsuite/gcc.dg/builtin-object-size-4.c
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-4.c
@@ -43,7 +43,12 @@ test1 (void *q, int x)
     abort ();
   if (__builtin_object_size (q, 3) != 0)
     abort ();
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (r, 3)
+      != (x < 0 ? sizeof (a.a) - 9 : sizeof (a.c) - 1))
+#else
   if (__builtin_object_size (r, 3) != sizeof (a.a) - 9)
+#endif
     abort ();
   if (x < 6)
     r = &w[2].a[1];
@@ -55,31 +60,57 @@ test1 (void *q, int x)
     abort ();
   if (__builtin_object_size (&y.b, 3) != sizeof (a.b))
     abort ();
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (r, 3)
+      != (x < 6 ? sizeof (w[2].a) - 1 : sizeof (a.a) - 6))
+#else
   if (__builtin_object_size (r, 3) != sizeof (a.a) - 6)
+#endif
     abort ();
   if (x < 20)
     r = malloc (30);
   else
     r = calloc (2, 16);
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (r, 3) != (x < 20 ? 30 : 2 * 16))
+#else
   if (__builtin_object_size (r, 3) != 30)
+#endif
     abort ();
   if (x < 20)
     r = malloc (30);
   else
     r = calloc (2, 14);
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (r, 3) != (x < 20 ? 30 : 2 * 14))
+#else
   if (__builtin_object_size (r, 3) != 2 * 14)
+#endif
     abort ();
   if (x < 30)
     r = malloc (sizeof (a));
   else
     r = &a.a[3];
+#ifdef DYNAMIC_OBJECT_SIZE
+  size_t objsz = x < 30 ? sizeof (a) : sizeof (a.a) - 3;
+  if (__builtin_object_size (r, 3) != objsz)
+#else
   if (__builtin_object_size (r, 3) != sizeof (a.a) - 3)
+#endif
     abort ();
   r = memcpy (r, "a", 2);
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (r, 3) != objsz)
+#else
   if (__builtin_object_size (r, 3) != sizeof (a.a) - 3)
+#endif
     abort ();
   r = memcpy (r + 2, "b", 2) + 2;
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (r, 3) != objsz - 4)
+#else
   if (__builtin_object_size (r, 3) != sizeof (a.a) - 3 - 4)
+#endif
     abort ();
   r = &a.a[4];
   r = memset (r, 'a', 2);
@@ -119,6 +150,23 @@ test1 (void *q, int x)
     abort ();
   if (__builtin_object_size (&extc[5].c[3], 3) != 0)
     abort ();
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (var, 3) != x + 10)
+    abort ();
+  if (__builtin_object_size (var + 10, 3) != x)
+    abort ();
+  if (__builtin_object_size (&var[5], 3) != x + 5)
+    abort ();
+  size_t vara_sz = (x + 10) * sizeof (struct A);
+  if (__builtin_object_size (vara, 3) != vara_sz)
+    abort ();
+  vara_sz = x * sizeof (struct A);
+  if (__builtin_object_size (vara + 10, 3) != vara_sz)
+    abort ();    
+  vara_sz = (x + 5) * sizeof (struct A);
+  if (__builtin_object_size (&vara[5], 3) != vara_sz)
+    abort ();
+#else
   if (__builtin_object_size (var, 3) != 0)
     abort ();
   if (__builtin_object_size (var + 10, 3) != 0)
@@ -131,6 +179,7 @@ test1 (void *q, int x)
     abort ();    
   if (__builtin_object_size (&vara[5], 3) != 0)
     abort ();
+#endif
   if (__builtin_object_size (&vara[0].a, 3) != sizeof (vara[0].a))
     abort ();
   if (__builtin_object_size (&vara[10].a[0], 3) != sizeof (vara[0].a))
@@ -184,6 +233,9 @@ test2 (void)
   struct B { char buf1[10]; char buf2[10]; } a;
   char *r, buf3[20];
   int i;
+#ifdef DYNAMIC_OBJECT_SIZE
+  size_t dyn_res = 0;
+#endif
 
   if (sizeof (a) != 20)
     return;
@@ -200,8 +252,26 @@ test2 (void)
       else if (i == l1 + 2)
 	r = &a.buf1[9];
     }
+#ifdef DYNAMIC_OBJECT_SIZE
+  dyn_res = sizeof (buf3);
+
+  for (i = 0; i < 4; ++i)
+    {
+      if (i == l1 - 1)
+	dyn_res = sizeof (a.buf1) - 1;
+      else if (i == l1)
+	dyn_res = sizeof (a.buf2) - 7;
+      else if (i == l1 + 1)
+	dyn_res = sizeof (buf3) - 5;
+      else if (i == l1 + 2)
+	dyn_res = sizeof (a.buf1) - 9;
+    }
+  if (__builtin_object_size (r, 3) != dyn_res)
+    abort ();
+#else
   if (__builtin_object_size (r, 3) != sizeof (a.buf1) - 9)
     abort ();
+#endif
   r = &buf3[20];
   for (i = 0; i < 4; ++i)
     {
@@ -214,8 +284,26 @@ test2 (void)
       else if (i == l1 + 2)
 	r = &a.buf1[9];
     }
+#ifdef DYNAMIC_OBJECT_SIZE
+  dyn_res = sizeof (buf3) - 20;
+
+  for (i = 0; i < 4; ++i)
+    {
+      if (i == l1 - 1)
+	dyn_res = sizeof (a.buf1) - 7;
+      else if (i == l1)
+	dyn_res = sizeof (a.buf2) - 7;
+      else if (i == l1 + 1)
+	dyn_res = sizeof (buf3) - 5;
+      else if (i == l1 + 2)
+	dyn_res = sizeof (a.buf1) - 9;
+    }
+  if (__builtin_object_size (r, 3) != dyn_res)
+    abort ();
+#else
   if (__builtin_object_size (r, 3) != 0)
     abort ();
+#endif
   r = &buf3[1];
   for (i = 0; i < 4; ++i)
     {
@@ -228,13 +316,38 @@ test2 (void)
       else if (i == l1 + 2)
 	r = &a.buf1[2];
     }
+#ifdef DYNAMIC_OBJECT_SIZE
+  dyn_res = sizeof (buf3) - 1;
+
+  for (i = 0; i < 4; ++i)
+    {
+      if (i == l1 - 1)
+	dyn_res = sizeof (a.buf1) - 6;
+      else if (i == l1)
+	dyn_res = sizeof (a.buf2) - 4;
+      else if (i == l1 + 1)
+	dyn_res = sizeof (buf3) - 5;
+      else if (i == l1 + 2)
+	dyn_res = sizeof (a.buf1) - 2;
+    }
+  if (__builtin_object_size (r, 3) != dyn_res)
+    abort ();
+#else
   if (__builtin_object_size (r, 3) != sizeof (a.buf1) - 6)
     abort ();
+#endif
   r += 2;
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (r, 3) != dyn_res - 2)
+    abort ();
+  if (__builtin_object_size (r + 1, 3) != dyn_res - 3)
+    abort ();
+#else
   if (__builtin_object_size (r, 3) != sizeof (a.buf1) - 6 - 2)
     abort ();
   if (__builtin_object_size (r + 1, 3) != sizeof (a.buf1) - 6 - 3)
     abort ();
+#endif
 }
 
 void
@@ -352,7 +465,11 @@ test5 (size_t x)
 
   for (i = 0; i < x; ++i)
     p = p + 4;
+#ifdef DYNAMIC_OBJECT_SIZE
+  if (__builtin_object_size (p, 3) != sizeof (t.buf) - 8 - 4 * x)
+#else
   if (__builtin_object_size (p, 3) != 0)
+#endif
     abort ();
   memset (p, ' ', sizeof (t.buf) - 8 - 4 * 4);
 }
