Fix a crash on invalid with _Generic expressions

We were failing to check if the controlling expression is dependent or
not when testing whether it has side effects. This would trigger an
assertion. Instead, if the controlling expression is dependent, we
suppress the check and diagnostic.

This fixes Issue 50227.
This commit is contained in:
Aaron Ballman 2022-05-04 12:39:18 -04:00
parent ff8d0b338f
commit 94d36fdbd7
3 changed files with 23 additions and 9 deletions

View File

@ -128,6 +128,10 @@ Bug Fixes
the functions were different. It now diagnoses this case correctly as an
ambiguous call and an error. Fixes
`Issue 53640 <https://github.com/llvm/llvm-project/issues/53640>`_.
- No longer crash when trying to determine whether the controlling expression
argument to a generic selection expression has side effects in the case where
the expression is result dependent. This fixes
`Issue 50227 <https://github.com/llvm/llvm-project/issues/50227>`_.
Improvements to Clang's diagnostics
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -1653,18 +1653,18 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc,
ControllingExpr = R.get();
}
// The controlling expression is an unevaluated operand, so side effects are
// likely unintended.
if (!inTemplateInstantiation() &&
ControllingExpr->HasSideEffects(Context, false))
Diag(ControllingExpr->getExprLoc(),
diag::warn_side_effects_unevaluated_context);
bool TypeErrorFound = false,
IsResultDependent = ControllingExpr->isTypeDependent(),
ContainsUnexpandedParameterPack
= ControllingExpr->containsUnexpandedParameterPack();
// The controlling expression is an unevaluated operand, so side effects are
// likely unintended.
if (!inTemplateInstantiation() && !IsResultDependent &&
ControllingExpr->HasSideEffects(Context, false))
Diag(ControllingExpr->getExprLoc(),
diag::warn_side_effects_unevaluated_context);
for (unsigned i = 0; i < NumAssocs; ++i) {
if (Exprs[i]->containsUnexpandedParameterPack())
ContainsUnexpandedParameterPack = true;

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -std=c11 -fsyntax-only -Wno-strict-prototypes -verify %s
// RUN: %clang_cc1 -std=c99 -pedantic -fsyntax-only -Wno-strict-prototypes -verify=expected,ext %s
// RUN: %clang_cc1 -std=c11 -fsyntax-only -Wno-strict-prototypes -Wno-implicit-function-declaration -verify %s
// RUN: %clang_cc1 -std=c99 -pedantic -fsyntax-only -Wno-strict-prototypes -Wno-implicit-function-declaration -verify=expected,ext %s
void g(void);
@ -47,3 +47,13 @@ char testc(char);
void PR30201(void) {
_Generic(4, char:testc, default:test)(4); // ext-warning {{'_Generic' is a C11 extension}}
}
void GH50227(void) {
// Previously, the controlling expression for the outer _Generic makes it
// result dependent, and testing whether that controlling expression has side
// effects would cause a crash.
_Generic( // ext-warning {{'_Generic' is a C11 extension}}
n(
_Generic(n++, int : 0) // expected-error {{cannot increment value of type 'int ()'}} ext-warning {{'_Generic' is a C11 extension}}
), int : 0);
}