ICU-21230 Add status to MaybeStackArray(int32_t newCapacity), plumb it through.
diff --git a/icu4c/source/common/cmemory.h b/icu4c/source/common/cmemory.h
index 313180b..754bbb5 100644
--- a/icu4c/source/common/cmemory.h
+++ b/icu4c/source/common/cmemory.h
@@ -297,12 +297,16 @@
* Automatically allocates the heap array if the argument is larger than the stack capacity.
* Intended for use when an approximate capacity is known at compile time but the true
* capacity is not known until runtime.
- *
- * WARNING: does not report errors upon memory allocation failure, after
- * which capacity will be stackCapacity, not the requested newCapacity.
*/
- MaybeStackArray(int32_t newCapacity) : MaybeStackArray() {
- if (capacity < newCapacity) { resize(newCapacity); }
+ MaybeStackArray(int32_t newCapacity, UErrorCode status) : MaybeStackArray() {
+ if (U_FAILURE(status)) {
+ return;
+ }
+ if (capacity < newCapacity) {
+ if (resize(newCapacity) == nullptr) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ }
+ }
}
/**
* Destructor deletes the array (if owned).
diff --git a/icu4c/source/common/localematcher.cpp b/icu4c/source/common/localematcher.cpp
index bb18e23..8efbf0b 100644
--- a/icu4c/source/common/localematcher.cpp
+++ b/icu4c/source/common/localematcher.cpp
@@ -436,11 +436,8 @@
int32_t suppLength = 0;
// Determine insertion order.
// Add locales immediately that are equivalent to the default.
- MaybeStackArray<int8_t, 100> order(supportedLocalesLength);
- if (order.getAlias() == nullptr) {
- errorCode = U_MEMORY_ALLOCATION_ERROR;
- return;
- }
+ MaybeStackArray<int8_t, 100> order(supportedLocalesLength, errorCode);
+ if (U_FAILURE(errorCode)) { return; }
int32_t numParadigms = 0;
for (int32_t i = 0; i < supportedLocalesLength; ++i) {
const Locale &locale = *supportedLocales[i];
diff --git a/icu4c/source/i18n/listformatter.cpp b/icu4c/source/i18n/listformatter.cpp
index da99c92..84f24d2 100644
--- a/icu4c/source/i18n/listformatter.cpp
+++ b/icu4c/source/i18n/listformatter.cpp
@@ -702,7 +702,7 @@
int32_t prefixLength = 0;
// for n items, there are 2 * (n + 1) boundary including 0 and the upper
// edge.
- MaybeStackArray<int32_t, 10> offsets((handler != nullptr) ? 2 * (nItems + 1): 0);
+ MaybeStackArray<int32_t, 10> offsets((handler != nullptr) ? 2 * (nItems + 1) : 0, errorCode);
if (nItems == 2) {
joinStringsAndReplace(
data->patternHandler->getTwoPattern(items[1]),
diff --git a/icu4c/source/i18n/number_decimalquantity.cpp b/icu4c/source/i18n/number_decimalquantity.cpp
index 482e93d..e646c54 100644
--- a/icu4c/source/i18n/number_decimalquantity.cpp
+++ b/icu4c/source/i18n/number_decimalquantity.cpp
@@ -20,6 +20,7 @@
#include "charstr.h"
#include "number_utils.h"
#include "uassert.h"
+#include "util.h"
using namespace icu;
using namespace icu::number;
@@ -634,7 +635,10 @@
// Use the BCD constructor. We need to do a little bit of work to convert, though.
// The decNumber constructor expects most-significant first, but we store least-significant first.
- MaybeStackArray<uint8_t, 20> ubcd(precision);
+ MaybeStackArray<uint8_t, 20> ubcd(precision, status);
+ if (U_FAILURE(status)) {
+ return;
+ }
for (int32_t m = 0; m < precision; m++) {
ubcd[precision - m - 1] = static_cast<uint8_t>(getDigitPos(m));
}
@@ -1324,7 +1328,11 @@
}
UnicodeString DecimalQuantity::toString() const {
- MaybeStackArray<char, 30> digits(precision + 1);
+ UErrorCode localStatus = U_ZERO_ERROR;
+ MaybeStackArray<char, 30> digits(precision + 1, localStatus);
+ if (U_FAILURE(localStatus)) {
+ return ICU_Utility::makeBogusString();
+ }
for (int32_t i = 0; i < precision; i++) {
digits[i] = getDigitPos(precision - i - 1) + '0';
}
diff --git a/icu4c/source/i18n/number_utils.cpp b/icu4c/source/i18n/number_utils.cpp
index 91d7f33..bef7ea6 100644
--- a/icu4c/source/i18n/number_utils.cpp
+++ b/icu4c/source/i18n/number_utils.cpp
@@ -258,7 +258,10 @@
}
// "string must be at least dn->digits+14 characters long"
int32_t minCapacity = fData.getAlias()->digits + 14;
- MaybeStackArray<char, 30> buffer(minCapacity);
+ MaybeStackArray<char, 30> buffer(minCapacity, status);
+ if (U_FAILURE(status)) {
+ return;
+ }
uprv_decNumberToString(fData, buffer.getAlias());
output.Append(buffer.getAlias(), static_cast<int32_t>(uprv_strlen(buffer.getAlias())));
}
diff --git a/icu4c/source/i18n/numparse_affixes.cpp b/icu4c/source/i18n/numparse_affixes.cpp
index ca293e7..cef1685 100644
--- a/icu4c/source/i18n/numparse_affixes.cpp
+++ b/icu4c/source/i18n/numparse_affixes.cpp
@@ -127,8 +127,8 @@
fMatchers[fMatchersLen++] = &matcher;
}
-AffixPatternMatcher AffixPatternMatcherBuilder::build() {
- return AffixPatternMatcher(fMatchers, fMatchersLen, fPattern);
+AffixPatternMatcher AffixPatternMatcherBuilder::build(UErrorCode& status) {
+ return AffixPatternMatcher(fMatchers, fMatchersLen, fPattern, status);
}
AffixTokenMatcherWarehouse::AffixTokenMatcherWarehouse(const AffixTokenMatcherSetupData* setupData)
@@ -209,12 +209,13 @@
AffixPatternMatcherBuilder builder(affixPattern, tokenWarehouse, ignorables);
AffixUtils::iterateWithConsumer(affixPattern, builder, status);
- return builder.build();
+ return builder.build(status);
}
AffixPatternMatcher::AffixPatternMatcher(MatcherArray& matchers, int32_t matchersLen,
- const UnicodeString& pattern)
- : ArraySeriesMatcher(matchers, matchersLen), fPattern(pattern) {}
+ const UnicodeString& pattern, UErrorCode& status)
+ : ArraySeriesMatcher(matchers, matchersLen), fPattern(pattern, status) {
+}
UnicodeString AffixPatternMatcher::getPattern() const {
return fPattern.toAliasedUnicodeString();
@@ -446,28 +447,3 @@
#endif /* #if !UCONFIG_NO_FORMATTING */
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/icu4c/source/i18n/numparse_affixes.h b/icu4c/source/i18n/numparse_affixes.h
index 97a17f4..a82b731 100644
--- a/icu4c/source/i18n/numparse_affixes.h
+++ b/icu4c/source/i18n/numparse_affixes.h
@@ -128,7 +128,7 @@
void consumeToken(::icu::number::impl::AffixPatternType type, UChar32 cp, UErrorCode& status) override;
/** NOTE: You can build only once! */
- AffixPatternMatcher build();
+ AffixPatternMatcher build(UErrorCode& status);
private:
ArraySeriesMatcher::MatcherArray fMatchers;
@@ -160,7 +160,8 @@
private:
CompactUnicodeString<4> fPattern;
- AffixPatternMatcher(MatcherArray& matchers, int32_t matchersLen, const UnicodeString& pattern);
+ AffixPatternMatcher(MatcherArray& matchers, int32_t matchersLen, const UnicodeString& pattern,
+ UErrorCode& status);
friend class AffixPatternMatcherBuilder;
};
diff --git a/icu4c/source/i18n/numparse_types.h b/icu4c/source/i18n/numparse_types.h
index b4007c2..a989e02 100644
--- a/icu4c/source/i18n/numparse_types.h
+++ b/icu4c/source/i18n/numparse_types.h
@@ -64,8 +64,9 @@
fBuffer[0] = 0;
}
- CompactUnicodeString(const UnicodeString& text)
- : fBuffer(text.length() + 1) {
+ CompactUnicodeString(const UnicodeString& text, UErrorCode& status)
+ : fBuffer(text.length() + 1, status) {
+ if (U_FAILURE(status)) { return; }
uprv_memcpy(fBuffer.getAlias(), text.getBuffer(), sizeof(UChar) * text.length());
fBuffer[text.length()] = 0;
}
diff --git a/icu4c/source/test/intltest/numbertest_parse.cpp b/icu4c/source/test/intltest/numbertest_parse.cpp
index 12ecc75..b47519d 100644
--- a/icu4c/source/test/intltest/numbertest_parse.cpp
+++ b/icu4c/source/test/intltest/numbertest_parse.cpp
@@ -196,7 +196,8 @@
PercentMatcher m3(symbols);
IgnorablesMatcher m4(0);
- ArraySeriesMatcher::MatcherArray matchers(5);
+ ArraySeriesMatcher::MatcherArray matchers(5, status);
+ status.assertSuccess();
matchers[0] = &m0;
matchers[1] = &m1;
matchers[2] = &m2;