brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.3 KiB · 5d62218 Raw
270 lines · cpp
1// RUN: %clang_cc1 -std=c++14 -fexperimental-new-constant-interpreter -verify=expected,both %s2// RUN: %clang_cc1 -std=c++23 -fexperimental-new-constant-interpreter -verify=expected,both %s3// RUN: %clang_cc1 -std=c++14 -verify=ref,both %s4// RUN: %clang_cc1 -std=c++23 -verify=ref,both %s5 6namespace MemberPointers {7  struct A {8    constexpr A(int n) : n(n) {}9    int n;10    constexpr int f() const { return n + 3; }11  };12 13  constexpr A a(7);14  static_assert(A(5).*&A::n == 5, "");15  static_assert((&a)->*&A::n == 7, "");16  static_assert((A(8).*&A::f)() == 11, "");17  static_assert(((&a)->*&A::f)() == 10, "");18 19  struct B : A {20    constexpr B(int n, int m) : A(n), m(m) {}21    int m;22    constexpr int g() const { return n + m + 1; }23  };24  constexpr B b(9, 13);25  static_assert(B(4, 11).*&A::n == 4, "");26  static_assert(B(4, 11).*&B::m == 11, "");27  static_assert(B(4, 11).m == 11, "");28  static_assert(B(4, 11).*(int(A::*))&B::m == 11, "");29  static_assert(B(4, 11).*&B::m == 11, "");30  static_assert((&b)->*&A::n == 9, "");31  static_assert((&b)->*&B::m == 13, "");32  static_assert((&b)->*(int(A::*))&B::m == 13, "");33  static_assert((B(4, 11).*&A::f)() == 7, "");34  static_assert((B(4, 11).*&B::g)() == 16, "");35 36  static_assert((B(4, 11).*(int(A::*)() const)&B::g)() == 16, "");37 38  static_assert(((&b)->*&A::f)() == 12, "");39  static_assert(((&b)->*&B::g)() == 23, "");40  static_assert(((&b)->*(int(A::*)()const)&B::g)() == 23, "");41 42 43  struct S {44    constexpr S(int m, int n, int (S::*pf)() const, int S::*pn) :45      m(m), n(n), pf(pf), pn(pn) {}46    constexpr S() : m(), n(), pf(&S::f), pn(&S::n) {}47 48    constexpr int f() const { return this->*pn; }49    virtual int g() const;50 51    int m, n;52    int (S::*pf)() const;53    int S::*pn;54  };55 56  constexpr int S::*pm = &S::m;57  constexpr int S::*pn = &S::n;58 59  constexpr int (S::*pf)() const = &S::f;60  constexpr int (S::*pg)() const = &S::g;61 62  constexpr S s(2, 5, &S::f, &S::m);63 64  static_assert((s.*&S::f)() == 2, "");65  static_assert((s.*s.pf)() == 2, "");66 67  static_assert(pf == &S::f, "");68 69  static_assert(pf == s.*&S::pf, "");70 71  static_assert(pm == &S::m, "");72  static_assert(pm != pn, "");73  static_assert(s.pn != pn, "");74  static_assert(s.pn == pm, "");75  static_assert(pg != nullptr, "");76  static_assert(pf != nullptr, "");77  static_assert((int S::*)nullptr == nullptr, "");78  static_assert(pg == pg, ""); // both-error {{constant expression}} \79                               // both-note {{comparison of pointer to virtual member function 'g' has unspecified value}}80  static_assert(pf != pg, ""); // both-error {{constant expression}} \81                               // both-note {{comparison of pointer to virtual member function 'g' has unspecified value}}82 83  template<int n> struct T : T<n-1> { const int X = n;};84  template<> struct T<0> { int n; char k;};85  template<> struct T<30> : T<29> { int m; };86 87  T<17> t17;88  T<30> t30;89 90  constexpr int (T<15>::*deepm) = (int(T<10>::*))&T<30>::m;91  constexpr int (T<10>::*deepn) = &T<0>::n;92  constexpr char (T<10>::*deepk) = &T<0>::k;93 94  static_assert(&(t17.*deepn) == &t17.n, "");95  static_assert(&(t17.*deepk) == &t17.k, "");96  static_assert(deepn == &T<2>::n, "");97 98  constexpr int *pgood = &(t30.*deepm);99  constexpr int *pbad = &(t17.*deepm); // both-error {{constant expression}}100  static_assert(&(t30.*deepm) == &t30.m, "");101 102  static_assert(deepm == &T<50>::m, "");103  static_assert(deepm != deepn, "");104 105  constexpr T<5> *p17_5 = &t17;106  constexpr T<13> *p17_13 = (T<13>*)p17_5;107  constexpr T<23> *p17_23 = (T<23>*)p17_13; // both-error {{constant expression}} \108                                            // both-note {{cannot cast object of dynamic type 'T<17>' to type 'T<23>'}}109  constexpr T<18> *p17_18 = (T<18>*)p17_13; // both-error {{constant expression}} \110                                            // both-note {{cannot cast object of dynamic type 'T<17>' to type 'T<18>'}}111  static_assert(&(p17_5->*(int(T<0>::*))deepn) == &t17.n, "");112  static_assert(&(p17_5->*(int(T<0>::*))deepn), "");113 114 115  static_assert(&(p17_13->*deepn) == &t17.n, "");116  constexpr int *pbad2 = &(p17_13->*(int(T<9>::*))deepm); // both-error {{constant expression}}117 118  constexpr T<5> *p30_5 = &t30;119  constexpr T<23> *p30_23 = (T<23>*)p30_5;120  constexpr T<13> *p30_13 = p30_23;121  static_assert(&(p30_13->*deepn) == &t30.n, "");122  static_assert(&(p30_23->*deepn) == &t30.n, "");123  static_assert(&(p30_5->*(int(T<3>::*))deepn) == &t30.n, "");124 125  static_assert(&(p30_5->*(int(T<2>::*))deepm) == &t30.m, "");126  static_assert(&(((T<17>*)p30_13)->*deepm) == &t30.m, "");127  static_assert(&(p30_23->*deepm) == &t30.m, "");128 129 130  /// Added tests not from constant-expression-cxx11.cpp131  static_assert(pm, "");132  static_assert(!((int S::*)nullptr), "");133  constexpr int S::*pk = nullptr;134  static_assert(!pk, "");135}136 137namespace test3 {138  struct nsCSSRect {139  };140  static int nsCSSRect::* sides;141  nsCSSRect dimenX;142  void ParseBoxCornerRadii(int y) {143    switch (y) {144    }145    int& x = dimenX.*sides;146  }147}148 149void foo() {150  class X;151  void (X::*d) ();152  d = nullptr; /// This calls in the constant interpreter.153}154 155namespace {156  struct A { int n; };157  struct B { int n; };158  struct C : A, B {};159  struct D { double d; C c; };160  const int &&u = static_cast<B&&>(0, ((D&&)D{}).*&D::c).n; // both-warning {{left operand of comma operator has no effect}}161}162 163/// From SemaTemplate/instantiate-member-pointers.cpp164namespace {165  struct Y {166    int x;167  };168 169  template<typename T, typename Class, T Class::*Ptr>170  struct X3 {171    X3<T, Class, Ptr> &operator=(const T& value) {172      return *this;173    }174  };175 176  typedef int Y::*IntMember;177  template<IntMember Member>178  struct X4 {179    X3<int, Y, Member> member;180    int &getMember(Y& y) { return y.*Member; }181  };182 183  int &get_X4(X4<&Y::x> x4, Y& y) {184    return x4.getMember(y);185  }186}187 188/// From test/CXX/basic/basic.def.odr/p2.cpp189namespace {190  void use(int);191  struct S { int x; int f() const; };192  constexpr S *ps = nullptr;193  S *const &psr = ps;194 195  void test() {196    use(ps->*&S::x);197    use(psr->*&S::x);198  }199}200 201namespace MemPtrTemporary {202  struct A {203    constexpr int f() const { return 5; }204  };205 206  constexpr int apply(const A &a, int (A::*ff)() const) {207    return (a.*ff)();208  }209 210  static_assert(apply(A(), &A::f) == 5, "");211}212 213namespace IndirectFields {214  struct I { union { struct { int a, b; }; }; };215 216  template <typename T, int T::*F>217  constexpr int ReadField(const T &o) {218    return F ? o.*F : 0;219  }220  void ReadFields() {221    I i;222    ReadField<I, &I::a>(i);223    ReadField<I, &I::b>(i);224  }225 226  constexpr I i{12};227  static_assert(ReadField<I, &I::a>(i) == 12, "");228}229 230namespace CallExprTypeMismatch {231  /// The call expression's getType() returns just S, not S&.232  struct S {233    constexpr S(int i_) : i(i_) {}234    constexpr const S& identity() const { return *this; }235    int i;236  };237 238  template<typename T, typename U>239  constexpr void Call(T t, U u) {240    ((&u)->*t)();241  }242 243  constexpr bool test() {244    const S s{12};245 246    Call(&S::identity, s);247 248    return true;249  }250  static_assert(test(), "");251}252 253namespace CastMemberPtrPtrFailed{254  struct S {255    constexpr S() {}256    constexpr int f() const;257    constexpr int g() const;258  };259  struct T : S {260    constexpr T(int n) : S(), n(n) {}261    int n;262  };263 264  constexpr int S::g() const {265    return this->*(int(S::*))&T::n; // both-note {{subexpression}}266  }267  static_assert(S().g(), ""); // both-error {{constant expression}} \268                              // both-note {{in call to 'S().g()'}}269}270