From: Anders Carlsson Date: Sun, 1 Mar 2009 01:45:25 +0000 (+0000) Subject: Emit errors about unsupported blocks features. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0df8c925710facc059d643b16dffc6df3d415363;p=clang Emit errors about unsupported blocks features. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65751 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 93e1b57fc9..ba9480fa0e 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -132,6 +132,44 @@ static bool CanBlockBeGlobal(const CodeGenFunction::BlockInfo &Info) return Info.ByRefDeclRefs.empty() && Info.ByCopyDeclRefs.empty(); } +/// CanGenerateCodeForBlockExpr - Returns whether CodeGen for the block expr +/// is supported. Will emit a diagnostic and return false if not. +/// FIXME: Once we support everything this should of course be removed. +static bool CanGenerateCodeForBlockExpr(CodeGenFunction &CGF, + const BlockExpr* BE, + const CodeGenFunction::BlockInfo &Info) +{ + if (!Info.ByRefDeclRefs.empty()) { + CGF.ErrorUnsupported(BE, "block expression with __block variables"); + return false; + } + + for (size_t I = 0, E = Info.ByCopyDeclRefs.size(); I != E; ++I) { + const BlockDeclRefExpr *E = Info.ByCopyDeclRefs[I]; + + E->getType()->dump(); + + if (E->getType()->isBlockPointerType()) { + CGF.ErrorUnsupported(BE, "block expression with imported block"); + return false; + } + + if (E->getDecl()->getAttr() || + CGF.getContext().isObjCNSObjectType(E->getType())) { + CGF.ErrorUnsupported(BE, "block expression with __attribute__((NSObject))" + " variable"); + return false; + } + + if (CGF.getContext().isObjCObjectPointerType(E->getType())) { + CGF.ErrorUnsupported(BE, "block expression with Objective-C variable"); + return false; + } + } + + return true; +} + // FIXME: Push most into CGM, passing down a few bits, like current // function name. llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { @@ -144,6 +182,9 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { if (CanBlockBeGlobal(Info)) return CGM.GetAddrOfGlobalBlock(BE, Name.c_str()); + if (!CanGenerateCodeForBlockExpr(*this, BE, Info)) + return llvm::UndefValue::get(ConvertType(BE->getType())); + std::vector Elts; llvm::Constant *C; llvm::Value *V; diff --git a/test/CodeGenObjC/blocks-unsupported.m b/test/CodeGenObjC/blocks-unsupported.m new file mode 100644 index 0000000000..03ceddf383 --- /dev/null +++ b/test/CodeGenObjC/blocks-unsupported.m @@ -0,0 +1,34 @@ +// RUN: clang -fnext-runtime --emit-llvm -o %t %s -verify + +@class Foo; +@protocol P; + +void t1() +{ + __block int a; + ^{ a = 10; }(); // expected-error {{cannot compile this block expression with __block variables yet}} + + void (^block)(void); + ^{ (void)block; }(); // expected-error {{}} + + struct Foo *__attribute__ ((NSObject)) foo; + ^{ (void)foo; }(); // expected-error {{cannot compile this block expression with __attribute__((NSObject)) variable yet}} + + typedef struct CGColor * __attribute__ ((NSObject)) CGColorRef; + CGColorRef color; + ^{ (void)color; }(); // expected-error {{cannot compile this block expression with __attribute__((NSObject)) variable yet}} + + id a1; + ^{ (void)a1; }(); // expected-error {{cannot compile this block expression with Objective-C variable yet}} + + Foo *a2; + ^{ (void)a2; }(); // expected-error {{cannot compile this block expression with Objective-C variable yet}} + + id

a3; + ^{ (void)a3; }(); // expected-error {{cannot compile this block expression with Objective-C variable yet}} + + Foo

*a4; + ^{ (void)a4; }(); // expected-error {{cannot compile this block expression with Objective-C variable yet}} + + +}