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

Chris Lattner clattner at apple.com
Thu Mar 26 23:17:42 PDT 2009


On Mar 26, 2009, at 11:00 PM, Douglas Gregor wrote:

> Author: dgregor
> Date: Fri Mar 27 01:00:30 2009
> New Revision: 67826
>
> URL: http://llvm.org/viewvc/llvm-project?rev=67826&view=rev
> Log:
> If the user is trying to apply the -> or . member reference operator
> to a function or function pointer, it's probably because the user
> forgot to put in parentheses () to call the function.

This is nice, but it should only be done when the function type in  
question returns a pointer or something that has an overloaded ->,  
right?

I wouldn't expect that advice for:

struct A {
  int f0;
};
struct B {
  int f0();
};
int f0(B *b) {
   return b->f0->f0;
}

Because b->f0() doesn't return a pointer, so inserting () would just  
lead to another error.

-Chris

>
>
> 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=67826&r1=67825&r2=67826&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Mar 27  
> 01:00:30 2009
> @@ -872,6 +872,9 @@
>   "cannot refer to type member %0 with '%select{.|->}1'">;
> def err_typecheck_member_reference_unknown : Error<
>   "cannot refer to member %0 with '%select{.|->}1'">;
> +def note_member_reference_needs_call : Note<
> +  "perhaps you meant to call this function with '()'?">;
> +
> def err_typecheck_incomplete_tag : Error<"incomplete definition of  
> type %0">;
> def err_typecheck_no_member : Error<"no member named %0">;
> def err_member_redeclared : Error<"class member cannot be  
> redeclared">;
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=67826&r1=67825&r2=67826&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Mar 27 01:00:30 2009
> @@ -2101,9 +2101,22 @@
>                                                     MemberLoc));
>   }
>
> -  return ExprError(Diag(MemberLoc,
> -                         
> diag::err_typecheck_member_reference_struct_union)
> -                     << BaseType << BaseExpr->getSourceRange());
> +  Diag(MemberLoc, diag::err_typecheck_member_reference_struct_union)
> +    << BaseType << BaseExpr->getSourceRange();
> +
> +  // If the user is trying to apply -> or . to a function or function
> +  // pointer, it's probably because they forgot parentheses to call
> +  // the function. Suggest the addition of those parentheses.
> +  if (BaseType == Context.OverloadTy ||
> +      BaseType->isFunctionType() ||
> +      (BaseType->isPointerType() &&
> +       BaseType->getAsPointerType()->isFunctionType())) {
> +    SourceLocation Loc = PP.getLocForEndOfToken(BaseExpr- 
> >getLocEnd());
> +    Diag(Loc, diag::note_member_reference_needs_call)
> +      << CodeModificationHint::CreateInsertion(Loc, "()");
> +  }
> +
> +  return ExprError();
> }
>
> /// ConvertArgumentsForCall - Converts the arguments specified in
>
> Modified: cfe/trunk/test/SemaCXX/member-expr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/member-expr.cpp?rev=67826&r1=67825&r2=67826&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/test/SemaCXX/member-expr.cpp (original)
> +++ cfe/trunk/test/SemaCXX/member-expr.cpp Fri Mar 27 01:00:30 2009
> @@ -20,3 +20,14 @@
>   float f1 = x.g();
>   float f2 = xp->g();
> }
> +
> +struct A {
> + int f0;
> +};
> +struct B {
> + A *f0();
> +};
> +int f0(B *b) {
> +  return b->f0->f0; // expected-error{{member reference base type  
> 'struct A *(void)' is not a structure or union}} \
> +  // expected-note{{perhaps you meant to call this function}}
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits




More information about the cfe-commits mailing list