From: Daniel Dunbar Date: Fri, 9 Jan 2009 16:50:52 +0000 (+0000) Subject: Give "unsupported" error on calls through block pointers instead of X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ce1d38b8163650e473d7084e0686ed5a7956057b;p=clang Give "unsupported" error on calls through block pointers instead of crashes. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61992 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 2742395db8..9d7d8be2f0 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -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(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) diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 3b951070ad..2cba7d03e0 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -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).