@@ -1389,4 +1389,59 @@ constexpr bool test_ctr(int *i) {
13891389static_assert (test_ctr(nullptr ), " " ); // expected-note {{in call to 'test_ctr(nullptr)'}}
13901390// expected-error@-1 {{static assertion expression is not an integral constant expression}}
13911391
1392+
1393+ // verify that we can dereference function pointers
1394+ namespace functions {
1395+
1396+ constexpr int f () {return 0 ;}
1397+ constexpr int (*f_ptr)() = &f;
1398+ constexpr int (*null_ptr)() = nullptr;
1399+
1400+ constexpr int (&f_ref)() = f;
1401+ constexpr int test = (*f_ptr)();
1402+ constexpr int test2 = (*f_ref)();
1403+ constexpr int test3 = (*f_ref)();
1404+ constexpr int test4 = (*null_ptr)();
1405+ // expected-error@-1 {{constexpr variable 'test4' must be initialized by a constant expression}} \
1406+ //expected-note@-1 {{'(*null_ptr)' evaluates to a null function pointer}}
1407+
1408+ constexpr int (*f_ptr_arr[1 ])() = {&f};
1409+ constexpr int test_array_ok = (f_ptr_arr[0 ])();
1410+ constexpr int test_array_err = (f_ptr_arr[1 ])();
1411+ // expected-error@-1 {{constexpr variable 'test_array_err' must be initialized by a constant expression}} \
1412+ // expected-note@-1 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}}
1413+
1414+ struct S {
1415+ int (*f_ptr)() = &f;
1416+ int (*f_ptr_arr[1 ])() = {&f};
1417+ int (&f_ref)() = f;
1418+ int (*null_ptr)() = nullptr ;
1419+ };
1420+
1421+ constexpr int test_member () {
1422+ S s {};
1423+ (*s.f_ptr )();
1424+ (*s.f_ref )();
1425+ (s.f_ref )();
1426+ (s.f_ptr_arr [0 ])();
1427+ (s.f_ptr_arr [1 ])();
1428+ // expected-note@-1 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}}
1429+ return 0 ;
1430+ }
1431+ constexpr int test_member_null () { // cxx14_20-error {{never produces a constant expression}}
1432+ S s {};
1433+ (*s.null_ptr )(); // expected-note {{'(*s.null_ptr)' evaluates to a null function pointer}} \
1434+ // cxx14_20-note {{'(*s.null_ptr)' evaluates to a null function pointer}}
1435+ return 0 ;
1436+ }
1437+
1438+ static_assert (test_member(), " " );
1439+ // expected-error@-1 {{static assertion expression is not an integral constant expression}} \
1440+ // expected-note@-1 {{in call to 'test_member()'}}
1441+
1442+ static_assert (test_member_null(), " " );
1443+ // expected-error@-1 {{static assertion expression is not an integral constant expression}} \
1444+ // expected-note@-1 {{in call to 'test_member_null()'}}
1445+
1446+ }
13921447}
0 commit comments