diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-06-03 08:26:00 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-06-03 08:26:00 +0000 |
commit | 454a7cdfb35e492e0539cbc75452229d3a5c5f54 (patch) | |
tree | c63fb6636b1be122d7ebe1ab777d4bfa8c722939 /clang/lib/CodeGen/CGExprCXX.cpp | |
parent | f05149680450b6543fc676987f601f359a86281f (diff) | |
download | bcm5719-llvm-454a7cdfb35e492e0539cbc75452229d3a5c5f54.tar.gz bcm5719-llvm-454a7cdfb35e492e0539cbc75452229d3a5c5f54.zip |
Implement DR990 and DR1070. Aggregate initialization initializes uninitialized
elements from {}, rather than value-initializing them. This permits calling an
initializer-list constructor or constructing a std::initializer_list object.
(It would also permit initializing a const reference or rvalue reference if
that weren't explicitly prohibited by other rules.)
llvm-svn: 210091
Diffstat (limited to 'clang/lib/CodeGen/CGExprCXX.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExprCXX.cpp | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index c6995d8a1b2..762d8e29595 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -858,9 +858,21 @@ CodeGenFunction::EmitNewArrayInitializer(const CXXNewExpr *E, return true; }; + // If all elements have already been initialized, skip any further + // initialization. + llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements); + if (ConstNum && ConstNum->getZExtValue() <= InitListElements) { + // If there was a Cleanup, deactivate it. + if (CleanupDominator) + DeactivateCleanupBlock(Cleanup, CleanupDominator); + return; + } + + assert(Init && "have trailing elements to initialize but no initializer"); + // If this is a constructor call, try to optimize it out, and failing that // emit a single loop to initialize all remaining elements. - if (const CXXConstructExpr *CCE = dyn_cast_or_null<CXXConstructExpr>(Init)){ + if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init)) { CXXConstructorDecl *Ctor = CCE->getConstructor(); if (Ctor->isTrivial()) { // If new expression did not specify value-initialization, then there @@ -891,7 +903,7 @@ CodeGenFunction::EmitNewArrayInitializer(const CXXNewExpr *E, // If this is value-initialization, we can usually use memset. ImplicitValueInitExpr IVIE(ElementType); - if (Init && isa<ImplicitValueInitExpr>(Init)) { + if (isa<ImplicitValueInitExpr>(Init)) { if (TryMemsetInitialization()) return; @@ -906,15 +918,10 @@ CodeGenFunction::EmitNewArrayInitializer(const CXXNewExpr *E, assert(getContext().hasSameUnqualifiedType(ElementType, Init->getType()) && "got wrong type of element to initialize"); - llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements); - - // If all elements have already been initialized, skip the whole loop. - if (ConstNum && ConstNum->getZExtValue() <= InitListElements) { - // If there was a Cleanup, deactivate it. - if (CleanupDominator) - DeactivateCleanupBlock(Cleanup, CleanupDominator); - return; - } + // If we have an empty initializer list, we can usually use memset. + if (auto *ILE = dyn_cast<InitListExpr>(Init)) + if (ILE->getNumInits() == 0 && TryMemsetInitialization()) + return; // Create the loop blocks. llvm::BasicBlock *EntryBB = Builder.GetInsertBlock(); |