diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2010-06-16 18:56:04 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2010-06-16 18:56:04 +0000 |
commit | d4266629ed62e3a0de5e2cb2dfb8e806f9bdc5f6 (patch) | |
tree | 6c2ca2642f284576b7d1bd6de3e83ddcd687b76c | |
parent | 0a184d313b327d0c3a2cb1420e79852223495c49 (diff) |
Make sure result type of objc++ message expression is
complete before attempting to bind it to a temporary.
Fixes PR7386.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106130 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 11 | ||||
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 5 | ||||
-rw-r--r-- | test/SemaObjCXX/instantiate-method-return.mm | 26 |
4 files changed, 44 insertions, 0 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 5d238b4e78..0a9cb8a22e 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1888,6 +1888,8 @@ def err_illegal_decl_array_of_functions : Error< "'%0' declared as array of functions of type %1">; def err_illegal_decl_array_incomplete_type : Error< "array has incomplete element type %0">; +def err_illegal_message_expr_incomplete_type : Error< + "objective-c message has incomplete result type %0">; def err_illegal_decl_array_of_references : Error< "'%0' declared as array of references of type %1">; def err_array_star_outside_prototype : Error< diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index e478d9a28f..84f6f407cd 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -17,6 +17,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/ExprObjC.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/TargetInfo.h" @@ -2605,6 +2606,16 @@ Sema::OwningExprResult Sema::MaybeBindToTemporary(Expr *E) { if (FTy->getResultType()->isReferenceType()) return Owned(E); } + else if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) { + QualType Ty = ME->getType(); + if (const PointerType *PT = Ty->getAs<PointerType>()) + Ty = PT->getPointeeType(); + else if (const BlockPointerType *BPT = Ty->getAs<BlockPointerType>()) + Ty = BPT->getPointeeType(); + if (Ty->isReferenceType()) + return Owned(E); + } + // That should be enough to guarantee that this type is complete. // If it has a trivial destructor, we can avoid the extra copy. diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 695a1beca1..ed6e917f55 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -1018,6 +1018,11 @@ Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE, else Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc, Receiver, Sel, Method, Args, NumArgs, RBracLoc); + if (Context.getLangOptions().CPlusPlus && !ReturnType->isVoidType()) { + if (RequireCompleteType(LBracLoc, ReturnType, + diag::err_illegal_message_expr_incomplete_type)) + return ExprError(); + } return MaybeBindToTemporary(Result); } diff --git a/test/SemaObjCXX/instantiate-method-return.mm b/test/SemaObjCXX/instantiate-method-return.mm new file mode 100644 index 0000000000..b8ba4af092 --- /dev/null +++ b/test/SemaObjCXX/instantiate-method-return.mm @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// PR7386 + +@class NSObject; + +class A; +template<class T> class V {}; + +@protocol Protocol +- (V<A*>)protocolMethod; +@end + + +@interface I<Protocol> +@end + + +@implementation I +- (void)randomMethod:(id)info { + V<A*> vec([self protocolMethod]); +} + +- (V<A*>)protocolMethod { + V<A*> va; return va; +} +@end |