]> granicus.if.org Git - clang/commitdiff
Implement checks for bool in increment and decrement.
authorSebastian Redl <sebastian.redl@getdesigned.at>
Sat, 20 Dec 2008 09:35:34 +0000 (09:35 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Sat, 20 Dec 2008 09:35:34 +0000 (09:35 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61275 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticKinds.def
lib/Sema/Sema.h
lib/Sema/SemaExpr.cpp
test/SemaCXX/bool.cpp
www/cxx_status.html

index 6b11d31701dcdf9c7ee8b4de0c08bc7e8d98f032..b1c5cbdaa8d81b28db5b13a98e4c61fe950ef653 100644 (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")
index 56b681c07055a8059ca670403496445737bf06cd..9cab3308c57630ef6340252c728b14aa02b3606b 100644 (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);
index da0354886c1d8c354b4b5a800dcea1a11256e0eb..51e4e05eec8fdde4b6c617a40a4934be188e8ea0 100644 (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);
index e35495ababfa617444bd1f4d9f5b670e551706e7..e606a518d7f5f403bda8092767bd8f757e922046 100644 (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}}
+}
index 2bb64e9a718b50c64423f21a0247a9f304f4e6fe..8748a0e605f773761e024f443042cc20f01e4c80 100644 (file)
@@ -548,9 +548,9 @@ welcome!</p>
   <td>&nbsp;&nbsp;&nbsp;&nbsp;5.2.6 [expr.post.incr]</td>\r
   <td class="complete" align="center">&#x2713;</td>\r
   <td class="complete" align="center">&#x2713;</td>\r
-  <td class="advanced"></td>\r
+  <td class="complete" align="center">&#x2713;</td>\r
+  <td></td>\r
   <td></td>\r
-  <td>Decrement of bool is accepted, increment not warned about</td>\r
 </tr>\r
 <tr>\r
   <td>&nbsp;&nbsp;&nbsp;&nbsp;5.2.7 [expr.dynamic.cast]</td>\r
@@ -646,9 +646,9 @@ welcome!</p>
   <td>&nbsp;&nbsp;&nbsp;&nbsp;5.3.2 [expr.pre.incr]</td>\r
   <td class="complete" align="center">&#x2713;</td>\r
   <td class="complete" align="center">&#x2713;</td>\r
-  <td class="advanced"></td>\r
+  <td class="complete" align="center">&#x2713;</td>\r
+  <td></td>\r
   <td></td>\r
-  <td>Decrement of bool is accepted, increment not warned about</td>\r
 </tr>\r
 <tr>\r
   <td>&nbsp;&nbsp;&nbsp;&nbsp;5.3.3 [expr.sizeof]</td>\r