]> granicus.if.org Git - clang/commitdiff
A few minor improvements to error recovery trying to access member of a function...
authorEli Friedman <eli.friedman@gmail.com>
Fri, 13 Jan 2012 02:20:01 +0000 (02:20 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Fri, 13 Jan 2012 02:20:01 +0000 (02:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148089 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExprMember.cpp
test/SemaCXX/member-expr.cpp

index fbd8098a40e9a8d13517355b4fc7edaee9fca438..dbe19dffcaf0bd0b43ea44fbef8c72c2f2c549e1 100644 (file)
@@ -3442,7 +3442,7 @@ 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 a function; perhaps you meant to call "
-  "it%select{| with no arguments}?">;
+  "it%select{| with no arguments}0?">;
 def warn_subscript_is_char : Warning<"array subscript is of type 'char'">,
   InGroup<CharSubscript>, DefaultIgnore;
 
index e05360b87ed72253c23302ce20f8e8d370770929..478b2dd4368594a29913906a388cd7e7a5a9b2f2 100644 (file)
@@ -976,12 +976,10 @@ static bool isPointerToRecordType(QualType T) {
 /// Perform conversions on the LHS of a member access expression.
 ExprResult
 Sema::PerformMemberExprBaseConversion(Expr *Base, bool IsArrow) {
-  ExprResult BaseResult = DefaultFunctionArrayConversion(Base);
+  if (IsArrow && !Base->getType()->isFunctionType())
+    return DefaultFunctionArrayLvalueConversion(Base);
 
-  if (!BaseResult.isInvalid() && IsArrow)
-    BaseResult = DefaultLvalueConversion(BaseResult.take());
-
-  return BaseResult;
+  return CheckPlaceholderExpr(Base);
 }
 
 /// Look up the given member of the given non-type-dependent
@@ -1033,7 +1031,7 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
         << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
         << FixItHint::CreateReplacement(OpLoc, ".");
       IsArrow = false;
-    } else if (BaseType == Context.BoundMemberTy) {
+    } else if (BaseType->isFunctionType()) {
       goto fail;
     } else {
       Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
@@ -1365,7 +1363,7 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
   if (tryToRecoverWithCall(BaseExpr,
                            PDiag(diag::err_member_reference_needs_call),
                            /*complain*/ false,
-                           IsArrow ? &isRecordType : &isPointerToRecordType)) {
+                           IsArrow ? &isPointerToRecordType : &isRecordType)) {
     if (BaseExpr.isInvalid())
       return ExprError();
     BaseExpr = DefaultFunctionArrayConversion(BaseExpr.take());
index 2e3fd73d7ff5c68b139278e3382e7885d68ad763..db5a051826800c433d99fe92d2d5b54f1fb5ba42 100644 (file)
@@ -147,3 +147,13 @@ namespace PR9025 {
     return fun5.x; // expected-error{{reference to overloaded function could not be resolved; did you mean to call it?}}
   }
 }
+
+namespace FuncInMemberExpr {
+  struct Vec { int size(); };
+  Vec fun1();
+  int test1() { return fun1.size(); } // expected-error {{base of member reference is a function; perhaps you meant to call it with no arguments}}
+  Vec *fun2();
+  int test2() { return fun2->size(); } // expected-error {{base of member reference is a function; perhaps you meant to call it with no arguments}}
+  Vec fun3(int x = 0);
+  int test3() { return fun3.size(); } // expected-error {{base of member reference is a function; perhaps you meant to call it with no arguments}}
+}