]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ax_cxx_compile_stdcxx.m4
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / ax_cxx_compile_stdcxx.m4
CommitLineData
1d506c26 1# Copyright (c) 2016-2024 Free Software Foundation, Inc.
0bcda685
PA
2#
3# Originally based on the AX_CXX_COMPILE_STDCXX macro found at the url
4# below.
5#
6# Local GDB customizations:
7#
8# - AC_SUBST CXX_DIALECT instead of changing CXX/CXXCPP.
9#
87106a7b 10# ===========================================================================
41260ac2 11# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
87106a7b
PA
12# ===========================================================================
13#
14# SYNOPSIS
15#
16# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
17#
18# DESCRIPTION
19#
20# Check for baseline language coverage in the compiler for the specified
21# version of the C++ standard. If necessary, add switches to CXX and
eb4de404
LS
22# CXXCPP to enable support. VERSION may be '11', '14', '17', or '20' for
23# the respective C++ standard version.
87106a7b
PA
24#
25# The second argument, if specified, indicates whether you insist on an
26# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
27# -std=c++11). If neither is specified, you get whatever works, with
eb4de404 28# preference for no added switch, and then for an extended mode.
87106a7b
PA
29#
30# The third argument, if specified 'mandatory' or if left unspecified,
31# indicates that baseline support for the specified C++ standard is
32# required and that the macro should error out if no mode with that
33# support is found. If specified 'optional', then configuration proceeds
34# regardless, after defining HAVE_CXX${VERSION} if and only if a
35# supporting mode is found.
36#
37# LICENSE
38#
39# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
40# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
41# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
42# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
43# Copyright (c) 2015 Paul Norman <penorman@mac.com>
44# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
eb4de404
LS
45# Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
46# Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com>
47# Copyright (c) 2020 Jason Merrill <jason@redhat.com>
48# Copyright (c) 2021 Jörn Heusipp <osmanx@problemloesungsmaschine.de>
87106a7b
PA
49#
50# Copying and distribution of this file, with or without modification, are
51# permitted in any medium without royalty provided the copyright notice
52# and this notice are preserved. This file is offered as-is, without any
53# warranty.
54
eb4de404 55#serial 18
87106a7b
PA
56
57dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
58dnl (serial version number 13).
59
60AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
41260ac2
SM
61 m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
62 [$1], [14], [ax_cxx_compile_alternatives="14 1y"],
63 [$1], [17], [ax_cxx_compile_alternatives="17 1z"],
eb4de404 64 [$1], [20], [ax_cxx_compile_alternatives="20"],
87106a7b
PA
65 [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
66 m4_if([$2], [], [],
67 [$2], [ext], [],
68 [$2], [noext], [],
69 [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
70 m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
71 [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
72 [$3], [optional], [ax_cxx_compile_cxx$1_required=false],
73 [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
74 AC_LANG_PUSH([C++])dnl
0bcda685 75 CXX_DIALECT=""
87106a7b 76 ac_success=no
eb4de404
LS
77
78 m4_if([$2], [], [dnl
79 AC_CACHE_CHECK(whether $CXX supports C++$1 features by default,
80 ax_cv_cxx_compile_cxx$1,
81 [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
82 [ax_cv_cxx_compile_cxx$1=yes],
83 [ax_cv_cxx_compile_cxx$1=no])])
84 if test x$ax_cv_cxx_compile_cxx$1 = xyes; then
85 ac_success=yes
86 fi])
87106a7b
PA
87
88 m4_if([$2], [noext], [], [dnl
89 if test x$ac_success = xno; then
41260ac2
SM
90 for alternative in ${ax_cxx_compile_alternatives}; do
91 switch="-std=gnu++${alternative}"
87106a7b
PA
92 cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
93 AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
94 $cachevar,
95 [ac_save_CXX="$CXX"
96 CXX="$CXX $switch"
97 AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
98 [eval $cachevar=yes],
99 [eval $cachevar=no])
100 CXX="$ac_save_CXX"])
101 if eval test x\$$cachevar = xyes; then
0bcda685 102 CXX_DIALECT="$switch"
77252bf2
TV
103 CXX="$CXX $switch"
104 if test -n "$CXXCPP" ; then
105 CXXCPP="$CXXCPP $switch"
106 fi
87106a7b
PA
107 ac_success=yes
108 break
109 fi
110 done
111 fi])
112
113 m4_if([$2], [ext], [], [dnl
114 if test x$ac_success = xno; then
115 dnl HP's aCC needs +std=c++11 according to:
116 dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
117 dnl Cray's crayCC needs "-h std=c++11"
eb4de404 118 dnl MSVC needs -std:c++NN for C++17 and later (default is C++14)
41260ac2 119 for alternative in ${ax_cxx_compile_alternatives}; do
eb4de404
LS
120 for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}" MSVC; do
121 if test x"$switch" = xMSVC; then
122 dnl AS_TR_SH maps both `:` and `=` to `_` so -std:c++17 would collide
123 dnl with -std=c++17. We suffix the cache variable name with _MSVC to
124 dnl avoid this.
125 switch=-std:c++${alternative}
126 cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_${switch}_MSVC])
127 else
128 cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
129 fi
41260ac2
SM
130 AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
131 $cachevar,
132 [ac_save_CXX="$CXX"
133 CXX="$CXX $switch"
134 AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
135 [eval $cachevar=yes],
136 [eval $cachevar=no])
137 CXX="$ac_save_CXX"])
138 if eval test x\$$cachevar = xyes; then
139 CXX_DIALECT="$switch"
77252bf2
TV
140 CXX="$CXX $switch"
141 if test -n "$CXXCPP" ; then
142 CXXCPP="$CXXCPP $switch"
143 fi
41260ac2
SM
144 ac_success=yes
145 break
146 fi
147 done
148 if test x$ac_success = xyes; then
87106a7b
PA
149 break
150 fi
151 done
152 fi])
153 AC_LANG_POP([C++])
154 if test x$ax_cxx_compile_cxx$1_required = xtrue; then
155 if test x$ac_success = xno; then
156 AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
157 fi
158 fi
159 if test x$ac_success = xno; then
160 HAVE_CXX$1=0
161 AC_MSG_NOTICE([No compiler with C++$1 support was found])
162 else
163 HAVE_CXX$1=1
164 AC_DEFINE(HAVE_CXX$1,1,
165 [define if the compiler supports basic C++$1 syntax])
166 fi
167 AC_SUBST(HAVE_CXX$1)
0bcda685 168 AC_SUBST(CXX_DIALECT)
87106a7b
PA
169])
170
171
172dnl Test body for checking C++11 support
173
174m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
175 _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
176)
177
87106a7b
PA
178dnl Test body for checking C++14 support
179
180m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
181 _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
182 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
183)
184
eb4de404
LS
185dnl Test body for checking C++17 support
186
41260ac2
SM
187m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
188 _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
189 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
190 _AX_CXX_COMPILE_STDCXX_testbody_new_in_17
191)
87106a7b 192
eb4de404
LS
193dnl Test body for checking C++20 support
194
195m4_define([_AX_CXX_COMPILE_STDCXX_testbody_20],
196 _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
197 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
198 _AX_CXX_COMPILE_STDCXX_testbody_new_in_17
199 _AX_CXX_COMPILE_STDCXX_testbody_new_in_20
200)
201
202
87106a7b
PA
203dnl Tests for new features in C++11
204
205m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
206
207// If the compiler admits that it is not ready for C++11, why torture it?
208// Hopefully, this will speed up the test.
209
210#ifndef __cplusplus
211
212#error "This is not a C++ compiler"
213
eb4de404
LS
214// MSVC always sets __cplusplus to 199711L in older versions; newer versions
215// only set it correctly if /Zc:__cplusplus is specified as well as a
216// /std:c++NN switch:
217// https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/
218#elif __cplusplus < 201103L && !defined _MSC_VER
87106a7b
PA
219
220#error "This is not a C++11 compiler"
221
222#else
223
224namespace cxx11
225{
226
227 namespace test_static_assert
228 {
229
230 template <typename T>
231 struct check
232 {
233 static_assert(sizeof(int) <= sizeof(T), "not big enough");
234 };
235
236 }
237
238 namespace test_final_override
239 {
240
241 struct Base
242 {
eb4de404 243 virtual ~Base() {}
87106a7b
PA
244 virtual void f() {}
245 };
246
247 struct Derived : public Base
248 {
eb4de404 249 virtual ~Derived() override {}
87106a7b
PA
250 virtual void f() override {}
251 };
252
253 }
254
255 namespace test_double_right_angle_brackets
256 {
257
258 template < typename T >
259 struct check {};
260
261 typedef check<void> single_type;
262 typedef check<check<void>> double_type;
263 typedef check<check<check<void>>> triple_type;
264 typedef check<check<check<check<void>>>> quadruple_type;
265
266 }
267
268 namespace test_decltype
269 {
270
271 int
272 f()
273 {
274 int a = 1;
275 decltype(a) b = 2;
276 return a + b;
277 }
278
279 }
280
281 namespace test_type_deduction
282 {
283
284 template < typename T1, typename T2 >
285 struct is_same
286 {
287 static const bool value = false;
288 };
289
290 template < typename T >
291 struct is_same<T, T>
292 {
293 static const bool value = true;
294 };
295
296 template < typename T1, typename T2 >
297 auto
298 add(T1 a1, T2 a2) -> decltype(a1 + a2)
299 {
300 return a1 + a2;
301 }
302
303 int
304 test(const int c, volatile int v)
305 {
306 static_assert(is_same<int, decltype(0)>::value == true, "");
307 static_assert(is_same<int, decltype(c)>::value == false, "");
308 static_assert(is_same<int, decltype(v)>::value == false, "");
309 auto ac = c;
310 auto av = v;
311 auto sumi = ac + av + 'x';
312 auto sumf = ac + av + 1.0;
313 static_assert(is_same<int, decltype(ac)>::value == true, "");
314 static_assert(is_same<int, decltype(av)>::value == true, "");
315 static_assert(is_same<int, decltype(sumi)>::value == true, "");
316 static_assert(is_same<int, decltype(sumf)>::value == false, "");
317 static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
318 return (sumf > 0.0) ? sumi : add(c, v);
319 }
320
321 }
322
323 namespace test_noexcept
324 {
325
326 int f() { return 0; }
327 int g() noexcept { return 0; }
328
329 static_assert(noexcept(f()) == false, "");
330 static_assert(noexcept(g()) == true, "");
331
332 }
333
334 namespace test_constexpr
335 {
336
337 template < typename CharT >
338 unsigned long constexpr
339 strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
340 {
341 return *s ? strlen_c_r(s + 1, acc + 1) : acc;
342 }
343
344 template < typename CharT >
345 unsigned long constexpr
346 strlen_c(const CharT *const s) noexcept
347 {
348 return strlen_c_r(s, 0UL);
349 }
350
351 static_assert(strlen_c("") == 0UL, "");
352 static_assert(strlen_c("1") == 1UL, "");
353 static_assert(strlen_c("example") == 7UL, "");
354 static_assert(strlen_c("another\0example") == 7UL, "");
355
356 }
357
358 namespace test_rvalue_references
359 {
360
361 template < int N >
362 struct answer
363 {
364 static constexpr int value = N;
365 };
366
367 answer<1> f(int&) { return answer<1>(); }
368 answer<2> f(const int&) { return answer<2>(); }
369 answer<3> f(int&&) { return answer<3>(); }
370
371 void
372 test()
373 {
374 int i = 0;
375 const int c = 0;
376 static_assert(decltype(f(i))::value == 1, "");
377 static_assert(decltype(f(c))::value == 2, "");
378 static_assert(decltype(f(0))::value == 3, "");
379 }
380
381 }
382
383 namespace test_uniform_initialization
384 {
385
386 struct test
387 {
388 static const int zero {};
389 static const int one {1};
390 };
391
392 static_assert(test::zero == 0, "");
393 static_assert(test::one == 1, "");
394
395 }
396
397 namespace test_lambdas
398 {
399
400 void
401 test1()
402 {
403 auto lambda1 = [](){};
404 auto lambda2 = lambda1;
405 lambda1();
406 lambda2();
407 }
408
409 int
410 test2()
411 {
412 auto a = [](int i, int j){ return i + j; }(1, 2);
413 auto b = []() -> int { return '0'; }();
414 auto c = [=](){ return a + b; }();
415 auto d = [&](){ return c; }();
416 auto e = [a, &b](int x) mutable {
417 const auto identity = [](int y){ return y; };
418 for (auto i = 0; i < a; ++i)
419 a += b--;
420 return x + identity(a + b);
421 }(0);
422 return a + b + c + d + e;
423 }
424
425 int
426 test3()
427 {
428 const auto nullary = [](){ return 0; };
429 const auto unary = [](int x){ return x; };
430 using nullary_t = decltype(nullary);
431 using unary_t = decltype(unary);
432 const auto higher1st = [](nullary_t f){ return f(); };
433 const auto higher2nd = [unary](nullary_t f1){
434 return [unary, f1](unary_t f2){ return f2(unary(f1())); };
435 };
436 return higher1st(nullary) + higher2nd(nullary)(unary);
437 }
438
439 }
440
441 namespace test_variadic_templates
442 {
443
444 template <int...>
445 struct sum;
446
447 template <int N0, int... N1toN>
448 struct sum<N0, N1toN...>
449 {
450 static constexpr auto value = N0 + sum<N1toN...>::value;
451 };
452
453 template <>
454 struct sum<>
455 {
456 static constexpr auto value = 0;
457 };
458
459 static_assert(sum<>::value == 0, "");
460 static_assert(sum<1>::value == 1, "");
461 static_assert(sum<23>::value == 23, "");
462 static_assert(sum<1, 2>::value == 3, "");
463 static_assert(sum<5, 5, 11>::value == 21, "");
464 static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
465
466 }
467
468 // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
469 // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
470 // because of this.
471 namespace test_template_alias_sfinae
472 {
473
474 struct foo {};
475
476 template<typename T>
477 using member = typename T::member_type;
478
479 template<typename T>
480 void func(...) {}
481
482 template<typename T>
483 void func(member<T>*) {}
484
485 void test();
486
487 void test() { func<foo>(0); }
488
489 }
490
491} // namespace cxx11
492
493#endif // __cplusplus >= 201103L
494
495]])
496
497
498dnl Tests for new features in C++14
499
500m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
501
502// If the compiler admits that it is not ready for C++14, why torture it?
503// Hopefully, this will speed up the test.
504
505#ifndef __cplusplus
506
507#error "This is not a C++ compiler"
508
eb4de404 509#elif __cplusplus < 201402L && !defined _MSC_VER
87106a7b
PA
510
511#error "This is not a C++14 compiler"
512
513#else
514
515namespace cxx14
516{
517
518 namespace test_polymorphic_lambdas
519 {
520
521 int
522 test()
523 {
524 const auto lambda = [](auto&&... args){
525 const auto istiny = [](auto x){
526 return (sizeof(x) == 1UL) ? 1 : 0;
527 };
528 const int aretiny[] = { istiny(args)... };
529 return aretiny[0];
530 };
531 return lambda(1, 1L, 1.0f, '1');
532 }
533
534 }
535
536 namespace test_binary_literals
537 {
538
539 constexpr auto ivii = 0b0000000000101010;
540 static_assert(ivii == 42, "wrong value");
541
542 }
543
544 namespace test_generalized_constexpr
545 {
546
547 template < typename CharT >
548 constexpr unsigned long
549 strlen_c(const CharT *const s) noexcept
550 {
551 auto length = 0UL;
552 for (auto p = s; *p; ++p)
553 ++length;
554 return length;
555 }
556
557 static_assert(strlen_c("") == 0UL, "");
558 static_assert(strlen_c("x") == 1UL, "");
559 static_assert(strlen_c("test") == 4UL, "");
560 static_assert(strlen_c("another\0test") == 7UL, "");
561
562 }
563
564 namespace test_lambda_init_capture
565 {
566
567 int
568 test()
569 {
570 auto x = 0;
571 const auto lambda1 = [a = x](int b){ return a + b; };
572 const auto lambda2 = [a = lambda1(x)](){ return a; };
573 return lambda2();
574 }
575
576 }
577
41260ac2 578 namespace test_digit_separators
87106a7b
PA
579 {
580
581 constexpr auto ten_million = 100'000'000;
582 static_assert(ten_million == 100000000, "");
583
584 }
585
586 namespace test_return_type_deduction
587 {
588
589 auto f(int& x) { return x; }
590 decltype(auto) g(int& x) { return x; }
591
592 template < typename T1, typename T2 >
593 struct is_same
594 {
595 static constexpr auto value = false;
596 };
597
598 template < typename T >
599 struct is_same<T, T>
600 {
601 static constexpr auto value = true;
602 };
603
604 int
605 test()
606 {
607 auto x = 0;
608 static_assert(is_same<int, decltype(f(x))>::value, "");
609 static_assert(is_same<int&, decltype(g(x))>::value, "");
610 return x;
611 }
612
613 }
614
615} // namespace cxx14
616
617#endif // __cplusplus >= 201402L
618
619]])
41260ac2
SM
620
621
622dnl Tests for new features in C++17
623
624m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
625
626// If the compiler admits that it is not ready for C++17, why torture it?
627// Hopefully, this will speed up the test.
628
629#ifndef __cplusplus
630
631#error "This is not a C++ compiler"
632
eb4de404 633#elif __cplusplus < 201703L && !defined _MSC_VER
41260ac2
SM
634
635#error "This is not a C++17 compiler"
636
637#else
638
41260ac2
SM
639#include <initializer_list>
640#include <utility>
641#include <type_traits>
642
643namespace cxx17
644{
645
41260ac2
SM
646 namespace test_constexpr_lambdas
647 {
648
41260ac2
SM
649 constexpr int foo = [](){return 42;}();
650
651 }
41260ac2
SM
652
653 namespace test::nested_namespace::definitions
654 {
655
656 }
657
658 namespace test_fold_expression
659 {
660
661 template<typename... Args>
662 int multiply(Args... args)
663 {
664 return (args * ... * 1);
665 }
666
667 template<typename... Args>
668 bool all(Args... args)
669 {
670 return (args && ...);
671 }
672
673 }
674
675 namespace test_extended_static_assert
676 {
677
678 static_assert (true);
679
680 }
681
682 namespace test_auto_brace_init_list
683 {
684
685 auto foo = {5};
686 auto bar {5};
687
688 static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
689 static_assert(std::is_same<int, decltype(bar)>::value);
690 }
691
692 namespace test_typename_in_template_template_parameter
693 {
694
695 template<template<typename> typename X> struct D;
696
697 }
698
699 namespace test_fallthrough_nodiscard_maybe_unused_attributes
700 {
701
702 int f1()
703 {
704 return 42;
705 }
706
707 [[nodiscard]] int f2()
708 {
709 [[maybe_unused]] auto unused = f1();
710
711 switch (f1())
712 {
713 case 17:
714 f1();
715 [[fallthrough]];
716 case 42:
717 f1();
718 }
719 return f1();
720 }
721
722 }
723
724 namespace test_extended_aggregate_initialization
725 {
726
727 struct base1
728 {
729 int b1, b2 = 42;
730 };
731
732 struct base2
733 {
734 base2() {
735 b3 = 42;
736 }
737 int b3;
738 };
739
740 struct derived : base1, base2
741 {
742 int d;
743 };
744
745 derived d1 {{1, 2}, {}, 4}; // full initialization
746 derived d2 {{}, {}, 4}; // value-initialized bases
747
748 }
749
750 namespace test_general_range_based_for_loop
751 {
752
753 struct iter
754 {
755 int i;
756
757 int& operator* ()
758 {
759 return i;
760 }
761
762 const int& operator* () const
763 {
764 return i;
765 }
766
767 iter& operator++()
768 {
769 ++i;
770 return *this;
771 }
772 };
773
774 struct sentinel
775 {
776 int i;
777 };
778
779 bool operator== (const iter& i, const sentinel& s)
780 {
781 return i.i == s.i;
782 }
783
784 bool operator!= (const iter& i, const sentinel& s)
785 {
786 return !(i == s);
787 }
788
789 struct range
790 {
791 iter begin() const
792 {
793 return {0};
794 }
795
796 sentinel end() const
797 {
798 return {5};
799 }
800 };
801
802 void f()
803 {
804 range r {};
805
806 for (auto i : r)
807 {
808 [[maybe_unused]] auto v = i;
809 }
810 }
811
812 }
813
814 namespace test_lambda_capture_asterisk_this_by_value
815 {
816
817 struct t
818 {
819 int i;
820 int foo()
821 {
822 return [*this]()
823 {
824 return i;
825 }();
826 }
827 };
828
829 }
830
831 namespace test_enum_class_construction
832 {
833
834 enum class byte : unsigned char
835 {};
836
837 byte foo {42};
838
839 }
840
841 namespace test_constexpr_if
842 {
843
844 template <bool cond>
845 int f ()
846 {
847 if constexpr(cond)
848 {
849 return 13;
850 }
851 else
852 {
853 return 42;
854 }
855 }
856
857 }
858
859 namespace test_selection_statement_with_initializer
860 {
861
862 int f()
863 {
864 return 13;
865 }
866
867 int f2()
868 {
869 if (auto i = f(); i > 0)
870 {
871 return 3;
872 }
873
874 switch (auto i = f(); i + 4)
875 {
876 case 17:
877 return 2;
878
879 default:
880 return 1;
881 }
882 }
883
884 }
885
41260ac2
SM
886 namespace test_template_argument_deduction_for_class_templates
887 {
888
41260ac2
SM
889 template <typename T1, typename T2>
890 struct pair
891 {
892 pair (T1 p1, T2 p2)
893 : m1 {p1},
894 m2 {p2}
895 {}
896
897 T1 m1;
898 T2 m2;
899 };
900
901 void f()
902 {
903 [[maybe_unused]] auto p = pair{13, 42u};
904 }
905
906 }
41260ac2
SM
907
908 namespace test_non_type_auto_template_parameters
909 {
910
911 template <auto n>
912 struct B
913 {};
914
915 B<5> b1;
916 B<'a'> b2;
917
918 }
919
41260ac2
SM
920 namespace test_structured_bindings
921 {
922
41260ac2
SM
923 int arr[2] = { 1, 2 };
924 std::pair<int, int> pr = { 1, 2 };
925
926 auto f1() -> int(&)[2]
927 {
928 return arr;
929 }
930
931 auto f2() -> std::pair<int, int>&
932 {
933 return pr;
934 }
935
936 struct S
937 {
938 int x1 : 2;
939 volatile double y1;
940 };
941
942 S f3()
943 {
944 return {};
945 }
946
947 auto [ x1, y1 ] = f1();
948 auto& [ xr1, yr1 ] = f1();
949 auto [ x2, y2 ] = f2();
950 auto& [ xr2, yr2 ] = f2();
951 const auto [ x3, y3 ] = f3();
952
953 }
41260ac2 954
41260ac2
SM
955 namespace test_exception_spec_type_system
956 {
957
41260ac2
SM
958 struct Good {};
959 struct Bad {};
960
961 void g1() noexcept;
962 void g2();
963
964 template<typename T>
965 Bad
966 f(T*, T*);
967
968 template<typename T1, typename T2>
969 Good
970 f(T1*, T2*);
971
972 static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
973
974 }
41260ac2
SM
975
976 namespace test_inline_variables
977 {
978
979 template<class T> void f(T)
980 {}
981
982 template<class T> inline T g(T)
983 {
984 return T{};
985 }
986
987 template<> inline void f<>(int)
988 {}
989
990 template<> int g<>(int)
991 {
992 return 5;
993 }
994
995 }
996
997} // namespace cxx17
998
eb4de404
LS
999#endif // __cplusplus < 201703L && !defined _MSC_VER
1000
1001]])
1002
1003
1004dnl Tests for new features in C++20
1005
1006m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[
1007
1008#ifndef __cplusplus
1009
1010#error "This is not a C++ compiler"
1011
1012#elif __cplusplus < 202002L && !defined _MSC_VER
1013
1014#error "This is not a C++20 compiler"
1015
1016#else
1017
1018#include <version>
1019
1020namespace cxx20
1021{
1022
1023// As C++20 supports feature test macros in the standard, there is no
1024// immediate need to actually test for feature availability on the
1025// Autoconf side.
1026
1027} // namespace cxx20
1028
1029#endif // __cplusplus < 202002L && !defined _MSC_VER
41260ac2
SM
1030
1031]])