Implement checks for bool in increment and decrement.

llvm-svn: 61275
This commit is contained in:
Sebastian Redl 2008-12-20 09:35:34 +00:00
parent af7415ffb1
commit e10c2c32af
5 changed files with 34 additions and 10 deletions

View File

@ -1298,6 +1298,10 @@ DIAG(err_delete_operand, ERROR,
"cannot delete expression of type %0")
DIAG(warn_delete_incomplete, WARNING,
"deleting pointer to incomplete type %0 may cause undefined behaviour")
DIAG(err_decrement_bool, ERROR,
"cannot decrement expression of type bool")
DIAG(warn_increment_bool, WARNING,
"incrementing expression of type bool is deprecated")
DIAG(err_invalid_use_of_function_type, ERROR,
"a function type is not allowed here")

View File

@ -1306,7 +1306,8 @@ public:
/// type checking unary operators (subroutines of ActOnUnaryOp).
/// C99 6.5.3.1, 6.5.3.2, 6.5.3.4
QualType CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc);
QualType CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc,
bool isInc);
QualType CheckAddressOfOperand(Expr *op, SourceLocation OpLoc);
QualType CheckIndirectionOperand(Expr *op, SourceLocation OpLoc);
QualType CheckRealImagOperand(Expr *&Op, SourceLocation OpLoc);

View File

@ -952,7 +952,8 @@ Action::ExprResult Sema::ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
// build a built-in operation.
}
QualType result = CheckIncrementDecrementOperand(Arg, OpLoc);
QualType result = CheckIncrementDecrementOperand(Arg, OpLoc,
Opc == UnaryOperator::PostInc);
if (result.isNull())
return true;
return new UnaryOperator(Arg, Opc, result, OpLoc);
@ -2762,12 +2763,20 @@ QualType Sema::CheckCommaOperands(Expr *LHS, Expr *&RHS, SourceLocation Loc) {
/// CheckIncrementDecrementOperand - unlike most "Check" methods, this routine
/// doesn't need to call UsualUnaryConversions or UsualArithmeticConversions.
QualType Sema::CheckIncrementDecrementOperand(Expr *Op, SourceLocation OpLoc) {
QualType Sema::CheckIncrementDecrementOperand(Expr *Op, SourceLocation OpLoc,
bool isInc) {
QualType ResType = Op->getType();
assert(!ResType.isNull() && "no type for increment/decrement expression");
// C99 6.5.2.4p1: We allow complex as a GCC extension.
if (ResType->isRealType()) {
if (getLangOptions().CPlusPlus && ResType->isBooleanType()) {
// Decrement of bool is not allowed.
if (!isInc) {
Diag(OpLoc, diag::err_decrement_bool) << Op->getSourceRange();
return QualType();
}
// Increment of bool sets it to true, but is deprecated.
Diag(OpLoc, diag::warn_increment_bool) << Op->getSourceRange();
} else if (ResType->isRealType()) {
// OK!
} else if (const PointerType *PT = ResType->getAsPointerType()) {
// C99 6.5.2.4p2, 6.5.6p2
@ -3350,7 +3359,8 @@ Action::ExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
assert(0 && "Unimplemented unary expr!");
case UnaryOperator::PreInc:
case UnaryOperator::PreDec:
resultType = CheckIncrementDecrementOperand(Input, OpLoc);
resultType = CheckIncrementDecrementOperand(Input, OpLoc,
Opc == UnaryOperator::PreInc);
break;
case UnaryOperator::AddrOf:
resultType = CheckAddressOfOperand(Input, OpLoc);

View File

@ -5,3 +5,12 @@ enum {
ReadWrite = false,
ReadOnly = true
};
// bool cannot be decremented, and gives a warning on increment
void test(bool b)
{
++b; // expected-warning {{incrementing expression of type bool is deprecated}}
b++; // expected-warning {{incrementing expression of type bool is deprecated}}
--b; // expected-error {{cannot decrement expression of type bool}}
b--; // expected-error {{cannot decrement expression of type bool}}
}

View File

@ -548,9 +548,9 @@ welcome!</p>
<td>&nbsp;&nbsp;&nbsp;&nbsp;5.2.6 [expr.post.incr]</td>
<td class="complete" align="center">&#x2713;</td>
<td class="complete" align="center">&#x2713;</td>
<td class="advanced"></td>
<td class="complete" align="center">&#x2713;</td>
<td></td>
<td></td>
<td>Decrement of bool is accepted, increment not warned about</td>
</tr>
<tr>
<td>&nbsp;&nbsp;&nbsp;&nbsp;5.2.7 [expr.dynamic.cast]</td>
@ -646,9 +646,9 @@ welcome!</p>
<td>&nbsp;&nbsp;&nbsp;&nbsp;5.3.2 [expr.pre.incr]</td>
<td class="complete" align="center">&#x2713;</td>
<td class="complete" align="center">&#x2713;</td>
<td class="advanced"></td>
<td class="complete" align="center">&#x2713;</td>
<td></td>
<td></td>
<td>Decrement of bool is accepted, increment not warned about</td>
</tr>
<tr>
<td>&nbsp;&nbsp;&nbsp;&nbsp;5.3.3 [expr.sizeof]</td>