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); } 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)45int 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