[PATCH] Suggest fix-it ':' when '=' used in for-range-declaration while initializing an auto
Ismail Pazarbasi
ismail.pazarbasi at gmail.com
Mon Apr 14 13:04:42 PDT 2014
Hi dblaikie, bkramer,
I patched this during an evening at ACCU 2014 last week, but seems like I forgot to send it.
This is fix for PR19176:
int arr[] = {1, 2, 3, 4};
for (auto i = arr)
(void)i;
possibly meant:
for (auto i : arr)
This is going to be issued iff for range declaration begins with auto keyword in C++11 mode.
http://reviews.llvm.org/D3370
Files:
include/clang/Basic/DiagnosticParseKinds.td
lib/Parse/ParseStmt.cpp
test/Parser/cxx0x-for-range.cpp
Index: include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- include/clang/Basic/DiagnosticParseKinds.td
+++ include/clang/Basic/DiagnosticParseKinds.td
@@ -204,6 +204,8 @@
def err_expected_semi_after_static_assert : Error<
"expected ';' after static_assert">;
def err_expected_semi_for : Error<"expected ';' in 'for' statement specifier">;
+def note_invalid_for_range : Note<
+ "range based for statement requires ':' after range declaration">;
def warn_missing_selector_name : Warning<
"%0 used as the name of the previous parameter rather than as part "
"of the selector">,
Index: lib/Parse/ParseStmt.cpp
===================================================================
--- lib/Parse/ParseStmt.cpp
+++ lib/Parse/ParseStmt.cpp
@@ -1469,8 +1469,16 @@
if (!C99orCXXorObjC) // Use of C99-style for loops in C90 mode?
Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
+ const bool RangeInitIsAuto = Tok.is(tok::kw_auto);
// In C++0x, "for (T NS:a" might not be a typo for ::
- bool MightBeForRangeStmt = getLangOpts().CPlusPlus;
+ const bool MightBeForRangeStmt = getLangOpts().CPlusPlus;
+ SourceLocation EqualLoc;
+ if (MightBeForRangeStmt && RangeInitIsAuto) {
+ TentativeParsingAction FindEqual(*this);
+ if (SkipUntil(tok::equal, StopAtSemi | StopBeforeMatch))
+ EqualLoc = Tok.getLocation();
+ FindEqual.Revert();
+ }
ColonProtectionRAIIObject ColonProtection(*this, MightBeForRangeStmt);
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
@@ -1501,6 +1509,9 @@
Collection = ParseExpression();
} else {
Diag(Tok, diag::err_expected_semi_for);
+ if (getLangOpts().CPlusPlus11 && RangeInitIsAuto && EqualLoc.isValid())
+ Diag(EqualLoc, diag::note_invalid_for_range)
+ << FixItHint::CreateReplacement(EqualLoc, ":");
}
} else {
ProhibitAttributes(attrs);
Index: test/Parser/cxx0x-for-range.cpp
===================================================================
--- test/Parser/cxx0x-for-range.cpp
+++ test/Parser/cxx0x-for-range.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -std=c++11 %s 2>&1 | FileCheck %s
template<typename T, typename U>
struct pair {};
@@ -28,3 +28,31 @@
return n;
}
+
+namespace PR19176 {
+struct Vector {
+ struct iterator {
+ int &operator*();
+ iterator &operator++();
+ iterator &operator++(int);
+ bool operator==(const iterator &) const;
+ };
+ iterator begin();
+ iterator end();
+};
+
+void f() {
+ Vector v;
+ int a[] = {1, 2, 3, 4};
+ for (auto foo = a) // expected-error {{expected ';' in 'for' statement specifier}}
+ // expected-note at -1 {{range based for statement requires ':' after range declaration}}
+ // expected-error at -2 {{expected ';' in 'for' statement specifier}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:18}:":"
+ (void)foo;
+ for (auto i = v) // expected-error {{expected ';' in 'for' statement specifier}}
+ // expected-note at -1 {{range based for statement requires ':' after range declaration}}
+ // expected-error at -2 {{expected ';' in 'for' statement specifier}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:15-[[@LINE-3]]:16}:":"
+ (void)i;
+}
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3370.1.patch
Type: text/x-patch
Size: 3376 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140414/d3ac0776/attachment.bin>
More information about the cfe-commits
mailing list