aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Panzer <espanz@gmail.com>2012-09-06 21:50:08 +0000
committerSam Panzer <espanz@gmail.com>2012-09-06 21:50:08 +0000
commit8123b6e7838216a53ba050f07e36fee28e1bbdaf (patch)
tree3945c56d13a9cc2c3fbf7e3b05221b353d25c7ab
parent200fa2e70d52ae6d620e81cd45536071fdde70c0 (diff)
Clarified diagnostics for range-based for loops with invalid ranges
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163350 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--lib/Sema/SemaStmt.cpp6
-rw-r--r--test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp19
3 files changed, 24 insertions, 3 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index b10e8cb008..75c98b1159 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/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/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 76410e20ac..17d1de81e7 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/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/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
index 66e30f5dc6..6c6fe09165 100644
--- a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
+++ b/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 {