From: Richard Smith Date: Tue, 20 Dec 2011 22:56:20 +0000 (+0000) Subject: PR11297: Provide a better diagnostic for code which contains a X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a44854a23b3f090729d82f447aa88df4f6563263;p=clang PR11297: Provide a better diagnostic for code which contains a reasonable-looking but ill-formed for-range statement of the form: for (expression : expression) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147006 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 0f5fb58ac7..74c4418ce6 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -244,6 +244,8 @@ def ext_for_range : ExtWarn< def warn_cxx98_compat_for_range : Warning< "range-based for loop is incompatible with C++98">, InGroup, DefaultIgnore; +def err_for_range_expected_decl : Error< + "for range declaration must declare a variable">; def err_argument_required_after_attribute : Error< "argument required after attribute">; def err_missing_param : Error<"expected parameter declarator">; diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 435bde3375..13b3bdaf74 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -1371,6 +1371,14 @@ StmtResult Parser::ParseForStatement(ParsedAttributes &attrs) { return StmtError(); } Collection = ParseExpression(); + } else if (getLang().CPlusPlus0x && Tok.is(tok::colon) && + !FirstPart.isInvalid()) { + // User tried to write the reasonable, but ill-formed, for-range-statement + // for (expr : expr) { ... } + Diag(Tok, diag::err_for_range_expected_decl) + << FirstPart.get()->getSourceRange(); + SkipUntil(tok::r_paren, false, true); + SecondPartIsInvalid = true; } else { if (!Value.isInvalid()) { Diag(Tok, diag::err_expected_semi_for); diff --git a/test/Parser/cxx0x-for-range.cpp b/test/Parser/cxx0x-for-range.cpp new file mode 100644 index 0000000000..f920ef9085 --- /dev/null +++ b/test/Parser/cxx0x-for-range.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +template +struct pair {}; + +template +struct map { + typedef pair *iterator; + iterator begin(); + iterator end(); +}; + +template +pair &tie(T &, U &); + +int foo(map &m) { + char *p; + int n; + + for (pair x : m) { + (void)x; + } + + for (tie(p, n) : m) { // expected-error {{for range declaration must declare a variable}} + (void)p; + (void)n; + } + + return n; +}