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