1 // Verify that -fsanitize=vptr downcast instrumentation works properly
2 // inside of constexpr.
3 // { dg-do compile }
4 // { dg-options "-std=c++11 -fsanitize=vptr" }
5 
6 struct S {
SS7   constexpr S() : a(0) {}
8   int a;
fS9   int f() { return 0; }
vS10   virtual int v() { return 0; }
11 };
12 
13 struct T : S {
TT14   constexpr T() : b(0) {}
15   int b;
gT16   int g() { return 0; }
vT17   virtual int v() { return 1; }
fooT18   constexpr const T *foo() { return (const T *) reinterpret_cast<const S *> (this); } // { dg-error "is not a constant expression" }
19 };
20 
21 constexpr T t;
22 constexpr const T *p = t.foo ();	// { dg-error "called in a constant expression" }
23 
24 template <typename U>
25 struct V {
VV26   constexpr V() : a(0) {}
27   int a;
fV28   int f() { return 0; }
vV29   virtual int v() { return 0; }
30 };
31 
32 template <typename U>
33 struct W : V<U> {
WW34   constexpr W() : b(0) {}
35   int b;
gW36   int g() { return 0; }
vW37   virtual int v() { return 1; }
fooW38   constexpr const W<U> *foo() { return (const W<U> *) reinterpret_cast<const V<U> *> (this); } // { dg-error "is not a constant expression" }
39 };
40 
41 constexpr W<int> w;
42 constexpr const W<int> *s = w.foo ();	// { dg-error "called in a constant expression" }
43 
44 template <typename U>
foo(void)45 int foo (void)
46 {
47   static constexpr T t;
48   static constexpr const T *p = t.foo ();	// { dg-error "called in a constant expression" }
49   static constexpr W<U> w;
50   static constexpr const W<U> *s = w.foo ();	// { dg-error "called in a constant expression" }
51   return t.b + w.b;
52 }
53 
54 int x = foo <char> ();
55