Skip to content

Commit f0e30b6

Browse files
cpplearnerDaveed Vandevoorde
authored andcommitted
Implement full support for CWG 2355 ("Deducing noexcept-specifiers"). [GH edgcpp#197]
Previously this was a GCC/Clang emulation feature.
1 parent 5ecc082 commit f0e30b6

21 files changed

Lines changed: 139 additions & 68 deletions

File tree

‎src/Changes‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
10/1/26 [GH #197]
2+
Deducing noexcept-specifiers
3+
4+
Previously, the front end emulated Clang and GCC's ability to deduce simple
5+
dependent noexcept-specifiers (see the entry for EDGcpfe/18317 of 9/6/17).
6+
Meanwhile, the standard has been changed through Core issue 2355 to make that
7+
behavior standard-mandated. It is now the default behavior, except in
8+
Microsoft mode with microsoft_version < 1951.
9+
10+
111
Version 7.0, September 28, 2026
212

313
9/15/26 [EDGcpfe/28958]

‎src/cmd_line.c‎

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3237,7 +3237,7 @@ option values if they were not already set by a command line option.
32373237
exc_spec_in_func_type = TRUE;
32383238
} /* if */
32393239
#endif /* EXC_SPEC_IN_FUNC_TYPE_ENABLING_POSSIBLE */
3240-
deduction_from_exc_spec_allowed = FALSE;
3240+
deduction_from_exc_spec_allowed = microsoft_version >= 1951;
32413241
if (!option_kind_used[(int)optk_aligned_new]) {
32423242
overaligned_allocation_enabled = TRUE;
32433243
} /* if */
@@ -5928,13 +5928,7 @@ before this routine is called.
59285928
warn_on_deduced_return_types = TRUE;
59295929
} /* if */
59305930
} /* if */
5931-
if (cpp17_mode) {
5932-
/* g++ and clang allow deduction from the noexcept flag of a function
5933-
parameter. */
5934-
if (exc_spec_in_func_type) {
5935-
deduction_from_exc_spec_allowed = TRUE;
5936-
} /* if */
5937-
} else {
5931+
if (!cpp17_mode) {
59385932
/* g++ and clang do not implement this as a DR in C++14 mode. Note that
59395933
clang has this disabled by default even in C++17 mode (as of 6.0.1).
59405934
But we don't have a separate option to enable this, so we still
@@ -13281,7 +13275,7 @@ variables declared in cmd_line.h.
1328113275
implicit_noexcept_enabled = FALSE;
1328213276
core_constant_expr_is_noexcept = FALSE;
1328313277
exc_spec_in_func_type = FALSE;
13284-
deduction_from_exc_spec_allowed = FALSE;
13278+
deduction_from_exc_spec_allowed = TRUE;
1328513279
delegating_constructors_enabled = FALSE;
1328613280
inheriting_constructors_enabled = FALSE;
1328713281
constexpr_enabled = FALSE;

‎src/templates.c‎

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13889,9 +13889,6 @@ A nontype template parameter is potentially being deduced from a noexcept
1388913889
specifier. For example:
1389013890

1389113891
template<bool B> void f(int (*)() noexcept(B));
13892-
13893-
This is currently nonstandard, but accepted by GCC and Clang, and the omission
13894-
in the standard is perhaps accidental.
1389513892
*/
1389613893
{
1389713894
a_boolean match = FALSE;
@@ -13910,8 +13907,7 @@ in the standard is perhaps accidental.
1391013907
if (deduction_from_exc_spec_allowed &&
1391113908
(flags & MTT_ALLOW_STRICTER_NOEXCEPT) == 0 &&
1391213909
!constant_bool_value_known_at_compile_time(t_cp)) {
13913-
/* Some compilers allow deduction from the noexcept flag of a function
13914-
type. Do this deduction, if needed. */
13910+
/* Perform deduction from the noexcept flag of a function type. */
1391513911
a_constant_ptr cp;
1391613912
a_boolean cp_is_local = FALSE;
1391713913
if (esp != NULL && esp->variant.noexcept_arg != NULL) {

‎tests/expectations/edg_x86_32/cwg.log‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
2355a.sft.cpp:cp:-DTEST_NUMBER=1:FAIL:
2-
2355c.sft.cpp:cp:-DTEST_NUMBER=1:FAIL:
3-
2355d.sft.cpp:fn:-DTEST_NUMBER=1:FAIL:
41
P2615R1a.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:
52
P2647R1b.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:
63
cwg1028c.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:

‎tests/expectations/edg_x86_32_cp/cwg.log‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
2355a.sft.cpp:cp:-DTEST_NUMBER=1:FAIL:
2-
2355c.sft.cpp:cp:-DTEST_NUMBER=1:FAIL:
3-
2355d.sft.cpp:fn:-DTEST_NUMBER=1:FAIL:
41
P2615R1a.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:
52
P2647R1b.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:
63
cwg1028c.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:

‎tests/expectations/edg_x86_64/cwg.log‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
2355a.sft.cpp:cp:-DTEST_NUMBER=1:FAIL:
2-
2355c.sft.cpp:cp:-DTEST_NUMBER=1:FAIL:
3-
2355d.sft.cpp:fn:-DTEST_NUMBER=1:FAIL:
41
P2615R1a.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:
52
P2647R1b.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:
63
cwg1028c.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:

‎tests/expectations/edg_x86_64_cp/cwg.log‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
2355a.sft.cpp:cp:-DTEST_NUMBER=1:FAIL:
2-
2355c.sft.cpp:cp:-DTEST_NUMBER=1:FAIL:
3-
2355d.sft.cpp:fn:-DTEST_NUMBER=1:FAIL:
41
P2615R1a.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:
52
P2647R1b.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:
63
cwg1028c.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:
Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1 @@
1-
cpfe -DTEST_NUMBER=1 --c++20 -tused -A Test_name.c
2-
"Test_name.c", line 8: error: no instance of function template "f1" matches the argument list
3-
argument types are: (void ())
4-
f1(g1); // OK: E is false
5-
^
6-
"Test_name.c", line 2: note: candidate function template "f1" failed deduction
7-
template <bool E> void f1(void (*)() noexcept(E));
8-
^
9-
10-
"Test_name.c", line 9: error: no instance of function template "f1" matches the argument list
11-
argument types are: (void () noexcept)
12-
f1(g2); // OK: E is true
13-
^
14-
"Test_name.c", line 2: note: candidate function template "f1" failed deduction
15-
template <bool E> void f1(void (*)() noexcept(E));
16-
^
17-
18-
2 errors detected in the compilation of "Test_name.c".
1+
cpfe -DTEST_NUMBER=1 -tused --c++17 -A Test_name.c
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
fe_only -DTEST_NUMBER=10 -tused --ms_c++14 --microsoft_version 1951 Test_name.c
2+
"Test_name.c", line 9: error: no instance of function template "f1" matches the argument list
3+
argument types are: (void ())
4+
f1(g1); // OK: E is false
5+
^
6+
"Test_name.c", line 3: note: candidate function template "f1" failed deduction
7+
template <bool E> void f1(void (*)() noexcept(E));
8+
^
9+
10+
"Test_name.c", line 10: error: no instance of function template "f1" matches the argument list
11+
argument types are: (void ())
12+
f1(g2); // OK: E is true
13+
^
14+
"Test_name.c", line 3: note: candidate function template "f1" failed deduction
15+
template <bool E> void f1(void (*)() noexcept(E));
16+
^
17+
18+
2 errors detected in the compilation of "Test_name.c".
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cpfe -DTEST_NUMBER=2 -tused --c++17 --gn 160200 Test_name.c

0 commit comments

Comments
 (0)