diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-01-13 02:20:01 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-01-13 02:20:01 +0000 |
commit | 9a766c40435de0f563218458228dc915c973a4f0 (patch) | |
tree | 7bb335ccfcea77385631a51df76d187fcf576375 /clang | |
parent | 90b748e0d1a86d998e204ba2fb1ee2602d0cc6e2 (diff) | |
download | bcm5719-llvm-9a766c40435de0f563218458228dc915c973a4f0.tar.gz bcm5719-llvm-9a766c40435de0f563218458228dc915c973a4f0.zip |
A few minor improvements to error recovery trying to access member of a function. In particular, this restores the cool error recovery for the example from http://blog.llvm.org/2010/04/amazing-feats-of-clang-error-recovery.html , which regressed a few months back.
llvm-svn: 148089
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprMember.cpp | 12 | ||||
-rw-r--r-- | clang/test/SemaCXX/member-expr.cpp | 10 |
3 files changed, 16 insertions, 8 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index fbd8098a40e..dbe19dffcaf 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -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; diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp index e05360b87ed..478b2dd4368 100644 --- a/clang/lib/Sema/SemaExprMember.cpp +++ b/clang/lib/Sema/SemaExprMember.cpp @@ -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()); diff --git a/clang/test/SemaCXX/member-expr.cpp b/clang/test/SemaCXX/member-expr.cpp index 2e3fd73d7ff..db5a0518268 100644 --- a/clang/test/SemaCXX/member-expr.cpp +++ b/clang/test/SemaCXX/member-expr.cpp @@ -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}} +} |