Provide a better diagnostic and a fixit for a '.' or '->' before the left paren
authorKaelyn Uhrain <rikka@google.com>
Fri, 12 Jul 2013 21:43:02 +0000 (21:43 +0000)
committerKaelyn Uhrain <rikka@google.com>
Fri, 12 Jul 2013 21:43:02 +0000 (21:43 +0000)
of a function call.

This fixes PR5898 and means we now have a better diagnostic here than GCC.

llvm-svn: 186208

clang/include/clang/Basic/DiagnosticParseKinds.td
clang/lib/Parse/ParseExpr.cpp
clang/test/FixIt/fixit.cpp

index d5982e9..012d13d 100644 (file)
@@ -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<DiagGroup<"anonymous-pack-parens">>;
+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">;
index 9521ffb..f9c7c4e 100644 (file)
@@ -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())
index a858a82..400c227 100644 (file)
@@ -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 '->'?}}
+  }
+}