xref: /llvm-project/clang/test/SemaCXX/cxx2a-consteval-default-params.cpp (revision d773c00e52f1acd68267c6f2f5bfa269b73810a0)
1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++23 %s
3 
4 consteval int undefined();  // expected-note 2 {{declared here}}
5 
check_lambdas_unused(int a=[](int no_error=undefined ()){}(0),int b=[](int defaulted=undefined ()){}())6 void check_lambdas_unused(
7     int a = [](int no_error = undefined()) {
8         return no_error;
9     }(0),
__anon87c0ec230202(int defaulted = undefined()) 10     int b = [](int defaulted = undefined()) {
11         return defaulted;
12     }()
13 ) {}
14 
check_lambdas_used(int b=[](int no_error=undefined ()){}(0),int c=[](int defaulted=undefined ()){}(),int d=[](int defaulted=sizeof (undefined ())){}())15 int check_lambdas_used(
16     int b = [](int no_error = undefined()) {
17         return no_error;
18     }(0),
__anon87c0ec230402(int defaulted = undefined()) 19     int c = [](int defaulted = undefined()) { // expected-error {{not a constant expression}} \
20                               // expected-note  {{declared here}} \
21                               // expected-note  {{undefined function 'undefined'}}
22         return defaulted;
23     }(),  // expected-note {{in the default initializer of 'defaulted'}}
__anon87c0ec230502(int defaulted = sizeof(undefined())) 24     int d = [](int defaulted = sizeof(undefined())) {
25         return defaulted;
26     }()
27 ) {
28     return 0;
29 }
30 
31 int test_check_lambdas_used = check_lambdas_used();
32 
33 struct UnusedInitWithLambda {
__anon87c0ec230602UnusedInitWithLambda34     int a = [] {
35         return undefined(); // never evaluated because immediate escalating
36     }();
37     // UnusedInitWithLambda is never constructed, so the initializer
38     // of b and undefined() are never evaluated.
__anon87c0ec230702UnusedInitWithLambda39     int b = [](int no_error = undefined()) {
40         return no_error;
41     }();
42 };
43 
ub(int n)44 consteval int ub(int n) {
45     return 0/n;
46 }
47 
48 struct InitWithLambda { // expected-note {{'InitWithLambda' is an immediate constructor because the default initializer of 'b' contains a call to a consteval function 'undefined' and that call is not a constant expression}}
__anon87c0ec230802InitWithLambda49     int b = [](int error = undefined()) {  // expected-note {{undefined function 'undefined' cannot be used in a constant expression}}
50         return error;
51     }();
__anon87c0ec230902InitWithLambda52     int c = [](int error = sizeof(undefined()) + ub(0)) {
53 
54         return error;
55     }();
56 } i;
57 // expected-error@-1 {{call to immediate function 'InitWithLambda::InitWithLambda' is not a constant expression}} \
58    expected-note@-1 {{in call to 'InitWithLambda()'}}
59 
60 namespace ShouldNotCrash {
61     template<typename T>
62     struct F {
63         template<typename U>
FShouldNotCrash::F64         F(const U&) {}
65     };
66     struct A {
__anon87c0ec230a02ShouldNotCrash::A67         static constexpr auto x = [] {};
68         F<int> f = x;
69     };
f(A a=A ())70     void f(A a = A()) { }
71 }
72 
73 namespace GH62224 {
74   consteval int fwd();
75   template <int i = fwd()>
76   struct C {
CGH62224::C77     consteval C(int = fwd()) { }
getGH62224::C78     consteval int get() { return i; }
79   };
80 
fwd()81   consteval int fwd() { return 42; }
82   C<> Val; // No error since fwd is defined already.
83   static_assert(Val.get() == 42);
84 }
85 
86 namespace GH80630 {
87 
ce()88 consteval const char* ce() { return "Hello"; }
89 
f2(const char * loc=[](char const * fn){}(ce ()))90 auto f2(const char* loc = []( char const* fn )
91     { return fn; }  ( ce() ) ) {
92     return loc;
93 }
94 
g()95 auto g() {
96     return f2();
97 }
98 
99 }
100