1a07aba5dSTimm Baeder // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=ref,both %s 2a07aba5dSTimm Baeder // RUN: %clang_cc1 -std=c++20 -fexperimental-new-constant-interpreter -fsyntax-only -verify=expected,both %s 3a07aba5dSTimm Baeder 4a07aba5dSTimm Baeder 5a07aba5dSTimm Baeder struct Foo { 6a07aba5dSTimm Baeder constexpr void zomg() const { (void)(1 / 0); } // both-error {{constant expression}} \ 7a07aba5dSTimm Baeder both-warning {{division by zero}} \ 8a07aba5dSTimm Baeder both-note 2{{division by zero}} 9a07aba5dSTimm Baeder }; 10a07aba5dSTimm Baeder 11a07aba5dSTimm Baeder struct S { 12a07aba5dSTimm Baeder constexpr S() {} 13a07aba5dSTimm Baeder constexpr bool operator==(const S&) const { // both-error {{never produces a constant expression}} 14a07aba5dSTimm Baeder return 1 / 0; // both-warning {{division by zero}} \ 15a07aba5dSTimm Baeder both-note 3{{division by zero}} 16a07aba5dSTimm Baeder } 17a07aba5dSTimm Baeder 18a07aba5dSTimm Baeder constexpr bool heh() const { 19a07aba5dSTimm Baeder auto F = new Foo(); 20a07aba5dSTimm Baeder F->zomg(); // both-note {{in call to 'F->zomg()'}} 21a07aba5dSTimm Baeder delete F; 22a07aba5dSTimm Baeder return false; 23a07aba5dSTimm Baeder } 24a07aba5dSTimm Baeder }; 25a07aba5dSTimm Baeder 26a07aba5dSTimm Baeder constexpr S s; 27a07aba5dSTimm Baeder 28a07aba5dSTimm Baeder static_assert(s.heh()); // both-error {{constant expression}} \ 29a07aba5dSTimm Baeder both-note {{in call to 's.heh()'}} 30a07aba5dSTimm Baeder 31a07aba5dSTimm Baeder constexpr S s2; 32a07aba5dSTimm Baeder constexpr const S *sptr = &s; 33a07aba5dSTimm Baeder constexpr const S *sptr2 = &s2; 34a07aba5dSTimm Baeder static_assert(s == s2); // both-error {{constant expression}} \ 35a07aba5dSTimm Baeder both-note {{in call to 's.operator==(s2)'}} 36a07aba5dSTimm Baeder static_assert(*sptr == *sptr2); // both-error {{constant expression}} \ 37a07aba5dSTimm Baeder both-note {{in call to '*sptr.operator==(s2)'}} 38a07aba5dSTimm Baeder 39a07aba5dSTimm Baeder struct A { 40a07aba5dSTimm Baeder constexpr int foo() { (void)(1/0); return 1;} // both-error {{never produces a constant expression}} \ 41a07aba5dSTimm Baeder both-warning {{division by zero}} \ 42a07aba5dSTimm Baeder both-note 2{{division by zero}} 43a07aba5dSTimm Baeder }; 44a07aba5dSTimm Baeder 45a07aba5dSTimm Baeder struct B { 46a07aba5dSTimm Baeder A aa; 47a07aba5dSTimm Baeder A *a = &aa; 48a07aba5dSTimm Baeder }; 49a07aba5dSTimm Baeder 50a07aba5dSTimm Baeder struct C { 51a07aba5dSTimm Baeder B b; 52a07aba5dSTimm Baeder }; 53a07aba5dSTimm Baeder 54a07aba5dSTimm Baeder struct D { 55a07aba5dSTimm Baeder C cc; 56a07aba5dSTimm Baeder C *c = &cc; 57a07aba5dSTimm Baeder }; 58a07aba5dSTimm Baeder 59a07aba5dSTimm Baeder constexpr D d{}; 60a07aba5dSTimm Baeder static_assert(d.c->b.a->foo() == 1); // both-error {{constant expression}} \ 61a07aba5dSTimm Baeder both-note {{in call to 'd.c->b.a->foo()'}} 62a07aba5dSTimm Baeder 63a07aba5dSTimm Baeder template <typename T> 64a07aba5dSTimm Baeder struct Bar { 65a07aba5dSTimm Baeder template <typename U> 66a07aba5dSTimm Baeder constexpr int fail1() const { return 1 / 0; } // both-warning {{division by zero}} \ 67a07aba5dSTimm Baeder // both-note {{division by zero}} 68a07aba5dSTimm Baeder template <typename U, int num> 69a07aba5dSTimm Baeder constexpr int fail2() const { return 1 / 0; } // both-warning {{division by zero}} \ 70a07aba5dSTimm Baeder // both-note {{division by zero}} 71a07aba5dSTimm Baeder template <typename ...Args> 72a07aba5dSTimm Baeder constexpr int fail3(Args... args) const { return 1 / 0; } // both-warning {{division by zero}} \ 73a07aba5dSTimm Baeder // both-note {{division by zero}} 74a07aba5dSTimm Baeder }; 75a07aba5dSTimm Baeder 76a07aba5dSTimm Baeder constexpr Bar<int> bar; 77a07aba5dSTimm Baeder static_assert(bar.fail1<int>()); // both-error {{constant expression}} \ 78a07aba5dSTimm Baeder // both-note {{in call to 'bar.fail1<int>()'}} 79a07aba5dSTimm Baeder static_assert(bar.fail2<int*, 42>()); // both-error {{constant expression}} \ 80a07aba5dSTimm Baeder // both-note {{in call to 'bar.fail2<int *, 42>()'}} 81a07aba5dSTimm Baeder static_assert(bar.fail3(3, 4UL, bar, &bar)); // both-error {{constant expression}} \ 82a07aba5dSTimm Baeder // expected-note {{in call to 'bar.fail3<int, unsigned long, Bar<int>, const Bar<int> *>(3, 4, &bar, &bar)'}} \ 83a07aba5dSTimm Baeder // ref-note {{in call to 'bar.fail3<int, unsigned long, Bar<int>, const Bar<int> *>(3, 4, {}, &bar)'}} 84a07aba5dSTimm Baeder 85a07aba5dSTimm Baeder 86a07aba5dSTimm Baeder 87a07aba5dSTimm Baeder struct MemPtrTest { 88a07aba5dSTimm Baeder int n; 89a07aba5dSTimm Baeder void f(); 90a07aba5dSTimm Baeder }; 91a07aba5dSTimm Baeder MemPtrTest mpt; // both-note {{here}} 92a07aba5dSTimm Baeder constexpr int MemPtr(int (MemPtrTest::*a), void (MemPtrTest::*b)(), int &c) { 93a07aba5dSTimm Baeder return c; // both-note {{read of non-constexpr variable 'mpt'}} 94a07aba5dSTimm Baeder } 95a07aba5dSTimm Baeder static_assert(MemPtr(&MemPtrTest::n, &MemPtrTest::f, mpt.*&MemPtrTest::n), ""); // both-error {{constant expression}} \ 96*733a92d7STimm Baeder // both-note {{in call to 'MemPtr(&MemPtrTest::n, &MemPtrTest::f, mpt.n)'}} 97