зеркало из https://github.com/microsoft/clang-1.git
implement PR6004, warning about divide and remainder by zero.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93256 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
a1e1dc77e9
Коммит
7ef655a788
|
@ -1557,10 +1557,10 @@ def warn_floatingpoint_eq : Warning<
|
|||
"comparing floating point with == or != is unsafe">,
|
||||
InGroup<DiagGroup<"float-equal">>, DefaultIgnore;
|
||||
|
||||
def warn_shift_negative : Warning<
|
||||
"shift count is negative">;
|
||||
def warn_shift_gt_typewidth : Warning<
|
||||
"shift count >= width of type">;
|
||||
def warn_division_by_zero : Warning<"division by zero is undefined">;
|
||||
def warn_remainder_by_zero : Warning<"remainder by zero is undefined">;
|
||||
def warn_shift_negative : Warning<"shift count is negative">;
|
||||
def warn_shift_gt_typewidth : Warning<"shift count >= width of type">;
|
||||
|
||||
def warn_precedence_bitwise_rel : Warning<
|
||||
"%0 has lower precedence than %1; %1 will be evaluated first">,
|
||||
|
|
|
@ -3644,7 +3644,8 @@ public:
|
|||
QualType CheckPointerToMemberOperands( // C++ 5.5
|
||||
Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isIndirect);
|
||||
QualType CheckMultiplyDivideOperands( // C99 6.5.5
|
||||
Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
|
||||
Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign,
|
||||
bool isDivide);
|
||||
QualType CheckRemainderOperands( // C99 6.5.5
|
||||
Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
|
||||
QualType CheckAdditionOperands( // C99 6.5.6
|
||||
|
|
|
@ -4793,8 +4793,7 @@ QualType Sema::InvalidOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) {
|
|||
return QualType();
|
||||
}
|
||||
|
||||
inline QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex,
|
||||
Expr *&rex) {
|
||||
QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) {
|
||||
// For conversion purposes, we ignore any qualifiers.
|
||||
// For example, "const float" and "float" are equivalent.
|
||||
QualType lhsType =
|
||||
|
@ -4855,19 +4854,26 @@ inline QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex,
|
|||
return QualType();
|
||||
}
|
||||
|
||||
inline QualType Sema::CheckMultiplyDivideOperands(
|
||||
Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign) {
|
||||
QualType Sema::CheckMultiplyDivideOperands(
|
||||
Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign, bool isDiv) {
|
||||
if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
|
||||
return CheckVectorOperands(Loc, lex, rex);
|
||||
|
||||
QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
|
||||
|
||||
if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType())
|
||||
return compType;
|
||||
return InvalidOperands(Loc, lex, rex);
|
||||
if (!lex->getType()->isArithmeticType() ||
|
||||
!rex->getType()->isArithmeticType())
|
||||
return InvalidOperands(Loc, lex, rex);
|
||||
|
||||
// Check for division by zero.
|
||||
if (isDiv &&
|
||||
rex->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull))
|
||||
Diag(Loc, diag::warn_division_by_zero) << rex->getSourceRange();
|
||||
|
||||
return compType;
|
||||
}
|
||||
|
||||
inline QualType Sema::CheckRemainderOperands(
|
||||
QualType Sema::CheckRemainderOperands(
|
||||
Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign) {
|
||||
if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) {
|
||||
if (lex->getType()->isIntegerType() && rex->getType()->isIntegerType())
|
||||
|
@ -4877,12 +4883,17 @@ inline QualType Sema::CheckRemainderOperands(
|
|||
|
||||
QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
|
||||
|
||||
if (lex->getType()->isIntegerType() && rex->getType()->isIntegerType())
|
||||
return compType;
|
||||
return InvalidOperands(Loc, lex, rex);
|
||||
if (!lex->getType()->isIntegerType() || !rex->getType()->isIntegerType())
|
||||
return InvalidOperands(Loc, lex, rex);
|
||||
|
||||
// Check for remainder by zero.
|
||||
if (rex->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull))
|
||||
Diag(Loc, diag::warn_remainder_by_zero) << rex->getSourceRange();
|
||||
|
||||
return compType;
|
||||
}
|
||||
|
||||
inline QualType Sema::CheckAdditionOperands( // C99 6.5.6
|
||||
QualType Sema::CheckAdditionOperands( // C99 6.5.6
|
||||
Expr *&lex, Expr *&rex, SourceLocation Loc, QualType* CompLHSTy) {
|
||||
if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) {
|
||||
QualType compType = CheckVectorOperands(Loc, lex, rex);
|
||||
|
@ -6082,7 +6093,8 @@ Action::OwningExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
|
|||
break;
|
||||
case BinaryOperator::Mul:
|
||||
case BinaryOperator::Div:
|
||||
ResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc);
|
||||
ResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, false,
|
||||
Opc == BinaryOperator::Div);
|
||||
break;
|
||||
case BinaryOperator::Rem:
|
||||
ResultTy = CheckRemainderOperands(lhs, rhs, OpLoc);
|
||||
|
@ -6118,7 +6130,8 @@ Action::OwningExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
|
|||
break;
|
||||
case BinaryOperator::MulAssign:
|
||||
case BinaryOperator::DivAssign:
|
||||
CompResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, true);
|
||||
CompResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, true,
|
||||
Opc == BinaryOperator::DivAssign);
|
||||
CompLHSTy = CompResultTy;
|
||||
if (!CompResultTy.isNull())
|
||||
ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
|
||||
|
|
|
@ -91,16 +91,16 @@ void r6268365() {
|
|||
|
||||
void divzeroassume(unsigned x, unsigned j) {
|
||||
x /= j;
|
||||
if (j == 0) x /= 0; // no-warning
|
||||
if (j == 0) x /= j; // no-warning
|
||||
if (j == 0) x = x / 0; // no-warning
|
||||
if (j == 0) x /= 0; // no static-analyzer warning expected-warning {{division by zero is undefined}}
|
||||
if (j == 0) x /= j; // no static-analyzer warning
|
||||
if (j == 0) x = x / 0; // no static-analyzer warning expected-warning {{division by zero is undefined}}
|
||||
}
|
||||
|
||||
void divzeroassumeB(unsigned x, unsigned j) {
|
||||
x = x / j;
|
||||
if (j == 0) x /= 0; // no-warning
|
||||
if (j == 0) x /= j; // no-warning
|
||||
if (j == 0) x = x / 0; // no-warning
|
||||
if (j == 0) x /= 0; // no static-analyzer warning expected-warning {{division by zero is undefined}}
|
||||
if (j == 0) x /= j; // no static-analyzer warning
|
||||
if (j == 0) x = x / 0; // no static-analyzer warning expected-warning {{division by zero is undefined}}
|
||||
}
|
||||
|
||||
// InitListExpr processing
|
||||
|
|
|
@ -114,3 +114,11 @@ test15_t test15(void) {
|
|||
// rdar://7446395
|
||||
void test16(float x) { x == ((void*) 0); } // expected-error {{invalid operands to binary expression}}
|
||||
|
||||
// PR6004
|
||||
void test17(int x) {
|
||||
x = x / 0; // expected-warning {{division by zero is undefined}}
|
||||
x = x % 0; // expected-warning {{remainder by zero is undefined}}
|
||||
x /= 0; // expected-warning {{division by zero is undefined}}
|
||||
x %= 0; // expected-warning {{remainder by zero is undefined}}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,8 +57,9 @@ int comma3[(1,2)]; // expected-warning {{size of static array must be an integer
|
|||
// Pointer + __builtin_constant_p
|
||||
char pbcp[__builtin_constant_p(4) ? (intptr_t)&expr : 0]; // expected-error {{variable length array declaration not allowed at file scope}}
|
||||
|
||||
int illegaldiv1[1 || 1/0];
|
||||
int illegaldiv2[1/0]; // expected-error {{variable length array declaration not allowed at file scope}}
|
||||
int illegaldiv1[1 || 1/0]; // expected-warning {{division by zero is undefined}}
|
||||
int illegaldiv2[1/0]; // expected-error {{variable length array declaration not allowed at file scope}} \
|
||||
// expected-warning {{division by zero is undefined}}
|
||||
int illegaldiv3[INT_MIN / -1]; // expected-error {{variable length array declaration not allowed at file scope}}
|
||||
|
||||
int chooseexpr[__builtin_choose_expr(1, 1, expr)];
|
||||
|
|
|
@ -35,7 +35,8 @@ void test_BitfieldMinus() {
|
|||
template<int I, int J>
|
||||
struct BitfieldDivide {
|
||||
int bitfield : I / J; // expected-error{{expression is not an integer constant expression}} \
|
||||
// expected-note{{division by zero}}
|
||||
// expected-note{{division by zero}} \
|
||||
// expected-warning {{division by zero is undefined}}
|
||||
};
|
||||
|
||||
void test_BitfieldDivide() {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
template<typename T, T Divisor>
|
||||
class X {
|
||||
public:
|
||||
static const T value = 10 / Divisor; // expected-error{{in-class initializer is not an integral constant expression}}
|
||||
static const T value = 10 / Divisor; // expected-error{{in-class initializer is not an integral constant expression}} expected-warning {{division by zero is undefined}}
|
||||
};
|
||||
|
||||
int array1[X<int, 2>::value == 5? 1 : -1];
|
||||
|
|
Загрузка…
Ссылка в новой задаче