On Fri, Oct 11, 2013 at 3:16 PM, Richard Trieu <[email protected]> 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@-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@-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 > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
