Hi!

If va_list is one-entry array of structs, those RECORD_TYPEs don't
have TYPE_BINFO.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

I've made the testcase compile instead of run, because while it with the
patch works both on x86_64-linux and i686-linux, not sure if it really
should be well defined - at least in C one can copy va_list only through
va_copy, by throwing it and catching it is copied in some other way.

2016-08-08  Jakub Jelinek  <ja...@redhat.com>

        PR c++/72809
        * rtti.c (get_pseudo_ti_index): Return TK_CLASS_TYPE for
        builtin aggregate types without TYPE_BINFO.

        * g++.dg/eh/stdarg1.C: New test.

--- gcc/cp/rtti.c.jj    2016-04-22 18:21:27.000000000 +0200
+++ gcc/cp/rtti.c       2016-08-08 16:21:32.937053462 +0200
@@ -1293,7 +1293,8 @@ get_pseudo_ti_index (tree type)
          ix = TK_CLASS_TYPE;
          break;
        }
-      else if (!BINFO_N_BASE_BINFOS (TYPE_BINFO (type)))
+      else if (!TYPE_BINFO (type)
+              || !BINFO_N_BASE_BINFOS (TYPE_BINFO (type)))
        {
          ix = TK_CLASS_TYPE;
          break;
--- gcc/testsuite/g++.dg/eh/stdarg1.C.jj        2016-08-08 16:31:52.553510463 
+0200
+++ gcc/testsuite/g++.dg/eh/stdarg1.C   2016-08-08 16:30:20.000000000 +0200
@@ -0,0 +1,30 @@
+// PR c++/72809
+// { dg-do compile }
+
+#include <stdarg.h>
+
+int
+foo (int a, ...)
+{
+  va_list ap;
+  int r = 0;
+  va_start (ap, a);
+  try
+    {
+      if (a == 1)
+       throw (ap);
+    }
+  catch (va_list b)
+    {
+      r = va_arg (b, int);
+    }
+  va_end (ap);
+  return r;
+}
+
+int
+main ()
+{
+  if (foo (0) != 0 || foo (1, 7) != 7)
+    __builtin_abort ();
+}

        Jakub

Reply via email to