From 5e6fcd4ba9cc4cab5a6be0a76bca9d51480ea346 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 8 Feb 2011 02:14:35 +0000 Subject: [PATCH] Sema::MaybeBindToTemporary() shouldn't treat any expression returning a glvalue as a temporary. Previously, we were enumerating all of the cases that coul return glvalues and might be called with Sema::MaybeBindToTemporary(), but that was gross and we missed the Objective-C property reference case. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125070 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaExprCXX.cpp | 14 +++----------- test/SemaObjCXX/properties.mm | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 test/SemaObjCXX/properties.mm diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 81031a54ee..ea1ad51e9d 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -3370,17 +3370,9 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) { if (!RT) return Owned(E); - // If this is the result of a call or an Objective-C message send expression, - // our source might actually be a reference, in which case we shouldn't bind. - if (CallExpr *CE = dyn_cast(E)) { - if (CE->getCallReturnType()->isReferenceType()) - return Owned(E); - } else if (ObjCMessageExpr *ME = dyn_cast(E)) { - if (const ObjCMethodDecl *MD = ME->getMethodDecl()) { - if (MD->getResultType()->isReferenceType()) - return Owned(E); - } - } + // If the result is a glvalue, we shouldn't bind it. + if (E->Classify(Context).isGLValue()) + 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/test/SemaObjCXX/properties.mm b/test/SemaObjCXX/properties.mm new file mode 100644 index 0000000000..f148b3395d --- /dev/null +++ b/test/SemaObjCXX/properties.mm @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct X { + void f() const; + ~X(); +}; + +@interface A { + X x_; +} + +- (const X&)x; +- (void)setx:(const X&)other; +@end + +@implementation A + +- (const X&)x { return x_; } +- (void)setx:(const X&)other { x_ = other; } +- (void)method { + self.x.f(); +} +@end + -- 2.50.1