Skip to content

Commit cd4cea1

Browse files
diagnose auto deduction from void more specifically [GH edgcpp#27]
1 parent 773d310 commit cd4cea1

29 files changed

Lines changed: 238 additions & 62 deletions

File tree

‎src/Changes‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
Version 7.1
22

3+
10/9/26 [GH #27]
4+
Clearer diagnostic when auto is deduced from an incomplete type
5+
6+
Deducing a plain "auto" (including cv-qualified "auto") from void or another
7+
incomplete type used to be reported as a deduction failure. The type is now
8+
deduced, and the usual incomplete-type diagnostic is issued, as it already
9+
is for decltype(auto). For example:
10+
11+
void g();
12+
auto x = g(); // Error: incomplete type "void" is not allowed
13+
auto *p = g(); // Error: cannot deduce "auto" type
14+
15+
Forms that are not a plain "auto", such as "auto *", still fail deduction.
16+
17+
318
10/7/26 [GH #176]
419
C-generating back end: always_inline attribute and inlined setjmp calls
520

‎src/overload.c‎

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ static a_boolean adjust_deduction_pair(
6565
a_template_arg_ptr template_arg_list,
6666
a_type_ptr *qc_param_type,
6767
a_type_ptr *qc_arg_type,
68-
a_boolean *consider_nondeduced);
68+
a_boolean *consider_nondeduced,
69+
a_boolean allow_incomplete_arg);
6970
static a_boolean check_narrowing_conversion(an_operand *source_operand,
7071
a_type_ptr dest_type,
7172
a_boolean check_enum_target,
@@ -1485,7 +1486,8 @@ from previous arguments; in the standard case, it is always NULL.
14851486
(an_operand *)NULL, templ_params,
14861487
(a_template_arg *)NULL,
14871488
(a_type_ptr*)NULL, (a_type_ptr*)NULL,
1488-
(a_boolean *)NULL) &&
1489+
(a_boolean *)NULL,
1490+
/*allow_incomplete_arg=*/FALSE) &&
14891491
tentatively_matches_template_type(local_arg_type,
14901492
local_param_type,
14911493
templ_params,
@@ -4272,7 +4274,8 @@ static a_boolean adjust_deduction_pair(
42724274
a_template_arg_ptr template_arg_list,
42734275
a_type_ptr *qc_param_type,
42744276
a_type_ptr *qc_arg_type,
4275-
a_boolean *consider_nondeduced)
4277+
a_boolean *consider_nondeduced,
4278+
a_boolean allow_incomplete_arg)
42764279
/*
42774280
Adjust the types *p_param_type (a parameter type of a function template or a
42784281
type involving the "auto" type specifier) and *p_arg_type (the type of the
@@ -4295,7 +4298,10 @@ are not removed. If consider_nondeduced is non-NULL and the reason for
42954298
failure is that an indefinite function matches several ways, return
42964299
*consider_nondeduced TRUE. template_arg_list is used in some nonstandard
42974300
modes to introduce knowledge from previous arguments; in the standard case,
4298-
it is always NULL.
4301+
it is always NULL. allow_incomplete_arg allows an incomplete argument
4302+
type (including void) to be used for deduction. It is used for placeholder
4303+
type deduction, where an incomplete type error is diagnosed by the caller
4304+
instead of a deduction failure.
42994305
*/
43004306
{
43014307
a_boolean adjustment_okay = FALSE, indefinite_function_designator = FALSE;
@@ -4399,7 +4405,8 @@ it is always NULL.
43994405
void m() { f(*p); }
44004406
*/
44014407
complete_type_is_needed(arg_type);
4402-
if (is_incomplete_type(arg_type) && !is_managed_nullptr_type(arg_type)) {
4408+
if (is_incomplete_type(arg_type) && !is_managed_nullptr_type(arg_type) &&
4409+
!allow_incomplete_arg) {
44034410
/* Although the managed (C++/CLI) nullptr type is incomplete and
44044411
cannot be used as the type of an object, for example, the Microsoft
44054412
compiler allows it as a template argument. */
@@ -4621,7 +4628,8 @@ deduction was successful: some cases are treated as "nondeduced contexts").
46214628
elem_operand,
46224629
templ_params, *template_arg_list,
46234630
&qc_param_type, &qc_arg_type,
4624-
&consider_nondeduced)) {
4631+
&consider_nondeduced,
4632+
/*allow_incomplete_arg=*/FALSE)) {
46254633
if (consider_nondeduced) continue;
46264634
deduction_okay = FALSE;
46274635
break;
@@ -4775,7 +4783,8 @@ deduction succeeds, FALSE if it fails.
47754783
if (!adjust_deduction_pair(&param_type, &arg_type, operand,
47764784
templ_params, *template_arg_list,
47774785
&qc_param_type, &qc_arg_type,
4778-
&consider_nondeduced)) {
4786+
&consider_nondeduced,
4787+
/*allow_incomplete_arg=*/FALSE)) {
47794788
if (consider_nondeduced) {
47804789
/* The argument is an indefinite function that can match in more than
47814790
one way. Keep going without adding anything to the template
@@ -31235,10 +31244,19 @@ TRUE and FALSE is returned.
3123531244
/* Adjust the argument and parameter types for deduction. Some types can
3123631245
never succeed: Issue an error and don't attempt deduction any
3123731246
further. */
31247+
/* GCC and Microsoft don't diagnose incomplete-type errors in template
31248+
definitions, but for now the only way for us to emulate that is by
31249+
failing deduction in these cases (which we then allow, see
31250+
prescan_initializer_for_auto_type_deduction). */
31251+
a_boolean allow_incomplete_arg =
31252+
!((gpp_version_is(any_version) || ms_version_is(any_version)) &&
31253+
scope_stack_top().in_prototype_instantiation &&
31254+
innermost_function_scope != NULL);
3123831255
if (!adjust_deduction_pair(&type, &arg_type, initializer_operand,
3123931256
templ_param, (a_template_arg *)NULL,
3124031257
&qc_param_type, &qc_arg_type,
31241-
(a_boolean *)NULL)) {
31258+
(a_boolean *)NULL,
31259+
allow_incomplete_arg)) {
3124231260
okay = FALSE;
3124331261
} else if (!deduce_from_one_pair(type, arg_type,
3124431262
qc_param_type, qc_arg_type,
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
fe_only -DTEST_NUMBER=1 --c++23 Test_name.c
2+
"Test_name.c", line 27: error: incomplete type "void" is not allowed
3+
auto v1 = void();
4+
^
5+
6+
"Test_name.c", line 28: error: incomplete type "void" is not allowed
7+
decltype(auto) v2 = void();
8+
^
9+
10+
"Test_name.c", line 29: error: incomplete type "Incomplete" is not allowed
11+
auto v3 = getIncomplete();
12+
^
13+
14+
"Test_name.c", line 30: error: incomplete type "void" is not allowed
15+
auto opts = Args{}.parse();
16+
^
17+
18+
"Test_name.c", line 32: error: cannot deduce "auto" type
19+
auto *v4 = void();
20+
^
21+
22+
"Test_name.c", line 33: error: cannot deduce "auto" type
23+
auto *v5 = 1;
24+
^
25+
26+
"Test_name.c", line 34: error: cannot deduce "auto" type
27+
auto *p = g();
28+
^
29+
30+
7 errors detected in the compilation of "Test_name.c".
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
fe_only -DTEST_NUMBER=1 --c++11 -A Test_name.c
2+
"Test_name.c", line 14: error: incomplete type "void" is not allowed
3+
auto v = void();
4+
^
5+
6+
"Test_name.c", line 20: error: incomplete type "void" is not allowed
7+
auto v = void();
8+
^
9+
10+
"Test_name.c", line 29: error: incomplete type "Later" is not allowed
11+
auto x = later_obj;
12+
^
13+
14+
3 errors detected in the compilation of "Test_name.c".
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fe_only -DTEST_NUMBER=2 --c++11 --gnu_version 160200 Test_name.c
2+
"Test_name.c", line 14: error: incomplete type "void" is not allowed
3+
auto v = void();
4+
^
5+
6+
1 error detected in the compilation of "Test_name.c".
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fe_only -DTEST_NUMBER=3 --c++11 --clang_version 230100 Test_name.c
2+
"Test_name.c", line 14: error: incomplete type "void" is not allowed
3+
auto v = void();
4+
^
5+
6+
1 error detected in the compilation of "Test_name.c".
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fe_only -DTEST_NUMBER=4 --ms_c++20 --microsoft_version 1951 Test_name.c
2+
"Test_name.c", line 14: error: incomplete type "void" is not allowed
3+
auto v = void();
4+
^
5+
6+
1 error detected in the compilation of "Test_name.c".
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
fe_only -DTEST_NUMBER=3 --c++11 --clang_version 230100 Test_name.c
2+
"Test_name.c", line 14: error: incomplete type "void" is not allowed
3+
auto v = void();
4+
^
5+
6+
"Test_name.c", line 20: error: incomplete type "void" is not allowed
7+
auto v = void();
8+
^
9+
10+
"Test_name.c", line 29: error: incomplete type "Later" is not allowed
11+
auto x = later_obj;
12+
^
13+
14+
3 errors detected in the compilation of "Test_name.c".
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
fe_only -DTEST_NUMBER=3 --c++11 --clang_version 230100 Test_name.c
2+
"Test_name.c", line 14: error: incomplete type "void" is not allowed
3+
auto v = void();
4+
^
5+
6+
"Test_name.c", line 20: error: incomplete type "void" is not allowed
7+
auto v = void();
8+
^
9+
10+
"Test_name.c", line 29: error: incomplete type "Later" is not allowed
11+
auto x = later_obj;
12+
^
13+
14+
3 errors detected in the compilation of "Test_name.c".

‎tests/tests/changes/GH27.sft.cpp‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//type:fn
2+
//options:--c++23
3+
//remark:[GH #27] Clearer diagnostic when auto deduces to void
4+
// 10/9/26 [GH #27]
5+
//
6+
// A plain auto deduced from void or another incomplete type gets the
7+
// incomplete-type diagnostic, matching decltype(auto). auto * still
8+
// fails deduction.
9+
10+
struct Incomplete;
11+
12+
struct Incomplete &getIncomplete();
13+
14+
struct Clap {
15+
template <typename Spec>
16+
auto parse(this Spec const& spec) {
17+
}
18+
};
19+
20+
struct Args : Clap {
21+
};
22+
23+
void g();
24+
25+
void f()
26+
{
27+
auto v1 = void();
28+
decltype(auto) v2 = void();
29+
auto v3 = getIncomplete();
30+
auto opts = Args{}.parse();
31+
32+
auto *v4 = void();
33+
auto *v5 = 1;
34+
auto *p = g();
35+
}
36+

0 commit comments

Comments
 (0)