diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-10-28 16:49:46 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-10-28 16:49:46 +0000 |
commit | 5de245058d411b166dc32622f39298716450fa1c (patch) | |
tree | d223c444a590e0e66fc5932b1e2ff740c6944526 | |
parent | 457e2815d43fa68f7ff7cd2f7e9d1bf7b6fdc653 (diff) |
Diagnose use of data pointer member in a function call
expression instead of crashing.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85401 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 33 | ||||
-rw-r--r-- | test/SemaCXX/ptrtomember-badcall.cpp | 13 |
2 files changed, 32 insertions, 14 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 12f1f513d4..a322eb0499 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2860,24 +2860,29 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Fn->IgnoreParens())) { if (BO->getOpcode() == BinaryOperator::PtrMemD || BO->getOpcode() == BinaryOperator::PtrMemI) { - const FunctionProtoType *FPT = cast<FunctionProtoType>(BO->getType()); - QualType ResultTy = FPT->getResultType().getNonReferenceType(); + if (const FunctionProtoType *FPT = + dyn_cast<FunctionProtoType>(BO->getType())) { + QualType ResultTy = FPT->getResultType().getNonReferenceType(); - ExprOwningPtr<CXXMemberCallExpr> - TheCall(this, new (Context) CXXMemberCallExpr(Context, BO, Args, - NumArgs, ResultTy, - RParenLoc)); + ExprOwningPtr<CXXMemberCallExpr> + TheCall(this, new (Context) CXXMemberCallExpr(Context, BO, Args, + NumArgs, ResultTy, + RParenLoc)); - if (CheckCallReturnType(FPT->getResultType(), - BO->getRHS()->getSourceRange().getBegin(), - TheCall.get(), 0)) - return ExprError(); + if (CheckCallReturnType(FPT->getResultType(), + BO->getRHS()->getSourceRange().getBegin(), + TheCall.get(), 0)) + return ExprError(); - if (ConvertArgumentsForCall(&*TheCall, BO, 0, FPT, Args, NumArgs, - RParenLoc)) - return ExprError(); + if (ConvertArgumentsForCall(&*TheCall, BO, 0, FPT, Args, NumArgs, + RParenLoc)) + return ExprError(); - return Owned(MaybeBindToTemporary(TheCall.release()).release()); + return Owned(MaybeBindToTemporary(TheCall.release()).release()); + } + return ExprError(Diag(Fn->getLocStart(), + diag::err_typecheck_call_not_function) + << Fn->getType() << Fn->getSourceRange()); } } } diff --git a/test/SemaCXX/ptrtomember-badcall.cpp b/test/SemaCXX/ptrtomember-badcall.cpp new file mode 100644 index 0000000000..42b8e3b6e0 --- /dev/null +++ b/test/SemaCXX/ptrtomember-badcall.cpp @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x + +struct S { + int i; + + int mem(int); +}; + +int foo(int S::* ps, S *s) +{ + return (s->*ps)(1); // expected-error {{called object type 'int' is not a function or function pointer}} +} + |