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