]> granicus.if.org Git - clang/commitdiff
Make sure result type of objc++ message expression is
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 16 Jun 2010 18:56:04 +0000 (18:56 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 16 Jun 2010 18:56:04 +0000 (18:56 +0000)
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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaExprObjC.cpp
test/SemaObjCXX/instantiate-method-return.mm [new file with mode: 0644]

index 5d238b4e7890c88cc751e63e480818c4e620859a..0a9cb8a22ed19e58eb5c7238920aec9bcc665787 100644 (file)
@@ -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<
index e478d9a28f53a575b6dfc1ce876d2857cbb3425c..84f6f407cd375856d3afb9dae107a29158328ae0 100644 (file)
@@ -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.
index 695a1beca15e0be49cc1dd720a7cec3c1d523f18..ed6e917f551c6b342f4c57da5345cde477f58014 100644 (file)
@@ -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 (file)
index 0000000..b8ba4af
--- /dev/null
@@ -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