From ee012692ba6981a5889d38e76e717e2cb0216e57 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sat, 12 Oct 2019 18:50:46 -1000 Subject: [PATCH] Fix memory-related problems triggered by emplace_back + copy elision --- atdna/main.cpp | 11 ++++++++++- src/athena/DNAYaml.cpp | 42 ++++++++++++++++++++++-------------------- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/atdna/main.cpp b/atdna/main.cpp index 3d697e9..0568950 100644 --- a/atdna/main.cpp +++ b/atdna/main.cpp @@ -1166,7 +1166,11 @@ class ATDNAAction : public clang::ASTFrontendAction { return {}; } +#if LLVM_VERSION_MAJOR >= 9 + std::optional TheDependencyFileGenerator; +#else std::unique_ptr TheDependencyFileGenerator; +#endif public: explicit ATDNAAction() = default; @@ -1175,9 +1179,14 @@ public: clang::DependencyOutputOptions DepOpts; DepOpts.OutputFile = DepFileOut.getValue(); DepOpts.Targets = DepFileTargets; +#if LLVM_VERSION_MAJOR >= 9 + if (!DepOpts.OutputFile.empty()) + TheDependencyFileGenerator.emplace(DepOpts).attachToPreprocessor(compiler.getPreprocessor()); +#else if (!DepOpts.OutputFile.empty()) TheDependencyFileGenerator.reset( - clang::DependencyFileGenerator::CreateAndAttachToPreprocessor(compiler.getPreprocessor(), DepOpts)); + clang::DependencyFileGenerator::CreateAndAttachToPreprocessor(compiler.getPreprocessor(), DepOpts)); +#endif std::unique_ptr fileout; StreamOut* fileoutOld; diff --git a/src/athena/DNAYaml.cpp b/src/athena/DNAYaml.cpp index 190f3e7..c8d7d59 100644 --- a/src/athena/DNAYaml.cpp +++ b/src/athena/DNAYaml.cpp @@ -169,7 +169,7 @@ std::unique_ptr ValToNode(const atVec2f& val) { for (size_t i = 0; i < 2; ++i) { auto comp = std::make_unique(YAML_SCALAR_NODE); comp->m_scalarString = fmt::format(fmt("{}"), f[i]); - ret->m_seqChildren.emplace_back(std::move(comp)); + ret->m_seqChildren.push_back(std::move(comp)); } return ret; } @@ -186,7 +186,7 @@ std::unique_ptr ValToNode(const atVec3f& val) { for (size_t i = 0; i < 3; ++i) { auto comp = std::make_unique(YAML_SCALAR_NODE); comp->m_scalarString = fmt::format(fmt("{}"), f[i]); - ret->m_seqChildren.emplace_back(std::move(comp)); + ret->m_seqChildren.push_back(std::move(comp)); } return ret; } @@ -203,7 +203,7 @@ std::unique_ptr ValToNode(const atVec4f& val) { for (size_t i = 0; i < 4; ++i) { auto comp = std::make_unique(YAML_SCALAR_NODE); comp->m_scalarString = fmt::format(fmt("{}"), f[i]); - ret->m_seqChildren.emplace_back(std::move(comp)); + ret->m_seqChildren.push_back(std::move(comp)); } return ret; } @@ -220,7 +220,7 @@ std::unique_ptr ValToNode(const atVec2d& val) { for (size_t i = 0; i < 2; ++i) { auto comp = std::make_unique(YAML_SCALAR_NODE); comp->m_scalarString = fmt::format(fmt("{}"), f[i]); - ret->m_seqChildren.emplace_back(std::move(comp)); + ret->m_seqChildren.push_back(std::move(comp)); } return ret; } @@ -237,7 +237,7 @@ std::unique_ptr ValToNode(const atVec3d& val) { for (size_t i = 0; i < 3; ++i) { auto comp = std::make_unique(YAML_SCALAR_NODE); comp->m_scalarString = fmt::format(fmt("{}"), f[i]); - ret->m_seqChildren.emplace_back(std::move(comp)); + ret->m_seqChildren.push_back(std::move(comp)); } return ret; } @@ -254,7 +254,7 @@ std::unique_ptr ValToNode(const atVec4d& val) { for (size_t i = 0; i < 4; ++i) { auto comp = std::make_unique(YAML_SCALAR_NODE); comp->m_scalarString = fmt::format(fmt("{}"), f[i]); - ret->m_seqChildren.emplace_back(std::move(comp)); + ret->m_seqChildren.push_back(std::move(comp)); } return ret; } @@ -422,7 +422,7 @@ YAMLDocWriter::YAMLDocWriter(std::string_view classType, athena::io::IStreamRead m_rootNode = std::make_unique(YAML_MAPPING_NODE); } - m_subStack.emplace_back(m_rootNode.get()); + m_subStack.push_back(m_rootNode.get()); if (!classType.empty()) { auto classVal = std::make_unique(YAML_SCALAR_NODE); classVal->m_scalarString.assign(classType); @@ -472,12 +472,13 @@ YAMLDocWriter::RecordRAII YAMLDocWriter::enterSubRecord(std::string_view name) { YAMLNode* curSub = m_subStack.back(); if (curSub->m_type != YAML_MAPPING_NODE && curSub->m_type != YAML_SEQUENCE_NODE) return {}; - YAMLNode* newNode = new YAMLNode(YAML_MAPPING_NODE); + auto newNode = std::make_unique(YAML_MAPPING_NODE); + YAMLNode* newPtr = newNode.get(); if (curSub->m_type == YAML_MAPPING_NODE) - curSub->assignMapChild(!name.empty() ? name : std::string_view{}, std::unique_ptr(newNode)); + curSub->assignMapChild(!name.empty() ? name : std::string_view{}, std::move(newNode)); else if (curSub->m_type == YAML_SEQUENCE_NODE) - curSub->m_seqChildren.emplace_back(newNode); - m_subStack.push_back(newNode); + curSub->m_seqChildren.push_back(std::move(newNode)); + m_subStack.push_back(newPtr); return RecordRAII{this}; } @@ -507,12 +508,13 @@ YAMLDocWriter::VectorRAII YAMLDocWriter::enterSubVector(std::string_view name) { YAMLNode* curSub = m_subStack.back(); if (curSub->m_type != YAML_MAPPING_NODE && curSub->m_type != YAML_SEQUENCE_NODE) return {}; - YAMLNode* newNode = new YAMLNode(YAML_SEQUENCE_NODE); + auto newNode = std::make_unique(YAML_SEQUENCE_NODE); + YAMLNode* newPtr = newNode.get(); if (curSub->m_type == YAML_MAPPING_NODE) - curSub->assignMapChild(!name.empty() ? name : std::string_view{}, std::unique_ptr(newNode)); + curSub->assignMapChild(!name.empty() ? name : std::string_view{}, std::move(newNode)); else if (curSub->m_type == YAML_SEQUENCE_NODE) - curSub->m_seqChildren.emplace_back(newNode); - m_subStack.push_back(newNode); + curSub->m_seqChildren.push_back(std::move(newNode)); + m_subStack.push_back(newPtr); return VectorRAII{this}; } @@ -527,7 +529,7 @@ void YAMLDocWriter::writeVal(std::string_view name, const INTYPE& val) { if (curSub->m_type == YAML_MAPPING_NODE) curSub->assignMapChild(!name.empty() ? name : std::string_view{}, ValToNode(val)); else if (curSub->m_type == YAML_SEQUENCE_NODE) - curSub->m_seqChildren.emplace_back(ValToNode(val)); + curSub->m_seqChildren.push_back(ValToNode(val)); } template void YAMLDocWriter::writeVal(std::string_view name, const atInt8& val); @@ -548,7 +550,7 @@ void YAMLDocWriter::writeVal(std::string_view name, const INTYPE& val, size_t by if (curSub->m_type == YAML_MAPPING_NODE) curSub->assignMapChild(!name.empty() ? name : std::string_view{}, ValToNode(val, byteCount)); else if (curSub->m_type == YAML_SEQUENCE_NODE) - curSub->m_seqChildren.emplace_back(ValToNode(val, byteCount)); + curSub->m_seqChildren.push_back(ValToNode(val, byteCount)); } void YAMLDocWriter::writeBool(std::string_view name, const bool& val) { writeVal(name, val); } @@ -611,7 +613,7 @@ static void InsertNode(std::vector& nodeStack, std::unique_ptrm_type == YAML_SEQUENCE_NODE) { - parent->m_seqChildren.emplace_back(std::move(newNode)); + parent->m_seqChildren.push_back(std::move(newNode)); } else if (parent->m_type == YAML_MAPPING_NODE) { if (!mapKey) mapKey = std::move(newNode); @@ -658,7 +660,7 @@ std::unique_ptr YAMLDocReader::ParseEvents(athena::io::IStreamReader* case YAML_SEQUENCE_START_EVENT: { YAMLNode* newSeq = new YAMLNode(YAML_SEQUENCE_NODE); InsertNode(nodeStack, mapKey, retVal, std::unique_ptr(newSeq)); - nodeStack.emplace_back(newSeq); + nodeStack.push_back(newSeq); break; } case YAML_SEQUENCE_END_EVENT: { @@ -668,7 +670,7 @@ std::unique_ptr YAMLDocReader::ParseEvents(athena::io::IStreamReader* case YAML_MAPPING_START_EVENT: { YAMLNode* newMap = new YAMLNode(YAML_MAPPING_NODE); InsertNode(nodeStack, mapKey, retVal, std::unique_ptr(newMap)); - nodeStack.emplace_back(newMap); + nodeStack.push_back(newMap); break; } case YAML_MAPPING_END_EVENT: {