Skip to content

Add flag to suppress overflow errors in C++ constant expressions. #102390

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ def err_expr_not_ice : Error<
def ext_expr_not_ice : Extension<
"expression is not an %select{integer|integral}0 constant expression; "
"folding it to a constant is a GNU extension">, InGroup<GNUFoldingConstant>;
def ext_expr_ice_overflow : Extension<
"expression is not an integer constant expression "
"because of arithmetic overflow; folding it to a constant is a GNU "
"extension">, InGroup<GNUFoldingConstant>;
def ext_expr_ice_overflow_cxx : Extension<
"expression is not an integral constant expression "
"because of arithmetic overflow">,
InGroup<DiagGroup<"constant-overflow">>, DefaultError, SFINAEFailure;
def err_typecheck_converted_constant_expression : Error<
"value of type %0 is not implicitly convertible to %1">;
def err_typecheck_converted_constant_expression_disallowed : Error<
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -7242,6 +7242,7 @@ class Sema final : public SemaBase {
virtual SemaDiagnosticBuilder diagnoseNotICE(Sema &S,
SourceLocation Loc) = 0;
virtual SemaDiagnosticBuilder diagnoseFold(Sema &S, SourceLocation Loc);
virtual SemaDiagnosticBuilder diagnoseOverflow(Sema &S, SourceLocation Loc);
virtual ~VerifyICEDiagnoser() {}
};

Expand Down
16 changes: 13 additions & 3 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16913,6 +16913,13 @@ Sema::VerifyICEDiagnoser::diagnoseFold(Sema &S, SourceLocation Loc) {
return S.Diag(Loc, diag::ext_expr_not_ice) << S.LangOpts.CPlusPlus;
}

Sema::SemaDiagnosticBuilder
Sema::VerifyICEDiagnoser::diagnoseOverflow(Sema &S, SourceLocation Loc) {
if (S.LangOpts.CPlusPlus)
return S.Diag(Loc, diag::ext_expr_ice_overflow_cxx);
return S.Diag(Loc, diag::ext_expr_ice_overflow);
}

ExprResult
Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
VerifyICEDiagnoser &Diagnoser,
Expand Down Expand Up @@ -17031,6 +17038,7 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
}

Diagnoser.diagnoseFold(*this, DiagLoc) << E->getSourceRange();

for (const PartialDiagnosticAt &Note : Notes)
Diag(Note.first, Note.second);

Expand All @@ -17045,8 +17053,7 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
// not a constant expression as a side-effect.
bool Folded =
E->EvaluateAsRValue(EvalResult, Context, /*isConstantContext*/ true) &&
EvalResult.Val.isInt() && !EvalResult.HasSideEffects &&
(!getLangOpts().CPlusPlus || !EvalResult.HasUndefinedBehavior);
EvalResult.Val.isInt() && !EvalResult.HasSideEffects;

if (!isa<ConstantExpr>(E))
E = ConstantExpr::Create(Context, E, EvalResult.Val);
Expand Down Expand Up @@ -17079,7 +17086,10 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
return ExprError();
}

Diagnoser.diagnoseFold(*this, DiagLoc) << E->getSourceRange();
if (EvalResult.HasUndefinedBehavior)
Diagnoser.diagnoseOverflow(*this, DiagLoc) << E->getSourceRange();
else
Diagnoser.diagnoseFold(*this, DiagLoc) << E->getSourceRange();
for (const PartialDiagnosticAt &Note : Notes)
Diag(Note.first, Note.second);

Expand Down
2 changes: 1 addition & 1 deletion clang/test/C/drs/dr2xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ void dr261(void) {
* but we fold it as a constant expression anyway as a GNU extension.
*/
enum e2 {
ex2 = __INT_MAX__ + (0, 1) /* expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}}
ex2 = __INT_MAX__ + (0, 1) /* expected-warning {{expression is not an integer constant expression because of arithmetic overflow; folding it to a constant is a GNU extension}}
expected-note {{value 2147483648 is outside the range of representable values of type 'int'}}
expected-warning {{left operand of comma operator has no effect}}
*/
Expand Down
3 changes: 3 additions & 0 deletions clang/test/Sema/shift-count-overflow.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// RUN: %clang_cc1 -fsyntax-only -verify=expected,c -pedantic %s
// RUN: %clang_cc1 -x c++ -std=c++98 -fsyntax-only -verify=expected,cpp %s
// RUN: %clang_cc1 -x c++ -std=c++11 -fsyntax-only -verify=expected,cpp %s
// RUN: %clang_cc1 -x c++ -std=c++11 -fsyntax-only -Wno-constant-overflow -verify=suppress %s

// suppress-no-diagnostics

enum shiftof {
X = (1<<32) // c-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}}
Expand Down
Loading