forked from OSchip/llvm-project
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
This commit is contained in:
parent
f1a3c2aee1
commit
03318c1dcf
|
@ -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;
|
||||
|
||||
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 VD;
|
||||
}
|
||||
|
||||
/// \brief Perform the initialization of a potentially-movable value, which
|
||||
|
|
|
@ -147,3 +147,15 @@ X test5() {
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// rdar://problem/10430868
|
||||
// CHECK: define void @_Z5test6v
|
||||
X test6() {
|
||||
X a __attribute__((aligned(8)));
|
||||
return a;
|
||||
// CHECK: [[A:%.*]] = alloca [[X:%.*]], align 8
|
||||
// CHECK-NEXT: call void @_ZN1XC1Ev([[X]]* [[A]])
|
||||
// CHECK-NEXT: call void @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* [[A]])
|
||||
// CHECK-NEXT: call void @_ZN1XD1Ev([[X]]* [[A]])
|
||||
// CHECK-NEXT: ret void
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue