diff options
| author | Richard Trieu <rtrieu@google.com> | 2013-08-08 01:50:23 +0000 |
|---|---|---|
| committer | Richard Trieu <rtrieu@google.com> | 2013-08-08 01:50:23 +0000 |
| commit | 493df1a14f5dc5267a029c6ff58018efe0647297 (patch) | |
| tree | 2f383d3265b034f2ae2cbe84fab473f2b768942a | |
| parent | d25f7fc4aeca0c4a2ff66abc9d44f8875a178979 (diff) | |
| download | bcm5719-llvm-493df1a14f5dc5267a029c6ff58018efe0647297.tar.gz bcm5719-llvm-493df1a14f5dc5267a029c6ff58018efe0647297.zip | |
Emit an error for enum increments and decrements in C++ mode.
Fixes PR16394.
llvm-svn: 187955
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 4 | ||||
| -rw-r--r-- | clang/test/Sema/enum-increment.c | 13 | ||||
| -rw-r--r-- | clang/test/SemaCXX/enum-increment.cpp | 16 |
4 files changed, 35 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 12ddc6b8a1c..20b2a40cb08 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4882,6 +4882,8 @@ def note_member_declared_here : Note< def err_decrement_bool : Error<"cannot decrement expression of type bool">; def warn_increment_bool : Warning< "incrementing expression of type bool is deprecated">, InGroup<Deprecated>; +def err_increment_decrement_enum : Error< + "cannot %select{decrement|increment}0 expression of enum type %1">; def err_catch_incomplete_ptr : Error< "cannot catch pointer to incomplete type %0">; def err_catch_incomplete_ref : Error< diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 8038a4502ab..8515cb2f53f 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -8377,6 +8377,10 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op, } // Increment of bool sets it to true, but is deprecated. S.Diag(OpLoc, diag::warn_increment_bool) << Op->getSourceRange(); + } else if (S.getLangOpts().CPlusPlus && ResType->isEnumeralType()) { + // Error on enum increments and decrements in C++ mode + S.Diag(OpLoc, diag::err_increment_decrement_enum) << IsInc << ResType; + return QualType(); } else if (ResType->isRealType()) { // OK! } else if (ResType->isPointerType()) { diff --git a/clang/test/Sema/enum-increment.c b/clang/test/Sema/enum-increment.c new file mode 100644 index 00000000000..baaa3489b95 --- /dev/null +++ b/clang/test/Sema/enum-increment.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only %s -verify +// expected-no-diagnostics +enum A { A1, A2, A3 }; +typedef enum A A; +void test() { + A a; + a++; + a--; + ++a; + --a; + a = a + 1; + a = a - 1; +} diff --git a/clang/test/SemaCXX/enum-increment.cpp b/clang/test/SemaCXX/enum-increment.cpp new file mode 100644 index 00000000000..dc1a921852e --- /dev/null +++ b/clang/test/SemaCXX/enum-increment.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsyntax-only %s -verify + +enum A { A1, A2, A3 }; +void test() { + A a; + a++; // expected-error{{cannot increment expression of enum type 'A'}} + a--; // expected-error{{cannot decrement expression of enum type 'A'}} + ++a; // expected-error{{cannot increment expression of enum type 'A'}} + --a; // expected-error{{cannot decrement expression of enum type 'A'}} +} + +enum B {B1, B2}; +inline B &operator++ (B &b) { b = B((int)b+1); return b; } +inline B operator++ (B &b, int) { B ret = b; ++b; return b; } + +void foo(enum B b) { ++b; b++; } |

