Skip to content

Commit 0ed3473

Browse files
[clang] Emit bad shift warnings
1 parent cb5d1b5 commit 0ed3473

File tree

8 files changed

+52
-8
lines changed

8 files changed

+52
-8
lines changed

clang/lib/AST/ExprConstant.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2856,6 +2856,9 @@ static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E,
28562856
else if (LHS.countl_zero() < SA)
28572857
Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
28582858
}
2859+
if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
2860+
Info.getLangOpts().CPlusPlus)
2861+
return false;
28592862
Result = LHS << SA;
28602863
return true;
28612864
}
@@ -2879,6 +2882,10 @@ static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E,
28792882
if (SA != RHS)
28802883
Info.CCEDiag(E, diag::note_constexpr_large_shift)
28812884
<< RHS << E->getType() << LHS.getBitWidth();
2885+
2886+
if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
2887+
Info.getLangOpts().CPlusPlus)
2888+
return false;
28822889
Result = LHS >> SA;
28832890
return true;
28842891
}

clang/lib/Sema/SemaExpr.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11246,7 +11246,7 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
1124611246
if (Right.isNegative()) {
1124711247
S.DiagRuntimeBehavior(Loc, RHS.get(),
1124811248
S.PDiag(diag::warn_shift_negative)
11249-
<< RHS.get()->getSourceRange());
11249+
<< RHS.get()->getSourceRange());
1125011250
return;
1125111251
}
1125211252

@@ -11261,7 +11261,7 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
1126111261
if (Right.uge(LeftSize)) {
1126211262
S.DiagRuntimeBehavior(Loc, RHS.get(),
1126311263
S.PDiag(diag::warn_shift_gt_typewidth)
11264-
<< RHS.get()->getSourceRange());
11264+
<< RHS.get()->getSourceRange());
1126511265
return;
1126611266
}
1126711267

@@ -11294,7 +11294,7 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
1129411294
if (Left.isNegative()) {
1129511295
S.DiagRuntimeBehavior(Loc, LHS.get(),
1129611296
S.PDiag(diag::warn_shift_lhs_negative)
11297-
<< LHS.get()->getSourceRange());
11297+
<< LHS.get()->getSourceRange());
1129811298
return;
1129911299
}
1130011300

@@ -17130,11 +17130,20 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
1713017130
// Circumvent ICE checking in C++11 to avoid evaluating the expression twice
1713117131
// in the non-ICE case.
1713217132
if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) {
17133+
SmallVector<PartialDiagnosticAt, 8> Notes;
1713317134
if (Result)
17134-
*Result = E->EvaluateKnownConstIntCheckOverflow(Context);
17135+
*Result = E->EvaluateKnownConstIntCheckOverflow(Context, &Notes);
1713517136
if (!isa<ConstantExpr>(E))
1713617137
E = Result ? ConstantExpr::Create(Context, E, APValue(*Result))
1713717138
: ConstantExpr::Create(Context, E);
17139+
17140+
if (Notes.size() && !Diagnoser.Suppress) {
17141+
Diagnoser.diagnoseNotICE(*this, DiagLoc) << E->getSourceRange();
17142+
for (const PartialDiagnosticAt &Note : Notes)
17143+
Diag(Note.first, Note.second);
17144+
return ExprError();
17145+
}
17146+
1713817147
return E;
1713917148
}
1714017149

clang/test/C/drs/dr0xx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ void dr081(void) {
430430
/* Demonstrate that we don't crash when left shifting a signed value; that's
431431
* implementation defined behavior.
432432
*/
433-
_Static_assert(-1 << 1 == -2, "fail"); /* Didn't shift a zero into the "sign bit". */
433+
_Static_assert(-1 << 1 == -2, "fail"); /* Undefined behavior since C99 */
434434
_Static_assert(1 << 3 == 1u << 3u, "fail"); /* Shift of a positive signed value does sensible things. */
435435
}
436436

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %clang_cc1 -x c -fsyntax-only -verify=expected,c -Wshift-count-negative %s
2+
// RUN: %clang_cc1 -x c -fsyntax-only -verify=expected,c -Wall %s
3+
// RUN: %clang_cc1 -x c++ -fsyntax-only -verify=expected,cpp -Wshift-count-negative %s
4+
// RUN: %clang_cc1 -x c++ -fsyntax-only -verify=expected,cpp -Wall %s
5+
6+
enum shiftof {
7+
X = (1<<-29) // c-error {{expression is not an integer constant expression}}
8+
// cpp-error@-1 {{expression is not an integral constant expression}}
9+
// expected-note@-2 {{negative shift count -29}}
10+
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify -Wshift-count-overflow %s
2+
// RUN: %clang_cc1 -fsyntax-only -verify -Wall %s
3+
4+
enum shiftof {
5+
X = (1<<32) // expected-error {{expression is not an integer constant expression}}
6+
// expected-note@-1 {{shift count 32 >= width of type 'int'}}
7+
};
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %clang_cc1 -x c -fsyntax-only -verify=expected,c -Wshift-negative-value %s
2+
// RUN: %clang_cc1 -x c -fsyntax-only -verify=expected,c -Wall %s
3+
// RUN: %clang_cc1 -x c++ -fsyntax-only -verify=expected,cpp -Wshift-negative-value %s
4+
// RUN: %clang_cc1 -x c++ -fsyntax-only -verify=expected,cpp -Wall %s
5+
6+
enum shiftof {
7+
X = (-1<<29) // c-error {{expression is not an integer constant expression}}
8+
// cpp-error@-1 {{expression is not an integral constant expression}}
9+
// expected-note@-2 {{left shift of negative value -1}}
10+
};

clang/test/Sema/vla-2.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
// a different codepath when we have already emitted an error.)
55

66
int PotentiallyEvaluatedSizeofWarn(int n) {
7-
return (int)sizeof *(0 << 32,(int(*)[n])0); // expected-warning {{left operand of comma operator has no effect}} expected-warning {{shift count >= width of type}}
7+
return (int)sizeof *(0 << 32,(int(*)[n])0); /* expected-warning {{shift count >= width of type}}
8+
expected-warning {{left operand of comma operator has no effect}} */
89
}
910

1011
void PotentiallyEvaluatedTypeofWarn(int n) {
11-
__typeof(*(0 << 32,(int(*)[n])0)) x; // expected-warning {{left operand of comma operator has no effect}} expected-warning {{shift count >= width of type}}
12+
__typeof(*(0 << 32,(int(*)[n])0)) x; /* expected-warning {{shift count >= width of type}}
13+
expected-warning {{left operand of comma operator has no effect}} */
1214
(void)x;
1315
}
1416

clang/test/SemaCXX/shift.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ void test() {
2222
c = 1 << -1; // expected-warning {{shift count is negative}}
2323
c = 1 >> -1; // expected-warning {{shift count is negative}}
2424
c = 1 << (unsigned)-1; // expected-warning {{shift count >= width of type}}
25-
// expected-warning@-1 {{implicit conversion}}
2625
c = 1 >> (unsigned)-1; // expected-warning {{shift count >= width of type}}
2726
c = 1 << c;
2827
c <<= 0;

0 commit comments

Comments
 (0)