Skip to content

Commit cc5237c

Browse files
authored
[C2y] Correctly handle incomplete types in generic selections (#141596)
We were emitting a non-error diagnostic but claiming we emitted an error, which caused some obvious follow-on problems. Fixes #141549
1 parent 97f6076 commit cc5237c

File tree

3 files changed

+31
-8
lines changed

3 files changed

+31
-8
lines changed

clang/lib/Sema/SemaExpr.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1874,9 +1874,11 @@ ExprResult Sema::CreateGenericSelectionExpr(
18741874

18751875
if (D != 0) {
18761876
Diag(Types[i]->getTypeLoc().getBeginLoc(), D)
1877-
<< Types[i]->getTypeLoc().getSourceRange()
1878-
<< Types[i]->getType();
1879-
TypeErrorFound = true;
1877+
<< Types[i]->getTypeLoc().getSourceRange() << Types[i]->getType();
1878+
if (getDiagnostics().getDiagnosticLevel(
1879+
D, Types[i]->getTypeLoc().getBeginLoc()) >=
1880+
DiagnosticsEngine::Error)
1881+
TypeErrorFound = true;
18801882
}
18811883

18821884
// C11 6.5.1.1p2 "No two generic associations in the same generic

clang/test/C/C2y/n3409.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
// RUN: %clang_cc1 -verify -std=c2y -pedantic %s
2-
// RUN: %clang_cc1 -verify=pre-c2y -std=c2y -Wpre-c2y-compat %s
3-
// RUN: %clang_cc1 -verify=ext -std=c23 -pedantic %s
4-
// expected-no-diagnostics
1+
// RUN: %clang_cc1 -verify -std=c2y -pedantic -Wno-unused %s
2+
// RUN: %clang_cc1 -verify=expected,pre-c2y -std=c2y -Wpre-c2y-compat -Wno-unused %s
3+
// RUN: %clang_cc1 -verify=expected,ext -std=c23 -pedantic -Wno-unused %s
54

65
/* WG14 N3409: Clang 21
76
* Slay Some Earthly Demons X
@@ -34,3 +33,25 @@ void foo() {
3433
// C23 and earlier.
3534
return x; // ext-warning {{void function 'foo' should not return void expression}}
3635
}
36+
37+
38+
// Ensure we behave correctly with incomplete types. See GH141549.
39+
static_assert(
40+
_Generic(
41+
void, /* ext-warning {{passing a type argument as the first operand to '_Generic' is a C2y extension}}
42+
pre-c2y-warning {{passing a type argument as the first operand to '_Generic' is incompatible with C standards before C2y}}
43+
*/
44+
void : 1,
45+
default : 0
46+
)
47+
);
48+
49+
static_assert(
50+
_Generic( // expected-error {{static assertion failed}}
51+
12,
52+
void : 1, /* ext-warning {{incomplete type 'void' in a '_Generic' association is a C2y extension}}
53+
pre-c2y-warning {{use of incomplete type 'void' in a '_Generic' association is incompatible with C standards before C2y}}
54+
*/
55+
default : 0
56+
)
57+
);

clang/test/SemaCXX/generic-selection.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ void func(struct S s) {
8181
// is an elaborated type specifier followed by the association's value and
8282
// it should work the same as in C.
8383
(void)_Generic(s, struct S : 1);
84-
(void)_Generic(s, struct T : 1);
84+
(void)_Generic(s, struct T : 1); // expected-error {{controlling expression type 'struct S' not compatible with any generic association type}}
8585

8686
// The rest of these cases test that we still produce a reasonable diagnostic
8787
// when referencing an unknown type or trying to define a type in other ways.

0 commit comments

Comments
 (0)