xref: /llvm-project/clang/test/AST/ByteCode/cxx20.cpp (revision 7075eee6bd0d445aa3f58ace314f7d12756c3e38)
1 // RUN: %clang_cc1 -fcxx-exceptions -fexperimental-new-constant-interpreter -std=c++20 -verify=both,expected -fcxx-exceptions %s
2 // RUN: %clang_cc1 -fcxx-exceptions -std=c++20 -verify=both,ref -fcxx-exceptions %s
3 
4 void test_alignas_operand() {
5   alignas(8) char dummy;
6   static_assert(__alignof(dummy) == 8);
7 }
8 
9 constexpr int getMinus5() {
10   int a = 10;
11   a = -5;
12   int *p = &a;
13   return *p;
14 }
15 static_assert(getMinus5() == -5, "");
16 
17 constexpr int assign() {
18   int m = 10;
19   int k = 12;
20 
21   m = (k = 20);
22 
23   return m;
24 }
25 static_assert(assign() == 20, "");
26 
27 
28 constexpr int pointerAssign() {
29   int m = 10;
30   int *p = &m;
31 
32   *p = 12; // modifies m
33 
34   return m;
35 }
36 static_assert(pointerAssign() == 12, "");
37 
38 constexpr int pointerDeref() {
39   int m = 12;
40   int *p = &m;
41 
42   return *p;
43 }
44 static_assert(pointerDeref() == 12, "");
45 
46 constexpr int pointerAssign2() {
47   int m = 10;
48   int *p = &m;
49   int **pp = &p;
50 
51   **pp = 12;
52 
53   int v = **pp;
54 
55   return v;
56 }
57 static_assert(pointerAssign2() == 12, "");
58 
59 constexpr int unInitLocal() {
60   int a;
61   return a; // both-note {{read of uninitialized object}}
62 }
63 static_assert(unInitLocal() == 0, ""); // both-error {{not an integral constant expression}} \
64                                        // both-note {{in call to 'unInitLocal()'}}
65 
66 constexpr int initializedLocal() {
67   int a;
68   a = 20;
69   return a;
70 }
71 static_assert(initializedLocal() == 20);
72 
73 constexpr int initializedLocal2() {
74   int a[2];
75   return *a; // both-note {{read of uninitialized object is not allowed in a constant expression}}
76 }
77 static_assert(initializedLocal2() == 20); // both-error {{not an integral constant expression}} \
78                                           // both-note {{in call to}}
79 
80 
81 struct Int { int a; };
82 constexpr int initializedLocal3() {
83   Int i;
84   return i.a; // both-note {{read of uninitialized object is not allowed in a constant expression}}
85 }
86 static_assert(initializedLocal3() == 20); // both-error {{not an integral constant expression}} \
87                                           // both-note {{in call to}}
88 
89 
90 
91 #if 0
92 // FIXME: This code should be rejected because we pass an uninitialized value
93 //   as a function parameter.
94 constexpr int inc(int a) { return a + 1; }
95 constexpr int f() {
96     int i;
97     return inc(i);
98 }
99 static_assert(f());
100 #endif
101 
102 /// Distinct literals have distinct addresses.
103 /// see https://github.com/llvm/llvm-project/issues/58754
104 constexpr auto foo(const char *p) { return p; }
105 constexpr auto p1 = "test1";
106 constexpr auto p2 = "test2";
107 
108 constexpr bool b1 = foo(p1) == foo(p1);
109 static_assert(b1);
110 
111 constexpr bool b2 = foo(p1) == foo(p2);
112 static_assert(!b2);
113 
114 constexpr auto name1() { return "name1"; }
115 constexpr auto name2() { return "name2"; }
116 
117 constexpr auto b3 = name1() == name1(); // ref-error {{must be initialized by a constant expression}} \
118                                         // ref-note {{comparison of addresses of potentially overlapping literals}}
119 constexpr auto b4 = name1() == name2();
120 static_assert(!b4);
121 
122 namespace UninitializedFields {
123   class A {
124   public:
125     int a; // both-note 4{{subobject declared here}}
126     constexpr A() {}
127   };
128   constexpr A a; // both-error {{must be initialized by a constant expression}} \
129                  // both-note {{subobject 'a' is not initialized}}
130   constexpr A aarr[2]; // both-error {{must be initialized by a constant expression}} \
131                        // both-note {{subobject 'a' is not initialized}}
132   class F {
133     public:
134       int f; // both-note 3{{subobject declared here}}
135 
136       constexpr F() {}
137       constexpr F(bool b) {
138         if (b)
139           f = 42;
140       }
141   };
142 
143   constexpr F foo[2] = {true}; // both-error {{must be initialized by a constant expression}} \
144                                // both-note {{subobject 'f' is not initialized}}
145   constexpr F foo2[3] = {true, false, true}; // both-error {{must be initialized by a constant expression}} \
146                                              // both-note {{subobject 'f' is not initialized}}
147   constexpr F foo3[3] = {true, true, F()}; // both-error {{must be initialized by a constant expression}} \
148                                            // both-note {{subobject 'f' is not initialized}}
149 
150 
151 
152   class Base {
153   public:
154     bool b;
155     int a; // both-note {{subobject declared here}}
156     constexpr Base() : b(true) {}
157   };
158 
159   class Derived : public Base {
160   public:
161     constexpr Derived() : Base() {}   };
162 
163   constexpr Derived D; // both-error {{must be initialized by a constant expression}} \
164                        // both-note {{subobject 'a' is not initialized}}
165 
166   class C2 {
167   public:
168     A a;
169     constexpr C2() {}   };
170   constexpr C2 c2; // both-error {{must be initialized by a constant expression}} \
171                    // both-note {{subobject 'a' is not initialized}}
172 
173   class C3 {
174   public:
175     A a[2];
176     constexpr C3() {}
177   };
178   constexpr C3 c3; // both-error {{must be initialized by a constant expression}} \
179                    // both-note {{subobject 'a' is not initialized}}
180 
181   class C4 {
182   public:
183     bool B[2][3]; // both-note {{subobject declared here}}
184     constexpr C4(){}
185   };
186   constexpr C4 c4; // both-error {{must be initialized by a constant expression}} \
187                    // both-note {{subobject 'B' is not initialized}}
188 };
189 
190 namespace ConstThis {
191   class Foo {
192     const int T = 12; // both-note {{declared const here}}
193     int a;
194   public:
195     constexpr Foo() {
196       this->a = 10;
197       T = 13; // both-error {{cannot assign to non-static data member 'T' with const-qualified type}}
198     }
199   };
200   constexpr Foo F; // both-error {{must be initialized by a constant expression}}
201 
202 
203   class FooDtor {
204     int a;
205   public:
206     constexpr FooDtor() {
207       this->a = 10;
208     }
209     constexpr ~FooDtor() {
210       this->a = 12;
211     }
212   };
213 
214   constexpr int foo() {
215     const FooDtor f;
216     return 0;
217   }
218   static_assert(foo() == 0);
219 
220   template <bool Good>
221   struct ctor_test {
222     int a = 0;
223 
224     constexpr ctor_test() {
225       if (Good)
226         a = 10;
227       int local = 100 / a; // both-note {{division by zero}}
228     }
229   };
230 
231   template <bool Good>
232   struct dtor_test {
233     int a = 0;
234 
235     constexpr dtor_test() = default;
236     constexpr ~dtor_test() {
237       if (Good)
238         a = 10;
239       int local = 100 / a; // both-note {{division by zero}}
240     }
241   };
242 
243   constexpr ctor_test<true> good_ctor;
244   constexpr dtor_test<true> good_dtor;
245 
246   constexpr ctor_test<false> bad_ctor; // both-error {{must be initialized by a constant expression}} \
247                                        // both-note {{in call to}}
248   constexpr dtor_test<false> bad_dtor; // both-error {{must have constant destruction}} \
249                                        // both-note {{in call to}}
250 };
251 
252 namespace BaseInit {
253   struct Base {
254     int a;
255   };
256 
257   struct Intermediate : Base {
258     int b;
259   };
260 
261   struct Final : Intermediate {
262     int c;
263 
264     constexpr Final(int a, int b, int c) : c(c) {}
265   };
266 
267   static_assert(Final{1, 2, 3}.c == 3, ""); // OK
268   static_assert(Final{1, 2, 3}.a == 0, ""); // both-error {{not an integral constant expression}} \
269                                             // both-note {{read of uninitialized object}}
270 
271 
272   struct Mixin  {
273     int b;
274 
275     constexpr Mixin() = default;
276     constexpr Mixin(int b) : b(b) {}
277   };
278 
279   struct Final2 : Base, Mixin {
280     int c;
281 
282     constexpr Final2(int a, int b, int c) : Mixin(b), c(c) {}
283     constexpr Final2(int a, int b, int c, bool) : c(c) {}
284   };
285 
286   static_assert(Final2{1, 2, 3}.c == 3, ""); // OK
287   static_assert(Final2{1, 2, 3}.b == 2, ""); // OK
288   static_assert(Final2{1, 2, 3}.a == 0, ""); // both-error {{not an integral constant expression}} \
289                                              // both-note {{read of uninitialized object}}
290 
291 
292   struct Mixin3  {
293     int b;
294   };
295 
296   struct Final3 : Base, Mixin3 {
297     int c;
298 
299     constexpr Final3(int a, int b, int c) : c(c) { this->b = b; }
300     constexpr Final3(int a, int b, int c, bool) : c(c) {}
301   };
302 
303   static_assert(Final3{1, 2, 3}.c == 3, ""); // OK
304   static_assert(Final3{1, 2, 3}.b == 2, ""); // OK
305   static_assert(Final3{1, 2, 3}.a == 0, ""); // both-error {{not an integral constant expression}} \
306                                              // both-note {{read of uninitialized object}}
307 };
308 
309 namespace Destructors {
310 
311   class Inc final {
312   public:
313     int &I;
314     constexpr Inc(int &I) : I(I) {}
315     constexpr ~Inc() {
316       I++;
317     }
318   };
319 
320   class Dec final {
321   public:
322     int &I;
323     constexpr Dec(int &I) : I(I) {}
324     constexpr ~Dec() {
325       I--;
326     }
327   };
328 
329 
330 
331   constexpr int m() {
332     int i = 0;
333     {
334       Inc f1(i);
335       Inc f2(i);
336       Inc f3(i);
337     }
338     return i;
339   }
340   static_assert(m() == 3, "");
341 
342 
343   constexpr int C() {
344     int i = 0;
345 
346     while (i < 10) {
347       Inc inc(i);
348       continue;
349       Dec dec(i);
350     }
351     return i;
352   }
353   static_assert(C() == 10, "");
354 
355 
356   constexpr int D() {
357     int i = 0;
358 
359     {
360       Inc i1(i);
361       {
362         Inc i2(i);
363         return i;
364       }
365     }
366 
367     return i;
368   }
369   static_assert(D() == 0, "");
370 
371   constexpr int E() {
372     int i = 0;
373 
374     for(;;) {
375       Inc i1(i);
376       break;
377     }
378     return i;
379   }
380   static_assert(E() == 1, "");
381 
382 
383   /// FIXME: This should be rejected, since we call the destructor
384   ///   twice. However, GCC doesn't care either.
385   constexpr int ManualDtor() {
386     int i = 0;
387     {
388       Inc I(i); // ref-note {{destroying object 'I' whose lifetime has already ended}}
389       I.~Inc();
390     }
391     return i;
392   }
393   static_assert(ManualDtor() == 1, ""); // expected-error {{static assertion failed}} \
394                                         // expected-note {{evaluates to '2 == 1'}} \
395                                         // ref-error {{not an integral constant expression}} \
396                                         // ref-note {{in call to 'ManualDtor()'}}
397 
398   constexpr void doInc(int &i) {
399     Inc I(i);
400     return;
401   }
402   constexpr int testInc() {
403     int i = 0;
404     doInc(i);
405     return i;
406   }
407   static_assert(testInc() == 1, "");
408   constexpr void doInc2(int &i) {
409     Inc I(i);
410     // No return statement.
411   }
412    constexpr int testInc2() {
413     int i = 0;
414     doInc2(i);
415     return i;
416   }
417   static_assert(testInc2() == 1, "");
418 
419 
420   namespace DtorOrder {
421     class A {
422       public:
423       int &I;
424       constexpr A(int &I) : I(I) {}
425       constexpr ~A() {
426         I = 1337;
427       }
428     };
429 
430     class B : public A {
431       public:
432       constexpr B(int &I) : A(I) {}
433       constexpr ~B() {
434         I = 42;
435       }
436     };
437 
438     constexpr int foo() {
439       int i = 0;
440       {
441         B b(i);
442       }
443       return i;
444     }
445 
446     static_assert(foo() == 1337);
447   }
448 
449   class FieldDtor1 {
450   public:
451     Inc I1;
452     Inc I2;
453     constexpr FieldDtor1(int &I) : I1(I), I2(I){}
454   };
455 
456   constexpr int foo2() {
457     int i = 0;
458     {
459       FieldDtor1 FD1(i);
460     }
461     return i;
462   }
463 
464   static_assert(foo2() == 2);
465 
466   class FieldDtor2 {
467   public:
468     Inc Incs[3];
469     constexpr FieldDtor2(int &I)  : Incs{Inc(I), Inc(I), Inc(I)} {}
470   };
471 
472   constexpr int foo3() {
473     int i = 0;
474     {
475       FieldDtor2 FD2(i);
476     }
477     return i;
478   }
479 
480   static_assert(foo3() == 3);
481 
482   struct ArrD {
483     int index;
484     int *arr;
485     int &p;
486     constexpr ~ArrD() {
487       arr[p] = index;
488       ++p;
489     }
490   };
491   constexpr bool ArrayOrder() {
492     int order[3] = {0, 0, 0};
493     int p = 0;
494     {
495       ArrD ds[3] = {
496         {1, order, p},
497         {2, order, p},
498         {3, order, p},
499       };
500       // ds will be destroyed.
501     }
502     return order[0] == 3 && order[1] == 2 && order[2] == 1;
503   }
504   static_assert(ArrayOrder());
505 
506 
507   // Static members aren't destroyed.
508   class Dec2 {
509   public:
510     int A = 0;
511     constexpr ~Dec2() {
512       A++;
513     }
514   };
515   class Foo {
516   public:
517     static constexpr Dec2 a;
518     static Dec2 b;
519   };
520   static_assert(Foo::a.A == 0);
521   constexpr bool f() {
522     Foo f;
523     return true;
524   }
525   static_assert(Foo::a.A == 0);
526   static_assert(f());
527   static_assert(Foo::a.A == 0);
528 
529 
530   struct NotConstexpr {
531     NotConstexpr() {}
532     ~NotConstexpr() {}
533   };
534 
535   struct Outer {
536     constexpr Outer() = default;
537     constexpr ~Outer();
538 
539     constexpr int foo() {
540       return 12;
541     }
542 
543     constexpr int bar()const  {
544       return Outer{}.foo();
545     }
546 
547     static NotConstexpr Val;
548   };
549 
550   constexpr Outer::~Outer() {}
551 
552   constexpr Outer O;
553   static_assert(O.bar() == 12);
554 }
555 
556 namespace BaseAndFieldInit {
557   struct A {
558     int a;
559   };
560 
561   struct B : A {
562     int b;
563   };
564 
565   struct C : B {
566     int c;
567   };
568 
569   constexpr C c = {1,2,3};
570   static_assert(c.a == 1 && c.b == 2 && c.c == 3);
571 }
572 
573 namespace ImplicitFunction {
574   struct A {
575     int a; // ref-note {{subobject declared here}}
576   };
577 
578   constexpr int callMe() {
579    A a;
580    A b{12};
581 
582    /// The operator= call here will fail and the diagnostics should be fine.
583    b = a; // ref-note {{subobject 'a' is not initialized}} \
584           // expected-note {{read of uninitialized object}} \
585           // both-note {{in call to}}
586 
587    return 1;
588   }
589   static_assert(callMe() == 1, ""); // both-error {{not an integral constant expression}} \
590                                     // both-note {{in call to 'callMe()'}}
591 }
592 
593 namespace std {
594   class strong_ordering {
595   public:
596     int n;
597     static const strong_ordering less, equal, greater;
598     constexpr bool operator==(int n) const noexcept { return this->n == n;}
599     constexpr bool operator!=(int n) const noexcept { return this->n != n;}
600   };
601   constexpr strong_ordering strong_ordering::less = {-1};
602   constexpr strong_ordering strong_ordering::equal = {0};
603   constexpr strong_ordering strong_ordering::greater = {1};
604 
605   class partial_ordering {
606   public:
607     long n;
608     static const partial_ordering less, equal, greater, equivalent, unordered;
609     constexpr bool operator==(long n) const noexcept { return this->n == n;}
610     constexpr bool operator!=(long n) const noexcept { return this->n != n;}
611   };
612   constexpr partial_ordering partial_ordering::less = {-1};
613   constexpr partial_ordering partial_ordering::equal = {0};
614   constexpr partial_ordering partial_ordering::greater = {1};
615   constexpr partial_ordering partial_ordering::equivalent = {0};
616   constexpr partial_ordering partial_ordering::unordered = {-127};
617 } // namespace std
618 
619 namespace ThreeWayCmp {
620   static_assert(1 <=> 2 == -1, "");
621   static_assert(1 <=> 1 == 0, "");
622   static_assert(2 <=> 1 == 1, "");
623   static_assert(1.0 <=> 2.f == -1, "");
624   static_assert(1.0 <=> 1.0 == 0, "");
625   static_assert(2.0 <=> 1.0 == 1, "");
626   constexpr int k = (1 <=> 1, 0); // both-warning {{comparison result unused}}
627   static_assert(k== 0, "");
628 
629   /// Pointers.
630   constexpr int a[] = {1,2,3};
631   constexpr int b[] = {1,2,3};
632   constexpr const int *pa1 = &a[1];
633   constexpr const int *pa2 = &a[2];
634   constexpr const int *pb1 = &b[1];
635   static_assert(pa1 <=> pb1 != 0, ""); // both-error {{not an integral constant expression}} \
636                                        // both-note {{has unspecified value}}
637   static_assert(pa1 <=> pa1 == 0, "");
638   static_assert(pa1 <=> pa2 == -1, "");
639   static_assert(pa2 <=> pa1 == 1, "");
640 }
641 
642 namespace ConstexprArrayInitLoopExprDestructors
643 {
644   struct Highlander {
645       int *p = 0;
646       constexpr Highlander() {}
647       constexpr void set(int *p) { this->p = p; ++*p; if (*p != 1) throw "there can be only one"; }
648       constexpr ~Highlander() { --*p; }
649   };
650 
651   struct X {
652       int *p;
653       constexpr X(int *p) : p(p) {}
654       constexpr X(const X &x, Highlander &&h = Highlander()) : p(x.p) {
655           h.set(p);
656       }
657   };
658 
659   constexpr int f() {
660       int n = 0;
661       X x[3] = {&n, &n, &n};
662       auto [a, b, c] = x;
663       return n;
664   }
665 
666   static_assert(f() == 0);
667 }
668 
669 namespace NonPrimitiveOpaqueValue
670 {
671   struct X {
672     int x;
673     constexpr operator bool() const { return x != 0; }
674   };
675 
676   constexpr int ternary() { return X(0) ?: X(0); }
677 
678   static_assert(!ternary(), "");
679 }
680 
681 namespace TryCatch {
682   constexpr int foo() {
683     int a = 10;
684     try {
685       ++a;
686     } catch(int m) {
687       --a;
688     }
689     return a;
690   }
691   static_assert(foo() == 11);
692 }
693 
694 namespace IgnoredConstantExpr {
695   consteval int immediate() { return 0;}
696   struct ReferenceToNestedMembers {
697     int m;
698     int a = ((void)immediate(), m);
699     int b = ((void)immediate(), this->m);
700   };
701   struct ReferenceToNestedMembersTest {
702     void* m = nullptr;
703     ReferenceToNestedMembers j{0};
704   } test_reference_to_nested_members;
705 }
706 
707 namespace RewrittenBinaryOperators {
708   template <class T, T Val>
709   struct Conv {
710     constexpr operator T() const { return Val; }
711     operator T() { return Val; }
712   };
713 
714   struct X {
715     constexpr const Conv<int, -1> operator<=>(X) { return {}; }
716   };
717   static_assert(X() < X(), "");
718 }
719 
720 namespace GH61417 {
721 struct A {
722   unsigned x : 1;
723   unsigned   : 0;
724   unsigned y : 1;
725 
726   constexpr A() : x(0), y(0) {}
727   bool operator==(const A& rhs) const noexcept = default;
728 };
729 
730 void f1() {
731   constexpr A a, b;
732   constexpr bool c = (a == b); // no diagnostic, we should not be comparing the
733                                // unnamed bit-field which is indeterminate
734 }
735 
736 void f2() {
737     A a, b;
738     bool c = (a == b); // no diagnostic nor crash during codegen attempting to
739                        // access info for unnamed bit-field
740 }
741 }
742 
743 namespace FailingDestructor {
744   struct D {
745     int n;
746     bool can_destroy;
747 
748     constexpr ~D() {
749       if (!can_destroy)
750         throw "oh no";
751     }
752   };
753   template<D d>
754   void f() {} // both-note {{invalid explicitly-specified argument}}
755 
756   void g() {
757     f<D{0, false}>(); // both-error {{no matching function}}
758   }
759 }
760 
761 
762 void overflowInSwitchCase(int n) {
763   switch (n) {
764   case (int)(float)1e300: // both-error {{constant expression}} \
765                           // both-note {{value +Inf is outside the range of representable values of type 'int'}}
766     break;
767   }
768 }
769 
770 namespace APValues {
771   int g;
772   struct A { union { int n, m; }; int *p; int A::*q; char buffer[32]; };
773   template<A a> constexpr const A &get = a;
774   constexpr const A &v = get<A{}>;
775   constexpr const A &w = get<A{1, &g, &A::n, "hello"}>;
776 }
777 
778 namespace self_referencing {
779   struct S {
780     S* ptr = nullptr;
781     constexpr S(int i) : ptr(this) {
782       if (this == ptr && i)
783         ptr = nullptr;
784     }
785     constexpr ~S() {}
786   };
787 
788   void test() {
789     S s(1);
790   }
791 }
792 
793 namespace GH64949 {
794   struct f {
795     int g; // both-note {{subobject declared here}}
796     constexpr ~f() {}
797   };
798 
799   class h {
800   public:
801     consteval h(char *) {}
802     f i;
803   };
804 
805   void test() { h{nullptr}; } // both-error {{call to consteval function 'GH64949::h::h' is not a constant expression}} \
806                               // both-note {{subobject 'g' is not initialized}} \
807                               // both-warning {{expression result unused}}
808 }
809 
810 /// This used to cause an assertion failure inside EvaluationResult::checkFullyInitialized.
811 namespace CheckingNullPtrForInitialization {
812   struct X {
813     consteval operator const char *() const {
814       return nullptr;
815     }
816   };
817   const char *f() {
818     constexpr X x;
819     return x;
820   }
821 }
822 
823 namespace VariadicCallOperator {
824   class F {
825   public:
826     constexpr void operator()(int a, int b, ...) {}
827   };
828   constexpr int foo() {
829     F f;
830 
831     f(1,2, 3);
832     return 1;
833   }
834   constexpr int A = foo();
835 }
836 
837 namespace DefinitionLoc {
838 
839   struct NonConstexprCopy {
840     constexpr NonConstexprCopy() = default;
841     NonConstexprCopy(const NonConstexprCopy &);
842     constexpr NonConstexprCopy(NonConstexprCopy &&) = default;
843 
844     int n = 42;
845   };
846 
847   NonConstexprCopy::NonConstexprCopy(const NonConstexprCopy &) = default; // both-note {{here}}
848 
849   constexpr NonConstexprCopy ncc1 = NonConstexprCopy(NonConstexprCopy());
850   constexpr NonConstexprCopy ncc2 = ncc1; // both-error {{constant expression}} \
851                                           // both-note {{non-constexpr constructor}}
852 }
853 
854 namespace VirtDtor {
855   class B {
856   public:
857     constexpr B(char *p) : p(p) {}
858     virtual constexpr ~B() {
859       *p = 'B';
860       ++p;
861     }
862 
863     char *p;
864   };
865 
866   class C : public B {
867   public:
868     constexpr C(char *p) : B(p) {}
869     virtual constexpr ~C() override {
870       *p = 'C';
871       ++p;
872     }
873   };
874 
875   union U {
876     constexpr U(char *p) : c(p) {}
877     constexpr ~U() {}
878 
879     C c;
880   };
881 
882   constexpr int test(char a, char b) {
883     char buff[2] = {};
884     U u(buff);
885 
886     /// U is a union, so it won't call the destructor of its fields.
887     /// We do this manually here. Explicitly calling ~C() here should
888     /// also call the destructor of the base classes however.
889     u.c.~C();
890 
891     return buff[0] == a && buff[1] == b;
892   }
893 
894   static_assert(test('C', 'B'));
895 }
896 
897 namespace TemporaryInNTTP {
898   template<auto n> struct B { /* ... */ };
899   struct J1 {
900     J1 *self=this;
901   };
902   /// FIXME: The bytecode interpreter emits a different diagnostic here.
903   /// The current interpreter creates a fake MaterializeTemporaryExpr (see EvaluateAsConstantExpr)
904   /// which is later used as the LValueBase of the created APValue.
905   B<J1{}> j1;  // ref-error {{pointer to temporary object is not allowed in a template argument}} \
906                // expected-error {{non-type template argument is not a constant expression}} \
907                // expected-note {{pointer to temporary is not a constant expression}} \
908                // expected-note {{created here}}
909   B<2> j2; /// Ok.
910 }
911