]> granicus.if.org Git - clang/commitdiff
Give "unsupported" error on calls through block pointers instead of
authorDaniel Dunbar <daniel@zuster.org>
Fri, 9 Jan 2009 16:50:52 +0000 (16:50 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Fri, 9 Jan 2009 16:50:52 +0000 (16:50 +0000)
crashes.

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

lib/CodeGen/CGExpr.cpp
lib/CodeGen/CodeGenFunction.h

index 2742395db86df5891edebcfb17e27b8fb2043994..9d7d8be2f03ce869f15ef1f5b9a96fc79597b268 100644 (file)
@@ -83,6 +83,13 @@ unsigned CodeGenFunction::getAccessedFieldNo(unsigned Idx,
 //                         LValue Expression Emission
 //===----------------------------------------------------------------------===//
 
+RValue CodeGenFunction::EmitUnsupportedRValue(const Expr *E,
+                                              const char *Name) {
+  ErrorUnsupported(E, Name);
+  llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType()));
+  return RValue::get(llvm::UndefValue::get(Ty));
+}
+
 LValue CodeGenFunction::EmitUnsupportedLValue(const Expr *E,
                                               const char *Name) {
   ErrorUnsupported(E, Name);
@@ -903,6 +910,9 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) {
         if (unsigned builtinID = FDecl->getIdentifier()->getBuiltinID())
           return EmitBuiltinExpr(builtinID, E);
 
+  if (E->getCallee()->getType()->isBlockPointerType())
+    return EmitUnsupportedRValue(E->getCallee(), "block pointer reference");
+
   llvm::Value *Callee = EmitScalarExpr(E->getCallee());
   return EmitCallExpr(Callee, E->getCallee()->getType(),
                       E->arg_begin(), E->arg_end());
@@ -1034,14 +1044,20 @@ CodeGenFunction::EmitObjCSuperExpr(const ObjCSuperExpr *E) {
   return EmitUnsupportedLValue(E, "use of super");
 }
 
-RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType FnType, 
+RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType CalleeType, 
                                      CallExpr::const_arg_iterator ArgBeg,
                                      CallExpr::const_arg_iterator ArgEnd) {
-  
-  // The callee type will always be a pointer to function type, get the function
-  // type.
-  FnType = FnType->getAsPointerType()->getPointeeType();
-  QualType ResultType = FnType->getAsFunctionType()->getResultType();
+  // Get the actual function type. The callee type will always be a
+  // pointer to function type or a block pointer type.
+  QualType ResultType;
+  if (const BlockPointerType *BPT = dyn_cast<BlockPointerType>(CalleeType)) {
+    ResultType = BPT->getPointeeType()->getAsFunctionType()->getResultType();
+  } else {
+    assert(CalleeType->isFunctionPointerType() && 
+           "Call must have function pointer type!");
+    QualType FnType = CalleeType->getAsPointerType()->getPointeeType();
+    ResultType = FnType->getAsFunctionType()->getResultType();
+  }
 
   CallArgList Args;
   for (CallExpr::const_arg_iterator I = ArgBeg; I != ArgEnd; ++I)
index 3b951070adb489752d303c73703aa633810da240..2cba7d03e00e4f683d09ef37481350e0d8610f4b 100644 (file)
@@ -431,6 +431,12 @@ public:
   //                         LValue Expression Emission
   //===--------------------------------------------------------------------===//
 
+  /// EmitUnsupportedRValue - Emit a dummy r-value using the type of E
+  /// and issue an ErrorUnsupported style diagnostic (using the
+  /// provided Name).
+  RValue EmitUnsupportedRValue(const Expr *E,
+                               const char *Name);
+
   /// EmitUnsupportedLValue - Emit a dummy l-value using the type of E
   /// and issue an ErrorUnsupported style diagnostic (using the
   /// provided Name).