From 5a8cabe34546428e32cb2fc137f8c573cf181485 Mon Sep 17 00:00:00 2001 From: Akshay Sonawane Date: Wed, 12 Aug 2026 00:39:05 -0700 Subject: [PATCH] Fix NodeAttrHelper string default lifetime --- .../qnn/builder/onnx_ctx_model_helper.cc | 3 ++- onnxruntime/core/providers/qnn/ort_api.cc | 16 ++++++++++++++++ onnxruntime/core/providers/qnn/ort_api.h | 3 +++ .../core/providers/shared/utils/utils.cc | 18 ++++++++++++++++++ .../core/providers/shared/utils/utils.h | 3 +++ .../vsinpu/builders/impl/resize_op_builder.h | 2 +- 6 files changed, 43 insertions(+), 2 deletions(-) diff --git a/onnxruntime/core/providers/qnn/builder/onnx_ctx_model_helper.cc b/onnxruntime/core/providers/qnn/builder/onnx_ctx_model_helper.cc index 3d2f167653473..a4fe1eec496eb 100644 --- a/onnxruntime/core/providers/qnn/builder/onnx_ctx_model_helper.cc +++ b/onnxruntime/core/providers/qnn/builder/onnx_ctx_model_helper.cc @@ -91,7 +91,8 @@ Status GetEpContextFromMainNode(const onnxruntime::Node& main_context_node, NodeAttrHelper node_helper(main_context_node); bool is_embed_mode = node_helper.Get(EMBED_MODE, true); if (is_embed_mode) { - const std::string& context_binary = node_helper.Get(EP_CACHE_CONTEXT, ""); + static const std::string empty_context_binary; + const std::string& context_binary = node_helper.Get(EP_CACHE_CONTEXT, empty_context_binary); return qnn_backend_manager->LoadCachedQnnContextFromBuffer(const_cast(context_binary.c_str()), static_cast(context_binary.length()), "", diff --git a/onnxruntime/core/providers/qnn/ort_api.cc b/onnxruntime/core/providers/qnn/ort_api.cc index aec09d043d2bc..6255d3d67f373 100644 --- a/onnxruntime/core/providers/qnn/ort_api.cc +++ b/onnxruntime/core/providers/qnn/ort_api.cc @@ -102,6 +102,22 @@ const std::string& NodeAttrHelper::Get(const std::string& key, const std::string return def_val; } +std::string NodeAttrHelper::Get(const std::string& key, std::string&& def_val) const { + if (auto entry = node_attributes_.find(key); entry != node_attributes_.end()) { + return NODE_ATTR_ITER_VAL(entry).s(); + } + + return std::move(def_val); +} + +std::string NodeAttrHelper::Get(const std::string& key, const char* def_val) const { + if (auto entry = node_attributes_.find(key); entry != node_attributes_.end()) { + return NODE_ATTR_ITER_VAL(entry).s(); + } + + return def_val; +} + std::vector NodeAttrHelper::Get(const std::string& key, const std::vector& def_val) const { if (auto entry = node_attributes_.find(key); entry != node_attributes_.end()) { std::vector res; diff --git a/onnxruntime/core/providers/qnn/ort_api.h b/onnxruntime/core/providers/qnn/ort_api.h index 9e79b852761c7..600949dd75329 100644 --- a/onnxruntime/core/providers/qnn/ort_api.h +++ b/onnxruntime/core/providers/qnn/ort_api.h @@ -150,7 +150,10 @@ class NodeAttrHelper { int64_t Get(const std::string& key, int64_t def_val) const; std::vector Get(const std::string& key, const std::vector& def_val) const; + // Lvalue defaults may be returned by reference; temporary and literal defaults return owned strings. const std::string& Get(const std::string& key, const std::string& def_val) const; + std::string Get(const std::string& key, std::string&& def_val) const; + std::string Get(const std::string& key, const char* def_val) const; std::vector Get(const std::string& key, const std::vector& def_val) const; // Convert the i() or ints() of the attribute from int64_t to int32_t diff --git a/onnxruntime/core/providers/shared/utils/utils.cc b/onnxruntime/core/providers/shared/utils/utils.cc index 0e0f559d2e0f1..3cb583418480b 100644 --- a/onnxruntime/core/providers/shared/utils/utils.cc +++ b/onnxruntime/core/providers/shared/utils/utils.cc @@ -4,6 +4,8 @@ #include "utils.h" +#include + #include "core/common/safeint.h" #include "core/framework/node_unit.h" #include "core/framework/tensorprotoutils.h" @@ -146,6 +148,22 @@ const std::string& NodeAttrHelper::Get(const std::string& key, const std::string return def_val; } +std::string NodeAttrHelper::Get(const std::string& key, std::string&& def_val) const { + if (auto entry = node_attributes_.find(key); entry != node_attributes_.end()) { + return entry->second.s(); + } + + return std::move(def_val); +} + +std::string NodeAttrHelper::Get(const std::string& key, const char* def_val) const { + if (auto entry = node_attributes_.find(key); entry != node_attributes_.end()) { + return entry->second.s(); + } + + return def_val; +} + std::vector NodeAttrHelper::Get(const std::string& key, const std::vector& def_val) const { if (auto entry = node_attributes_.find(key); entry != node_attributes_.end()) { const auto& attr = entry->second; diff --git a/onnxruntime/core/providers/shared/utils/utils.h b/onnxruntime/core/providers/shared/utils/utils.h index 78da6c76047bd..130f3a91ef14a 100644 --- a/onnxruntime/core/providers/shared/utils/utils.h +++ b/onnxruntime/core/providers/shared/utils/utils.h @@ -50,7 +50,10 @@ class NodeAttrHelper { int64_t Get(const std::string& key, int64_t def_val) const; std::vector Get(const std::string& key, const std::vector& def_val) const; + // Lvalue defaults may be returned by reference; temporary and literal defaults return owned strings. const std::string& Get(const std::string& key, const std::string& def_val) const; + std::string Get(const std::string& key, std::string&& def_val) const; + std::string Get(const std::string& key, const char* def_val) const; std::vector Get(const std::string& key, const std::vector& def_val) const; // Convert the i() or ints() of the attribute from int64_t to int32_t diff --git a/onnxruntime/core/providers/vsinpu/builders/impl/resize_op_builder.h b/onnxruntime/core/providers/vsinpu/builders/impl/resize_op_builder.h index db3ccb153ec35..bbfafa72fadcf 100644 --- a/onnxruntime/core/providers/vsinpu/builders/impl/resize_op_builder.h +++ b/onnxruntime/core/providers/vsinpu/builders/impl/resize_op_builder.h @@ -69,7 +69,7 @@ class ResizeOpBuilder : public BaseOpBuilder { LOGS_DEFAULT(WARNING) << "Antialias attribute is not supported."; return false; } - auto& cooridinate = helper.Get("coordinate_transoformation_mode", "half_pixel"); + auto cooridinate = helper.Get("coordinate_transoformation_mode", "half_pixel"); if (cooridinate != "align_corners" && cooridinate != "half_pixel") { LOGS_DEFAULT(WARNING) << "Only support half_pixel and align_corners attributes now."; return false;