[cfe-commits] [patch] Better diagnostics in for-range expressions.
Richard Smith
richard at metafoo.co.uk
Mon Aug 20 16:37:31 PDT 2012
Couple of tiny things, then LGTM:
+ *CallExpr = FinishOverloadedCallExpr(*this, S, Fn, Fn, Loc, &Range, 1,
+ Loc, 0, CandidateSet, &Best,
+ OverloadResult,
+ /*AllowTypoCorrection=*/false);
+ if (CallExpr->isInvalid() || OverloadResult == OR_Deleted) {
The second condition would be clearer as OverloadResult != OR_Success.
+ ForRangeStatus RangeStatus =
+ BuildNonArrayForRange(*this, S, BeginRangeRef.get(),
+ EndRangeRef.get(), RangeType,
+ 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 (RangeStatus != FRS_Success) {
This 'if' is now redundant; all the code within it is conditioned within
'if (RangeStatus == FRS_NoViableFunction)'. I suggest you change this to
check for FRS_NoViableFunction and remove the newly-redundant inner checks.
On Mon, Aug 20, 2012 at 3:43 PM, Sam Panzer <panzer at google.com> wrote:
> New patch is ~10% smaller!
>
>
> On Thu, Aug 16, 2012 at 3:14 PM, Richard Smith <richard at metafoo.co.uk>wrote:
>
>> On Thu, Aug 16, 2012 at 2:56 PM, Sam Panzer <panzer at google.com> wrote:
>>
>>> Here's the next update for this patch.
>>>
>>>
>>> On Wed, Aug 15, 2012 at 4:29 PM, Richard Smith <richard at metafoo.co.uk>wrote:
>>>
>> [...]
>>
>>> > + if (CXXRecordDecl *D = RangeType->getAsCXXRecordDecl()) {
>>>
>>> > + // - if _RangeT is a class type, the unqualified-ids begin and
>>>> end are
>>>> > + // looked up in the scope of class _RangeT as if by class
>>>> member access
>>>> > + // lookup (3.4.5), and if either (or both) finds at least one
>>>> > + // declaration, begin-expr and end-expr are __range.begin() and
>>>> > + // __range.end(), respectively;
>>>> > + SemaRef.LookupQualifiedName(BeginMemberLookup, D);
>>>> > + SemaRef.LookupQualifiedName(EndMemberLookup, D);
>>>> > +
>>>> > + if (BeginMemberLookup.empty() != EndMemberLookup.empty()) {
>>>> > + *BEF = BeginMemberLookup.empty() ? Sema::BEF_end :
>>>> Sema::BEF_begin;
>>>> > + return Sema::FRS_BeginEndMismatch;
>>>>
>>>> Can you just issue the diagnostic directly here? I don't think we
>>>> should attempt recovery in this case. (My "If there's a viable begin() but
>>>> lookup for end() fails" comment was intended to apply to this case too.)
>>>>
>>>>
>>> Yes, though this means that I have two "diagnostic emitted" error codes:
>>> one which needs the type and which of begin/end failed to be noted, and a
>>> second which needs no extra diagnostics.
>>>
>>
>> I think previously I suggested that you should emit note_for_range_type
>> directly in BuildForRangeBeginEndCall; that still seems like the best way
>> to address this. I would also suggest that you don't emit the note in the
>> case where FinishForRangeVarDecl fails, since in that case we've already
>> emitted a diagnostic explaining what we're doing.
>>
>>
>
> This wasn't possible before introducing SFINAETrap, though it simplifies
> the code now as you suggest. After a little adjusting, I moved
> NoteForRangeBeginEndFunction and FinishForRangeVarDecl back out of Sema.
>
>
>
>> > + }
>>>> > + } else {
>>>> > + // - otherwise, begin-expr and end-expr are begin(__range) and
>>>> > + // end(__range), respectively, where begin and end are looked
>>>> up with
>>>> > + // argument-dependent lookup (3.4.2). For the purposes of this
>>>> name
>>>> > + // lookup, namespace std is an associated namespace.
>>>> > +
>>>> > + }
>>>> > +
>>>> > + *BEF = Sema::BEF_begin;
>>>> > + Sema::ForRangeStatus RangeStatus =
>>>> > + SemaRef.BuildForRangeBeginEndCall(S, ColonLoc, ColonLoc,
>>>> BeginVar,
>>>> > + Sema::BEF_begin,
>>>> BeginNameInfo,
>>>> > + BeginMemberLookup,
>>>> CandidateSet,
>>>> > + BeginRange, BeginExpr);
>>>> > + if (RangeStatus != Sema::FRS_Success)
>>>> > + return RangeStatus;
>>>> > +
>>>> > + *BEF = Sema::BEF_end;
>>>> > + RangeStatus =
>>>> > + SemaRef.BuildForRangeBeginEndCall(S, ColonLoc, ColonLoc,
>>>> EndVar,
>>>> > + Sema::BEF_end, EndNameInfo,
>>>> > + EndMemberLookup,
>>>> CandidateSet,
>>>> > + EndRange, EndExpr);
>>>> > + return RangeStatus;
>>>> > +}
>>>> > +
>>>> > +/// Speculatively attempt to dereference an invalid range expression.
>>>> > +/// This function will not emit diagnostics, but returns StmtError if
>>>> > +/// an error occurs.
>>>> > +static StmtResult RetryWithDereferencedRange(Sema &SemaRef, Scope *S,
>>>>
>>>> Please include something about ForRange in this function name.
>>>>
>>>
>>> How about RebuildForRangeWithDereference?
>>>
>>
>> SGTM
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120820/287efdd3/attachment.html>
More information about the cfe-commits
mailing list