r192512 - Improve the error message for attempting to build a for range loop using a

Richard Smith richard at metafoo.co.uk
Fri Oct 11 15:32:29 PDT 2013


On Fri, Oct 11, 2013 at 3:16 PM, Richard Trieu <rtrieu at google.com> wrote:

> Author: rtrieu
> Date: Fri Oct 11 17:16:04 2013
> New Revision: 192512
>
> URL: http://llvm.org/viewvc/llvm-project?rev=192512&view=rev
> Log:
> Improve the error message for attempting to build a for range loop using a
> function parameter that has array type.  Such a parameter will be treated
> as
> a pointer type instead, resulting in a missing begin function error is a
> suggestion to dereference the pointer.  This provides a different,
> more informative diagnostic as well as point to the parameter declaration.
>
> Modified:
>     cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>     cfe/trunk/lib/Sema/SemaStmt.cpp
>     cfe/trunk/test/SemaCXX/for-range-examples.cpp
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=192512&r1=192511&r2=192512&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Oct 11
> 17:16:04 2013
> @@ -1623,6 +1623,9 @@ def note_in_for_range: Note<
>  def err_for_range_invalid: Error<
>    "invalid range expression of type %0; no viable '%select{begin|end}1' "
>    "function available">;
> +def err_range_on_array_parameter : Error<
> +  "cannot build range expression with array function parameter %0 since "
> +  "parameter with array type %1 is treated as pointer type %2">;
>  def err_for_range_dereference : Error<
>    "invalid range expression of type %0; did you mean to dereference it "
>    "with '*'?">;
>
> Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=192512&r1=192511&r2=192512&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaStmt.cpp Fri Oct 11 17:16:04 2013
> @@ -2131,10 +2131,25 @@ Sema::BuildCXXForRangeStmt(SourceLocatio
>                                  BeginVar, EndVar, ColonLoc, &CandidateSet,
>                                  &BeginExpr, &EndExpr, &BEFFailure);
>
> -      // If building the range failed, try dereferencing the range
> expression
> -      // unless a diagnostic was issued or the end function is
> problematic.
>        if (Kind == BFRK_Build && RangeStatus == FRS_NoViableFunction &&
>            BEFFailure == BEF_begin) {
> +        // If the range is being built from an array parameter, emit a
> +        // a diagnostic that it is being treated as a pointer.
> +        if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Range)) {
>

+          if (ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
> +            QualType ArrayTy = PVD->getOriginalType();
> +            QualType PointerTy = PVD->getType();
> +            if (PointerTy->isPointerType() && ArrayTy->isArrayType()) {
>

FYI, you can write this a little more elegantly as:

if (DecayedType *DT = DRE->getType()->getAs<DecayedType>()) {
  if (DT->getOriginalType()->isArrayType()) {

+              Diag(Range->getLocStart(),
> diag::err_range_on_array_parameter)
> +                << RangeLoc << PVD << ArrayTy << PointerTy;
> +              Diag(PVD->getLocation(), diag::note_declared_at);
> +              return StmtError();
> +            }
> +          }
> +        }
> +
> +        // If building the range failed, try dereferencing the range
> expression
> +        // unless a diagnostic was issued or the end function is
> problematic.
>          StmtResult SR = RebuildForRangeWithDereference(*this, S, ForLoc,
>                                                         LoopVarDecl,
> ColonLoc,
>                                                         Range, RangeLoc,
>
> Modified: cfe/trunk/test/SemaCXX/for-range-examples.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/for-range-examples.cpp?rev=192512&r1=192511&r2=192512&view=diff
>
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/for-range-examples.cpp (original)
> +++ cfe/trunk/test/SemaCXX/for-range-examples.cpp Fri Oct 11 17:16:04 2013
> @@ -191,3 +191,21 @@ namespace test5 {
>        x->foo();
>    }
>  }
> +
> +namespace test6 {
> +  void foo(int arr[]) {  // expected-note {{declared here}}
> +    for (auto i : arr) { }
> +      // expected-error at -1 {{cannot build range expression with array
> function parameter 'arr' since parameter with array type 'int []' is
> treated as pointer type 'int *'}}
> +  }
> +
> +  struct vector {
> +    int *begin() { return 0; }
> +    int *end() { return 0; }
> +  };
> +
> +  void foo(vector arr[]) {  // expected-note {{declared here}}
> +    // Don't suggest to dereference arr.
> +    for (auto i : arr) { }
> +      // expected-error at -1 {{cannot build range expression with array
> function parameter 'arr' since parameter with array type 'test6::vector []'
> is treated as pointer type 'test6::vector *'}}
> +  }
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131011/a02d2ea1/attachment.html>


More information about the cfe-commits mailing list