[cfe-commits] r125714 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp test/SemaCXX/member-expr.cpp

Matt Beaumont-Gay matthewbg at google.com
Wed Feb 16 22:27:59 PST 2011


On Wed, Feb 16, 2011 at 19:34, Douglas Gregor <dgregor at apple.com> wrote:
>
> On Feb 16, 2011, at 6:54 PM, Matt Beaumont-Gay wrote:
>
>> Author: matthewbg
>> Date: Wed Feb 16 20:54:17 2011
>> New Revision: 125714
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=125714&view=rev
>> Log:
>> Fix PR9025 and add a diagnostic (and sometimes a fixit) for an overloaded
>> function name used as the base of a member expression. Early feedback from
>> Chandler Carruth, and code review from Nick Lewycky.
>
> Thanks for working on this. A few comments below...
>
>> Modified:
>>    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>>    cfe/trunk/lib/Sema/SemaExpr.cpp
>>    cfe/trunk/test/SemaCXX/member-expr.cpp
>>
>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=125714&r1=125713&r2=125714&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Feb 16 20:54:17 2011
>> @@ -2364,6 +2364,11 @@
>> def err_typecheck_member_reference_unknown : Error<
>>   "cannot refer to member %0 in %1 with '%select{.|->}2'">;
>> def err_member_reference_needs_call : Error<
>> +  "base of member reference is an overloaded function; perhaps you meant "
>> +  "to call %select{it|the 0-argument overload}0?">;
>> +def note_member_ref_possible_intended_overload : Note<
>> +  "possibly valid overload here">;
>> +def err_member_reference_needs_call_zero_arg : Error<
>>   "base of member reference has function type %0; perhaps you meant to call "
>>   "this function with '()'?">;
>> def warn_subscript_is_char : Warning<"array subscript is of type 'char'">,
>>
>> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=125714&r1=125713&r2=125714&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Feb 16 20:54:17 2011
>> @@ -3995,6 +3995,8 @@
>>
>>   // There's a possible road to recovery for function types.
>>   const FunctionType *Fun = 0;
>> +  SourceLocation ParenInsertionLoc =
>> +      PP.getLocForEndOfToken(BaseExpr->getLocEnd());
>>
>>   if (const PointerType *Ptr = BaseType->getAs<PointerType>()) {
>>     if ((Fun = Ptr->getPointeeType()->getAs<FunctionType>())) {
>> @@ -4029,7 +4031,53 @@
>>   if (Fun || BaseType == Context.OverloadTy) {
>>     bool TryCall;
>>     if (BaseType == Context.OverloadTy) {
>> -      TryCall = true;
>> +      // Plunder the overload set for something that would make the member
>> +      // expression valid.
>> +      const OverloadExpr *Overloads = cast<OverloadExpr>(BaseExpr);
>> +      UnresolvedSet<4> CandidateOverloads;
>> +      bool HasZeroArgCandidateOverload = false;
>> +      for (OverloadExpr::decls_iterator it = Overloads->decls_begin(),
>> +           DeclsEnd = Overloads->decls_end(); it != DeclsEnd; ++it) {
>> +        const FunctionDecl *OverloadDecl = cast<FunctionDecl>(*it);
>> +        QualType ResultTy = OverloadDecl->getResultType();
>> +        if ((!IsArrow && ResultTy->isRecordType()) ||
>> +            (IsArrow && ResultTy->isPointerType() &&
>> +             ResultTy->getPointeeType()->isRecordType())) {
>> +          CandidateOverloads.addDecl(*it);
>> +          if (OverloadDecl->getNumParams() == 0) {
>> +            HasZeroArgCandidateOverload = true;
>> +          }
>
> OverloadDecl->getMinRequiredArguments() == 0 would be better here, since it accounts for parameter packs and default arguments.

Thanks, I'll submit a patch for this tomorrow.

>
> Overall, it would be great to pull the "find a function that we could call with ()" logic out into a subroutine, because there are probably a number of other places where we'd like to have the same kind of recovery.

Do you have any suggestions about what interface this subroutine
should have? As a strawman: UnresolvedSet::iterator
FindZeroArgCall(const UnresolvedSet& Candidates)

-Matt




More information about the cfe-commits mailing list