From a01885536cf093bd0f1d37a33cffaf80be1f821a Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Sat, 15 Apr 2017 15:56:43 -0400 Subject: [PATCH] PVUnion fixups select(int32) throw for variant w/ other than UNDEFINED_INDEX. Now same behavior for variant and discriminating, which is to clear contents. Fix selector range check. set(int32) Fix set(UNDEFINED_INDEX, NULL) for discriminating. Fix selector range check. --- src/factory/PVUnion.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/factory/PVUnion.cpp b/src/factory/PVUnion.cpp index 804b7fb..4e49287 100644 --- a/src/factory/PVUnion.cpp +++ b/src/factory/PVUnion.cpp @@ -70,8 +70,11 @@ string PVUnion::getSelectedFieldName() const PVFieldPtr PVUnion::select(int32 index) { + if (variant && index != UNDEFINED_INDEX) + throw std::invalid_argument("index out of bounds"); + // no change - if (selector == index) + if (selector == index && !variant) return value; if (index == UNDEFINED_INDEX) @@ -80,9 +83,7 @@ PVFieldPtr PVUnion::select(int32 index) value.reset(); return value; } - else if (variant) - throw std::invalid_argument("index out of bounds"); - else if (index < 0 || index > static_cast(unionPtr->getFields().size())) + else if (index < 0 || size_t(index) >= unionPtr->getFields().size()) throw std::invalid_argument("index out of bounds"); FieldConstPtr field = unionPtr->getField(index); @@ -114,14 +115,14 @@ void PVUnion::set(int32 index, PVFieldPtr const & value) if (index == UNDEFINED_INDEX) { // for undefined index we accept only null values - if (value.get()) + if (value) throw std::invalid_argument("non-null value for index == UNDEFINED_INDEX"); } - else if (index < 0 || index > static_cast(unionPtr->getFields().size())) + else if (index < 0 || size_t(index) >= unionPtr->getFields().size()) throw std::invalid_argument("index out of bounds"); - - // value type must match - if (value->getField() != unionPtr->getField(index)) + else if (!value) + throw std::invalid_argument("Can't set defined index w/ NULL"); + else if (value->getField() != unionPtr->getField(index)) throw std::invalid_argument("selected field and its introspection data do not match"); }