diff options
| author | Sam Panzer <espanz@gmail.com> | 2012-09-06 21:50:08 +0000 |
|---|---|---|
| committer | Sam Panzer <espanz@gmail.com> | 2012-09-06 21:50:08 +0000 |
| commit | 22a3fe1b9c95e0fb4500593af2d47005b3a2d955 (patch) | |
| tree | d604bb0143dd9275c9bfca12962d2df04d0577a3 | |
| parent | 33fa1df67dd7c139f93ba9993f9bec424a4dbfb4 (diff) | |
| download | bcm5719-llvm-22a3fe1b9c95e0fb4500593af2d47005b3a2d955.tar.gz bcm5719-llvm-22a3fe1b9c95e0fb4500593af2d47005b3a2d955.zip | |
Clarified diagnostics for range-based for loops with invalid ranges
llvm-svn: 163350
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 6 | ||||
| -rw-r--r-- | clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp | 19 |
3 files changed, 24 insertions, 3 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index b10e8cb0085..75c98b1159a 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1430,6 +1430,8 @@ def err_for_range_invalid: Error< def err_for_range_dereference : Error< "invalid range expression of type %0; did you mean to dereference it " "with '*'?">; +def note_for_range_invalid_iterator : Note < + "in implicit call to 'operator%select{!=|*|++}0' for iterator of type %1">; def note_for_range_begin_end : Note< "selected '%select{begin|end}0' %select{function|template }1%2 with iterator type %3">; diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 76410e20aca..17d1de81e75 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -1966,6 +1966,8 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc, NotEqExpr = ActOnBooleanCondition(S, ColonLoc, NotEqExpr.get()); NotEqExpr = ActOnFinishFullExpr(NotEqExpr.get()); if (NotEqExpr.isInvalid()) { + Diag(RangeLoc, diag::note_for_range_invalid_iterator) + << RangeLoc << 0 << BeginRangeRef.get()->getType(); NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin); if (!Context.hasSameType(BeginType, EndType)) NoteForRangeBeginEndFunction(*this, EndExpr.get(), BEF_end); @@ -1981,6 +1983,8 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc, IncrExpr = ActOnUnaryOp(S, ColonLoc, tok::plusplus, BeginRef.get()); IncrExpr = ActOnFinishFullExpr(IncrExpr.get()); if (IncrExpr.isInvalid()) { + Diag(RangeLoc, diag::note_for_range_invalid_iterator) + << RangeLoc << 2 << BeginRangeRef.get()->getType() ; NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin); return StmtError(); } @@ -1993,6 +1997,8 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc, ExprResult DerefExpr = ActOnUnaryOp(S, ColonLoc, tok::star, BeginRef.get()); if (DerefExpr.isInvalid()) { + Diag(RangeLoc, diag::note_for_range_invalid_iterator) + << RangeLoc << 1 << BeginRangeRef.get()->getType(); NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin); return StmtError(); } diff --git a/clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp b/clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp index 66e30f5dc63..6c6fe091656 100644 --- a/clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp +++ b/clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp @@ -129,14 +129,15 @@ void g() { }; for (auto u : NoBegin()) { // expected-error {{range type 'NoBegin' has 'end' member but no 'begin' member}} } - for (auto u : NoEnd()) { // expected-error {{range type 'NoEnd' has 'begin' member but no 'end' member}} + for (auto u : NoEnd()) { // expected-error {{range type 'NoEnd' has 'begin' member but no 'end' member}} } struct NoIncr { void *begin(); // expected-note {{selected 'begin' function with iterator type 'void *'}} void *end(); }; - for (auto u : NoIncr()) { // expected-error {{arithmetic on a pointer to void}} + for (auto u : NoIncr()) { // expected-error {{arithmetic on a pointer to void}}\ + expected-note {{in implicit call to 'operator++' for iterator of type 'NoIncr'}} } struct NoNotEq { @@ -144,7 +145,19 @@ void g() { NoNotEq end(); void operator++(); }; - for (auto u : NoNotEq()) { // expected-error {{invalid operands to binary expression}} + for (auto u : NoNotEq()) { // expected-error {{invalid operands to binary expression}}\ + expected-note {{in implicit call to 'operator!=' for iterator of type 'NoNotEq'}} + } + + struct NoDeref { + NoDeref begin(); // expected-note {{selected 'begin' function}} + NoDeref end(); + void operator++(); + bool operator!=(NoDeref &); + }; + + for (auto u : NoDeref()) { // expected-error {{indirection requires pointer operand}} \ + expected-note {{in implicit call to 'operator*' for iterator of type 'NoDeref'}} } struct NoCopy { |

