summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-11-11 03:57:31 +0000
committerJohn McCall <rjmccall@apple.com>2011-11-11 03:57:31 +0000
commit03318c1dcff689f51371dc4111aaa23e2b9ab4c5 (patch)
tree4880115140dc5da1c733aa4d71f8f5217d8b0af3 /clang/lib
parentf1a3c2aee1de6af989d52acf631b50713597e69d (diff)
downloadbcm5719-llvm-03318c1dcff689f51371dc4111aaa23e2b9ab4c5.tar.gz
bcm5719-llvm-03318c1dcff689f51371dc4111aaa23e2b9ab4c5.zip
Don't apply NRVO to over-aligned variables. The caller only
guarantees alignment up to the ABI alignment of the return type. llvm-svn: 144364
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaStmt.cpp30
1 files changed, 23 insertions, 7 deletions
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index a34d83812f6..a424a8a1b0e 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -18,6 +18,7 @@
#include "clang/Sema/Lookup.h"
#include "clang/AST/APValue.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
@@ -1650,14 +1651,29 @@ const VarDecl *Sema::getCopyElisionCandidate(QualType ReturnType,
if (!VD)
return 0;
- if (VD->hasLocalStorage() && !VD->isExceptionVariable() &&
- !VD->getType()->isReferenceType() && !VD->hasAttr<BlocksAttr>() &&
- !VD->getType().isVolatileQualified() &&
- ((VD->getKind() == Decl::Var) ||
- (AllowFunctionParameter && VD->getKind() == Decl::ParmVar)))
- return VD;
+ // ...object (other than a function or catch-clause parameter)...
+ if (VD->getKind() != Decl::Var &&
+ !(AllowFunctionParameter && VD->getKind() == Decl::ParmVar))
+ return 0;
+ if (VD->isExceptionVariable()) return 0;
+
+ // ...automatic...
+ if (!VD->hasLocalStorage()) return 0;
+
+ // ...non-volatile...
+ if (VD->getType().isVolatileQualified()) return 0;
+ if (VD->getType()->isReferenceType()) return 0;
+
+ // __block variables can't be allocated in a way that permits NRVO.
+ if (VD->hasAttr<BlocksAttr>()) return 0;
+
+ // Variables with higher required alignment than their type's ABI
+ // alignment cannot use NRVO.
+ if (VD->hasAttr<AlignedAttr>() &&
+ Context.getDeclAlign(VD) > Context.getTypeAlignInChars(VD->getType()))
+ return 0;
- return 0;
+ return VD;
}
/// \brief Perform the initialization of a potentially-movable value, which
OpenPOWER on IntegriCloud