aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2010-06-16 18:56:04 +0000
committerFariborz Jahanian <fjahanian@apple.com>2010-06-16 18:56:04 +0000
commitd4266629ed62e3a0de5e2cb2dfb8e806f9bdc5f6 (patch)
tree6c2ca2642f284576b7d1bd6de3e83ddcd687b76c
parent0a184d313b327d0c3a2cb1420e79852223495c49 (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.td2
-rw-r--r--lib/Sema/SemaExprCXX.cpp11
-rw-r--r--lib/Sema/SemaExprObjC.cpp5
-rw-r--r--test/SemaObjCXX/instantiate-method-return.mm26
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