From: Kaelyn Uhrain Date: Fri, 12 Jul 2013 21:43:02 +0000 (+0000) Subject: Provide a better diagnostic and a fixit for a '.' or '->' before the left paren X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6e9d86b31813edafb775c93e5b5595ebce1e71e1;p=clang Provide a better diagnostic and a fixit for a '.' or '->' before the left paren of a function call. This fixes PR5898 and means we now have a better diagnostic here than GCC. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@186208 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index d5982e9825..012d13d4cd 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -498,6 +498,9 @@ def err_misplaced_ellipsis_in_declaration : Error< def ext_abstract_pack_declarator_parens : ExtWarn< "ISO C++11 requires a parenthesized pack declaration to have a name">, InGroup>; +def err_function_is_not_record : Error< + "unexpected '%select{.|->}0' in function call; perhaps remove the " + "'%select{.|->}0'?">; // C++ derived classes def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">; diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 9521ffbc0e..f9c7c4e3b4 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -1457,7 +1457,19 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { ParsedType ObjectType; bool MayBePseudoDestructor = false; if (getLangOpts().CPlusPlus && !LHS.isInvalid()) { - LHS = Actions.ActOnStartCXXMemberReference(getCurScope(), LHS.take(), + Expr *Base = LHS.take(); + const Type* BaseType = Base->getType().getTypePtrOrNull(); + if (BaseType && Tok.is(tok::l_paren) && + (BaseType->isFunctionType() || + BaseType->getAsPlaceholderType()->getKind() == + BuiltinType::BoundMember)) { + Diag(OpLoc, diag::err_function_is_not_record) + << (OpKind == tok::arrow) << Base->getSourceRange() + << FixItHint::CreateRemoval(OpLoc); + return ParsePostfixExpressionSuffix(Base); + } + + LHS = Actions.ActOnStartCXXMemberReference(getCurScope(), Base, OpLoc, OpKind, ObjectType, MayBePseudoDestructor); if (LHS.isInvalid()) diff --git a/test/FixIt/fixit.cpp b/test/FixIt/fixit.cpp index a858a82e7f..400c227128 100644 --- a/test/FixIt/fixit.cpp +++ b/test/FixIt/fixit.cpp @@ -324,3 +324,17 @@ namespace PR15045 { return c->a; // expected-error {{member reference type 'PR15045::Cl0' is not a pointer; maybe you meant to use '.'?}} } } + +namespace PR5898 { + class A { + public: + const char *str(); + }; + const char* foo(A &x) + { + return x.str.(); // expected-error {{unexpected '.' in function call; perhaps remove the '.'?}} + } + bool bar(A x, const char *y) { + return foo->(x) == y; // expected-error {{unexpected '->' in function call; perhaps remove the '->'?}} + } +}