]> granicus.if.org Git - clang/commitdiff
Diagnose use of data pointer member in a function call
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 28 Oct 2009 16:49:46 +0000 (16:49 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 28 Oct 2009 16:49:46 +0000 (16:49 +0000)
expression instead of crashing.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85401 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/SemaCXX/ptrtomember-badcall.cpp [new file with mode: 0644]

index 12f1f513d4f509cffba3161ce445a46a684f23da..a322eb04999fefa22b449ba1b51953a827cea237 100644 (file)
@@ -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 (file)
index 0000000..42b8e3b
--- /dev/null
@@ -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}}
+}
+