+// { dg-do run }
+// { dg-require-alias "" }
+// { dg-options "-fno-strict-aliasing" }
// Origin: Mark Mitchell <mark@codesourcery.com>
#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
// These are tricks to allow us to get raw function pointers for
// member functions.
extern "C" {
-void s3__2S3 ();
-void s1__2S4 ();
+ void S3_s3 () __attribute__((__alias__ ("_ZN2S32s3Ev")));
+ void S4_s1 () __attribute__((__alias__ ("_ZN2S42s1Ev")));
}
+// IA-64 uses function descriptors not function pointers in its vtables.
+#if defined __ia64__
+#define CMP_VPTR(A, B) (*(void **)(A) == *(void **)(B))
+#ifdef _LP64
+#define INC_VPTR(A) ((A) += 2)
+#define INC_VDATA(A,N) ((A) += (N))
+#else
+#define INC_VPTR(A) ((A) += 4)
+#define INC_VDATA(A,N) ((A) += 2*(N))
+#endif
+#else
+#define CMP_VPTR(A, B) (*(A) == (ptrdiff_t)(B))
+#define INC_VPTR(A) ((A) += 1)
+#define INC_VDATA(A,N) ((A) += (N))
+#endif
+
int main ()
{
S4 s4;
// Set vtbl to point at the beginning of S4's primary vtable.
vptr = (ptrdiff_t **) &s4;
vtbl = *vptr;
- vtbl -= 5;
+ INC_VDATA (vtbl, -5);
- if (*vtbl++ != ((char*) (S0*) &s4) - (char*) &s4)
+ if (*vtbl != ((char*) (S0*) &s4) - (char*) &s4)
return 1;
- if (*vtbl++ != ((char*) (S1*) &s4) - (char*) &s4)
+ INC_VDATA (vtbl, 1);
+ if (*vtbl != ((char*) (S1*) &s4) - (char*) &s4)
return 2;
- if (*vtbl++ != ((char*) (S2*) &s4) - (char*) &s4)
+ INC_VDATA (vtbl, 1);
+ if (*vtbl != ((char*) (S2*) &s4) - (char*) &s4)
return 3;
- if (*vtbl++ != 0)
+ INC_VDATA (vtbl, 1);
+ if (*vtbl != 0)
return 4;
+ INC_VDATA (vtbl, 1);
// Skip the RTTI entry.
- vtbl++;
- if (*vtbl++ != (ptrdiff_t) &s3__2S3)
+ INC_VDATA (vtbl, 1);
+ if (! CMP_VPTR (vtbl, &S3_s3))
return 5;
- if (*vtbl++ != (ptrdiff_t) &s1__2S4)
+ INC_VPTR (vtbl);
+ if (! CMP_VPTR (vtbl, &S4_s1))
return 6;
+ INC_VPTR (vtbl);
// The S1 vbase offset.
- if (*vtbl++ != 0)
+ if (*vtbl != 0)
return 7;
+ INC_VDATA (vtbl, 1);
// The S4::s1 vcall offset is negative; once you convert to S2, you
// have to convert to S4 to find the final overrider.
- if (*vtbl++ != ((char*) &s4 - (char*) (S2*) &s4))
+ if (*vtbl != ((char*) &s4 - (char*) (S2*) &s4))
return 8;
- if (*vtbl++ != 0)
+ INC_VDATA (vtbl, 1);
+ if (*vtbl != 0)
return 9;
- if (*vtbl++ != 0)
+ INC_VDATA (vtbl, 1);
+ if (*vtbl != 0)
return 10;
+ INC_VDATA (vtbl, 1);
// Now we're at the S2 offset to top entry.
- if (*vtbl++ != ((char*) &s4 - (char*) (S2*) &s4))
+ if (*vtbl != ((char*) &s4 - (char*) (S2*) &s4))
return 11;
+ INC_VDATA (vtbl, 1);
// Skip the RTTI entry.
- vtbl++;
+ INC_VDATA (vtbl, 1);
// Skip the remaining virtual functions -- they are thunks.
- vtbl++;
- vtbl++;
+ INC_VPTR (vtbl);
+ INC_VPTR (vtbl);
}
#else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */