[clang] handle extended integer constant expressions in _Static_assert (PR #57687)

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D134311
This commit is contained in:
Martin Sebor 2022-09-28 13:24:54 -06:00
parent 74bab7d4a0
commit a181de452d
3 changed files with 37 additions and 3 deletions

View File

@ -99,6 +99,9 @@ Major New Features
Bug Fixes Bug Fixes
--------- ---------
- Correct ``_Static_assert`` to accept the same set of extended integer
constant expressions as is accpted in other contexts that accept them.
This fixes `Issue 57687 <https://github.com/llvm/llvm-project/issues/57687>`_.
- Fixes an accepts-invalid bug in C when using a ``_Noreturn`` function - Fixes an accepts-invalid bug in C when using a ``_Noreturn`` function
specifier on something other than a function declaration. This fixes specifier on something other than a function declaration. This fixes
`Issue 56800 <https://github.com/llvm/llvm-project/issues/56800>`_. `Issue 56800 <https://github.com/llvm/llvm-project/issues/56800>`_.

View File

@ -16736,10 +16736,21 @@ Decl *Sema::BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc,
AssertExpr = FullAssertExpr.get(); AssertExpr = FullAssertExpr.get();
llvm::APSInt Cond; llvm::APSInt Cond;
Expr *BaseExpr = AssertExpr;
AllowFoldKind FoldKind = NoFold;
if (!getLangOpts().CPlusPlus) {
// In C mode only allow folding and strip the implicit conversion
// to the type of the first _Static_assert argument that would
// otherwise suppress diagnostics for arguments that convert to int.
FoldKind = AllowFold;
BaseExpr = BaseExpr->IgnoreImpCasts();
}
if (!Failed && VerifyIntegerConstantExpression( if (!Failed && VerifyIntegerConstantExpression(
AssertExpr, &Cond, BaseExpr, &Cond,
diag::err_static_assert_expression_is_not_constant) diag::err_static_assert_expression_is_not_constant,
.isInvalid()) FoldKind).isInvalid())
Failed = true; Failed = true;
if (!Failed && !Cond) { if (!Failed && !Cond) {

View File

@ -74,3 +74,23 @@ static_assert(1, "1 is nonzero"); // ms-warning {{use of 'static_assert' without
_Static_assert(1 , "") // expected-error {{expected ';' after '_Static_assert'}} \ _Static_assert(1 , "") // expected-error {{expected ';' after '_Static_assert'}} \
// ext-warning {{'_Static_assert' is a C11 extension}} // ext-warning {{'_Static_assert' is a C11 extension}}
static int static_var;
_Static_assert(&static_var != 0, ""); // ext-warning {{'_Static_assert' is a C11 extension}} \
// expected-warning {{comparison of address of 'static_var' not equal to a null pointer is always true}}
_Static_assert("" != 0, ""); // ext-warning {{'_Static_assert' is a C11 extension}}
_Static_assert(("" != 0), ""); // ext-warning {{'_Static_assert' is a C11 extension}}
_Static_assert(*"1", ""); // ext-warning {{'_Static_assert' is a C11 extension}}
_Static_assert("1"[0], ""); // ext-warning {{'_Static_assert' is a C11 extension}}
_Static_assert(1.0 != 0, ""); // ext-warning {{'_Static_assert' is a C11 extension}}
_Static_assert(__builtin_strlen("1"), ""); // ext-warning {{'_Static_assert' is a C11 extension}}
#ifndef __cplusplus
// ext-warning@-9 {{expression is not an integer constant expression; folding it to a constant is a GNU extension}}
// ext-warning@-8 {{expression is not an integer constant expression; folding it to a constant is a GNU extension}}
// ext-warning@-8 {{expression is not an integer constant expression; folding it to a constant is a GNU extension}}
// ext-warning@-8 {{expression is not an integer constant expression; folding it to a constant is a GNU extension}}
// ext-warning@-8 {{expression is not an integer constant expression; folding it to a constant is a GNU extension}}
// ext-warning@-8 {{expression is not an integer constant expression; folding it to a constant is a GNU extension}}
// __builtin_strlen(literal) is considered an integer constant expression
// and doesn't cause a pedantic warning
#endif