From 94d36fdbd7d2c6eab250f15f65fd20a6447b92eb Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Wed, 4 May 2022 12:39:18 -0400 Subject: [PATCH] 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. --- clang/docs/ReleaseNotes.rst | 4 ++++ clang/lib/Sema/SemaExpr.cpp | 12 ++++++------ clang/test/Sema/generic-selection.c | 14 ++++++++++++-- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 74d1800..079523a 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -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 `_. +- 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 `_. Improvements to Clang's diagnostics ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 6701252..058967b 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1653,18 +1653,18 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc, ControllingExpr = R.get(); } + bool TypeErrorFound = false, + IsResultDependent = ControllingExpr->isTypeDependent(), + ContainsUnexpandedParameterPack + = ControllingExpr->containsUnexpandedParameterPack(); + // The controlling expression is an unevaluated operand, so side effects are // likely unintended. - if (!inTemplateInstantiation() && + if (!inTemplateInstantiation() && !IsResultDependent && ControllingExpr->HasSideEffects(Context, false)) Diag(ControllingExpr->getExprLoc(), diag::warn_side_effects_unevaluated_context); - bool TypeErrorFound = false, - IsResultDependent = ControllingExpr->isTypeDependent(), - ContainsUnexpandedParameterPack - = ControllingExpr->containsUnexpandedParameterPack(); - for (unsigned i = 0; i < NumAssocs; ++i) { if (Exprs[i]->containsUnexpandedParameterPack()) ContainsUnexpandedParameterPack = true; diff --git a/clang/test/Sema/generic-selection.c b/clang/test/Sema/generic-selection.c index 82d40afe..82ba75e 100644 --- a/clang/test/Sema/generic-selection.c +++ b/clang/test/Sema/generic-selection.c @@ -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); +} -- 2.7.4