<div dir="ltr">On Fri, Oct 11, 2013 at 3:16 PM, Richard Trieu <span dir="ltr"><<a href="mailto:rtrieu@google.com" target="_blank">rtrieu@google.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rtrieu<br>
Date: Fri Oct 11 17:16:04 2013<br>
New Revision: 192512<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=192512&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=192512&view=rev</a><br>
Log:<br>
Improve the error message for attempting to build a for range loop using a<br>
function parameter that has array type.  Such a parameter will be treated as<br>
a pointer type instead, resulting in a missing begin function error is a<br>
suggestion to dereference the pointer.  This provides a different,<br>
more informative diagnostic as well as point to the parameter declaration.<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
    cfe/trunk/lib/Sema/SemaStmt.cpp<br>
    cfe/trunk/test/SemaCXX/for-range-examples.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=192512&r1=192511&r2=192512&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=192512&r1=192511&r2=192512&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Oct 11 17:16:04 2013<br>
@@ -1623,6 +1623,9 @@ def note_in_for_range: Note<<br>
 def err_for_range_invalid: Error<<br>
   "invalid range expression of type %0; no viable '%select{begin|end}1' "<br>
   "function available">;<br>
+def err_range_on_array_parameter : Error<<br>
+  "cannot build range expression with array function parameter %0 since "<br>
+  "parameter with array type %1 is treated as pointer type %2">;<br>
 def err_for_range_dereference : Error<<br>
   "invalid range expression of type %0; did you mean to dereference it "<br>
   "with '*'?">;<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=192512&r1=192511&r2=192512&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=192512&r1=192511&r2=192512&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Fri Oct 11 17:16:04 2013<br>
@@ -2131,10 +2131,25 @@ Sema::BuildCXXForRangeStmt(SourceLocatio<br>
                                 BeginVar, EndVar, ColonLoc, &CandidateSet,<br>
                                 &BeginExpr, &EndExpr, &BEFFailure);<br>
<br>
-      // If building the range failed, try dereferencing the range expression<br>
-      // unless a diagnostic was issued or the end function is problematic.<br>
       if (Kind == BFRK_Build && RangeStatus == FRS_NoViableFunction &&<br>
           BEFFailure == BEF_begin) {<br>
+        // If the range is being built from an array parameter, emit a<br>
+        // a diagnostic that it is being treated as a pointer.<br>
+        if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Range)) {<br></blockquote><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+          if (ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {<br>
+            QualType ArrayTy = PVD->getOriginalType();<br>
+            QualType PointerTy = PVD->getType();<br>
+            if (PointerTy->isPointerType() && ArrayTy->isArrayType()) {<br></blockquote><div><br></div><div>FYI, you can write this a little more elegantly as:</div><div><br></div><div>if (DecayedType *DT = DRE->getType()->getAs<DecayedType>()) {</div>
<div>  if (DT->getOriginalType()->isArrayType()) {</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+              Diag(Range->getLocStart(), diag::err_range_on_array_parameter)<br>
+                << RangeLoc << PVD << ArrayTy << PointerTy;<br>
+              Diag(PVD->getLocation(), diag::note_declared_at);<br>
+              return StmtError();<br>
+            }<br>
+          }<br>
+        }<br>
+<br>
+        // If building the range failed, try dereferencing the range expression<br>
+        // unless a diagnostic was issued or the end function is problematic.<br>
         StmtResult SR = RebuildForRangeWithDereference(*this, S, ForLoc,<br>
                                                        LoopVarDecl, ColonLoc,<br>
                                                        Range, RangeLoc,<br>
<br>
Modified: cfe/trunk/test/SemaCXX/for-range-examples.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/for-range-examples.cpp?rev=192512&r1=192511&r2=192512&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/for-range-examples.cpp?rev=192512&r1=192511&r2=192512&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/SemaCXX/for-range-examples.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/for-range-examples.cpp Fri Oct 11 17:16:04 2013<br>
@@ -191,3 +191,21 @@ namespace test5 {<br>
       x->foo();<br>
   }<br>
 }<br>
+<br>
+namespace test6 {<br>
+  void foo(int arr[]) {  // expected-note {{declared here}}<br>
+    for (auto i : arr) { }<br>
+      // expected-error@-1 {{cannot build range expression with array function parameter 'arr' since parameter with array type 'int []' is treated as pointer type 'int *'}}<br>
+  }<br>
+<br>
+  struct vector {<br>
+    int *begin() { return 0; }<br>
+    int *end() { return 0; }<br>
+  };<br>
+<br>
+  void foo(vector arr[]) {  // expected-note {{declared here}}<br>
+    // Don't suggest to dereference arr.<br>
+    for (auto i : arr) { }<br>
+      // expected-error@-1 {{cannot build range expression with array function parameter 'arr' since parameter with array type 'test6::vector []' is treated as pointer type 'test6::vector *'}}<br>

+  }<br>
+}<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>