Make sure result type of objc++ message expression is

complete before attempting to bind it to a temporary.
Fixes PR7386.

llvm-svn: 106130
This commit is contained in:
Fariborz Jahanian 2010-06-16 18:56:04 +00:00
parent 6c0da25129
commit 1d44608cc1
4 changed files with 44 additions and 0 deletions

View File

@ -1888,6 +1888,8 @@ def err_illegal_decl_array_of_functions : Error<
"'%0' declared as array of functions of type %1">; "'%0' declared as array of functions of type %1">;
def err_illegal_decl_array_incomplete_type : Error< def err_illegal_decl_array_incomplete_type : Error<
"array has incomplete element type %0">; "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< def err_illegal_decl_array_of_references : Error<
"'%0' declared as array of references of type %1">; "'%0' declared as array of references of type %1">;
def err_array_star_outside_prototype : Error< def err_array_star_outside_prototype : Error<

View File

@ -17,6 +17,7 @@
#include "clang/AST/ASTContext.h" #include "clang/AST/ASTContext.h"
#include "clang/AST/CXXInheritance.h" #include "clang/AST/CXXInheritance.h"
#include "clang/AST/ExprCXX.h" #include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/TypeLoc.h" #include "clang/AST/TypeLoc.h"
#include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetInfo.h"
@ -2605,6 +2606,16 @@ Sema::OwningExprResult Sema::MaybeBindToTemporary(Expr *E) {
if (FTy->getResultType()->isReferenceType()) if (FTy->getResultType()->isReferenceType())
return Owned(E); 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. // That should be enough to guarantee that this type is complete.
// If it has a trivial destructor, we can avoid the extra copy. // If it has a trivial destructor, we can avoid the extra copy.

View File

@ -1018,6 +1018,11 @@ Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
else else
Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc, Receiver, Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc, Receiver,
Sel, Method, Args, NumArgs, RBracLoc); 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); return MaybeBindToTemporary(Result);
} }

View File

@ -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