From 9edbbecb24e7d2baca3735f041a65c7623bdf230 Mon Sep 17 00:00:00 2001 From: Markus Scherer Date: Thu, 20 Nov 2014 00:27:17 +0000 Subject: [PATCH] ICU-11339 add & use LocalPointer(p, errorCode) and adoptInsteadAndCheckErrorCode(p, errorCode) X-SVN-Rev: 36757 --- icu4c/source/common/unicode/localpointer.h | 46 ++++++++++++++++++- icu4c/source/i18n/alphaindex.cpp | 15 +++--- icu4c/source/i18n/collationbuilder.cpp | 5 +- icu4c/source/i18n/decimfmt.cpp | 2 +- icu4c/source/i18n/filteredbrk.cpp | 11 ++--- icu4c/source/i18n/measfmt.cpp | 6 +-- icu4c/source/i18n/numfmt.cpp | 7 ++- icu4c/source/i18n/region.cpp | 6 +-- icu4c/source/test/intltest/calregts.cpp | 14 +++--- icu4c/source/test/intltest/dcfmapts.cpp | 21 +++++---- icu4c/source/test/intltest/dtfmttst.cpp | 6 +-- icu4c/source/test/intltest/dtifmtts.cpp | 6 +-- icu4c/source/test/intltest/itutil.cpp | 53 ++++++++++++++++++---- icu4c/source/test/intltest/numrgts.cpp | 2 +- icu4c/source/test/intltest/plurults.cpp | 8 +++- icu4c/source/test/intltest/regcoll.cpp | 12 +++-- icu4c/source/test/intltest/thcoll.cpp | 2 +- icu4c/source/test/intltest/tufmtts.cpp | 3 +- icu4c/source/test/intltest/tzfmttst.cpp | 2 +- icu4c/source/tools/gennorm2/gennorm2.cpp | 2 +- 20 files changed, 151 insertions(+), 78 deletions(-) diff --git a/icu4c/source/common/unicode/localpointer.h b/icu4c/source/common/unicode/localpointer.h index e3ccb258154..05800561c63 100644 --- a/icu4c/source/common/unicode/localpointer.h +++ b/icu4c/source/common/unicode/localpointer.h @@ -1,7 +1,7 @@ /* ******************************************************************************* * -* Copyright (C) 2009-2012, International Business Machines +* Copyright (C) 2009-2014, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* @@ -191,6 +191,24 @@ public: * @stable ICU 4.4 */ explicit LocalPointer(T *p=NULL) : LocalPointerBase(p) {} + /** + * Constructor takes ownership and reports an error if NULL. + * + * This constructor is intended to be used with other-class constructors + * that may report a failure UErrorCode, + * so that callers need to check only for U_FAILURE(errorCode) + * and not also separately for isNull(). + * + * @param p simple pointer to an object that is adopted + * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR + * if p==NULL and no other failure code had been set + * @draft ICU 55 + */ + LocalPointer(T *p, UErrorCode &errorCode) : LocalPointerBase(p) { + if(p==NULL && U_SUCCESS(errorCode)) { + errorCode=U_MEMORY_ALLOCATION_ERROR; + } + } /** * Destructor deletes the object it owns. * @stable ICU 4.4 @@ -208,6 +226,32 @@ public: delete LocalPointerBase::ptr; LocalPointerBase::ptr=p; } + /** + * Deletes the object it owns, + * and adopts (takes ownership of) the one passed in. + * + * If U_FAILURE(errorCode), then the current object is retained and the new one deleted. + * + * If U_SUCCESS(errorCode) but the input pointer is NULL, + * then U_MEMORY_ALLOCATION_ERROR is set, + * the current object is deleted, and NULL is set. + * + * @param p simple pointer to an object that is adopted + * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR + * if p==NULL and no other failure code had been set + * @draft ICU 55 + */ + void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) { + if(U_SUCCESS(errorCode)) { + delete LocalPointerBase::ptr; + LocalPointerBase::ptr=p; + if(p==NULL) { + errorCode=U_MEMORY_ALLOCATION_ERROR; + } + } else { + delete p; + } + } }; /** diff --git a/icu4c/source/i18n/alphaindex.cpp b/icu4c/source/i18n/alphaindex.cpp index 0bea1dc22fb..9fa98b8029b 100644 --- a/icu4c/source/i18n/alphaindex.cpp +++ b/icu4c/source/i18n/alphaindex.cpp @@ -442,9 +442,8 @@ BucketList *AlphabeticIndex::createBucketList(UErrorCode &errorCode) const { }; UBool hasPinyin = FALSE; - LocalPointer bucketList(new UVector(errorCode)); - if (bucketList.isNull()) { - errorCode = U_MEMORY_ALLOCATION_ERROR; + LocalPointer bucketList(new UVector(errorCode), errorCode); + if (U_FAILURE(errorCode)) { return NULL; } bucketList->setDeleter(uprv_deleteUObject); @@ -601,9 +600,8 @@ BucketList *AlphabeticIndex::createBucketList(UErrorCode &errorCode) const { nextBucket = bucket; } - LocalPointer publicBucketList(new UVector(errorCode)); - if (bucketList.isNull()) { - errorCode = U_MEMORY_ALLOCATION_ERROR; + LocalPointer publicBucketList(new UVector(errorCode), errorCode); + if (U_FAILURE(errorCode)) { return NULL; } // Do not call publicBucketList->setDeleter(): @@ -990,9 +988,8 @@ UVector *AlphabeticIndex::firstStringsInScript(UErrorCode &status) { if (U_FAILURE(status)) { return NULL; } - LocalPointer dest(new UVector(status)); - if (dest.isNull()) { - status = U_MEMORY_ALLOCATION_ERROR; + LocalPointer dest(new UVector(status), status); + if (U_FAILURE(status)) { return NULL; } dest->setDeleter(uprv_deleteUObject); diff --git a/icu4c/source/i18n/collationbuilder.cpp b/icu4c/source/i18n/collationbuilder.cpp index 37f701ce775..6e3b482f095 100644 --- a/icu4c/source/i18n/collationbuilder.cpp +++ b/icu4c/source/i18n/collationbuilder.cpp @@ -1563,9 +1563,8 @@ CEFinalizer::~CEFinalizer() {} void CollationBuilder::finalizeCEs(UErrorCode &errorCode) { if(U_FAILURE(errorCode)) { return; } - LocalPointer newBuilder(new CollationDataBuilder(errorCode)); - if(newBuilder.isNull()) { - errorCode = U_MEMORY_ALLOCATION_ERROR; + LocalPointer newBuilder(new CollationDataBuilder(errorCode), errorCode); + if(U_FAILURE(errorCode)) { return; } newBuilder->initForTailoring(baseData, errorCode); diff --git a/icu4c/source/i18n/decimfmt.cpp b/icu4c/source/i18n/decimfmt.cpp index da1f8d29f37..bc49f0ef418 100644 --- a/icu4c/source/i18n/decimfmt.cpp +++ b/icu4c/source/i18n/decimfmt.cpp @@ -2209,7 +2209,7 @@ CurrencyAmount* DecimalFormat::parseCurrency(const UnicodeString& text, parse(text, parseResult, pos, curbuf); if (pos.getIndex() != start) { UErrorCode ec = U_ZERO_ERROR; - LocalPointer currAmt(new CurrencyAmount(parseResult, curbuf, ec)); + LocalPointer currAmt(new CurrencyAmount(parseResult, curbuf, ec), ec); if (U_FAILURE(ec)) { pos.setIndex(start); // indicate failure } else { diff --git a/icu4c/source/i18n/filteredbrk.cpp b/icu4c/source/i18n/filteredbrk.cpp index cc6880a600f..7ecb004b3ff 100644 --- a/icu4c/source/i18n/filteredbrk.cpp +++ b/icu4c/source/i18n/filteredbrk.cpp @@ -374,13 +374,12 @@ BreakIterator * SimpleFilteredBreakIteratorBuilder::build(BreakIterator* adoptBreakIterator, UErrorCode& status) { LocalPointer adopt(adoptBreakIterator); + LocalPointer builder(new UCharsTrieBuilder(status), status); + LocalPointer builder2(new UCharsTrieBuilder(status), status); if(U_FAILURE(status)) { return NULL; } - LocalPointer builder(new UCharsTrieBuilder(status)); - LocalPointer builder2(new UCharsTrieBuilder(status)); - int32_t revCount = 0; int32_t fwdCount = 0; @@ -503,16 +502,14 @@ FilteredBreakIteratorBuilder::~FilteredBreakIteratorBuilder() { FilteredBreakIteratorBuilder * FilteredBreakIteratorBuilder::createInstance(const Locale& where, UErrorCode& status) { if(U_FAILURE(status)) return NULL; - LocalPointer ret(new SimpleFilteredBreakIteratorBuilder(where, status)); - if(U_SUCCESS(status) && !ret.isValid()) status = U_MEMORY_ALLOCATION_ERROR; + LocalPointer ret(new SimpleFilteredBreakIteratorBuilder(where, status), status); return ret.orphan(); } FilteredBreakIteratorBuilder * FilteredBreakIteratorBuilder::createInstance(UErrorCode& status) { if(U_FAILURE(status)) return NULL; - LocalPointer ret(new SimpleFilteredBreakIteratorBuilder(status)); - if(U_SUCCESS(status) && !ret.isValid()) status = U_MEMORY_ALLOCATION_ERROR; + LocalPointer ret(new SimpleFilteredBreakIteratorBuilder(status), status); return ret.orphan(); } diff --git a/icu4c/source/i18n/measfmt.cpp b/icu4c/source/i18n/measfmt.cpp index 48ed139000b..017200c85dd 100644 --- a/icu4c/source/i18n/measfmt.cpp +++ b/icu4c/source/i18n/measfmt.cpp @@ -350,14 +350,10 @@ const MeasureFormatCacheData *LocaleCacheKey::createObje LocalUResourceBundlePointer unitsBundle(ures_open(U_ICUDATA_UNIT, localeId, &status)); static UNumberFormatStyle currencyStyles[] = { UNUM_CURRENCY_PLURAL, UNUM_CURRENCY_ISO, UNUM_CURRENCY}; + LocalPointer result(new MeasureFormatCacheData(), status); if (U_FAILURE(status)) { return NULL; } - LocalPointer result(new MeasureFormatCacheData()); - if (result.isNull()) { - status = U_MEMORY_ALLOCATION_ERROR; - return NULL; - } if (!loadMeasureUnitData( unitsBundle.getAlias(), *result, diff --git a/icu4c/source/i18n/numfmt.cpp b/icu4c/source/i18n/numfmt.cpp index ed4239650cc..ff3e17d6d2b 100644 --- a/icu4c/source/i18n/numfmt.cpp +++ b/icu4c/source/i18n/numfmt.cpp @@ -731,7 +731,7 @@ CurrencyAmount* NumberFormat::parseCurrency(const UnicodeString& text, UErrorCode ec = U_ZERO_ERROR; getEffectiveCurrency(curr, ec); if (U_SUCCESS(ec)) { - LocalPointer currAmt(new CurrencyAmount(parseResult, curr, ec)); + LocalPointer currAmt(new CurrencyAmount(parseResult, curr, ec), ec); if (U_FAILURE(ec)) { pos.setIndex(start); // indicate failure } else { @@ -1375,9 +1375,8 @@ NumberFormat::makeInstance(const Locale& desiredLocale, } else { // Loads the decimal symbols of the desired locale. - symbolsToAdopt.adoptInstead(new DecimalFormatSymbols(desiredLocale, status)); - if (symbolsToAdopt.isNull()) { - status = U_MEMORY_ALLOCATION_ERROR; + symbolsToAdopt.adoptInsteadAndCheckErrorCode(new DecimalFormatSymbols(desiredLocale, status), status); + if (U_FAILURE(status)) { return NULL; } diff --git a/icu4c/source/i18n/region.cpp b/icu4c/source/i18n/region.cpp index 21123a16322..02be72d5d5a 100644 --- a/icu4c/source/i18n/region.cpp +++ b/icu4c/source/i18n/region.cpp @@ -78,14 +78,10 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RegionNameEnumeration) * anything meaningful. */ void Region::loadRegionData(UErrorCode &status) { - LocalPointer df(new DecimalFormat(status)); + LocalPointer df(new DecimalFormat(status), status); if (U_FAILURE(status)) { return; } - if (df == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - return; - } df->setParseIntegerOnly(TRUE); regionIDMap = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, &status); diff --git a/icu4c/source/test/intltest/calregts.cpp b/icu4c/source/test/intltest/calregts.cpp index 9a25c265187..e773dbea65a 100644 --- a/icu4c/source/test/intltest/calregts.cpp +++ b/icu4c/source/test/intltest/calregts.cpp @@ -1,6 +1,6 @@ /******************************************************************** * COPYRIGHT: - * Copyright (c) 1997-2013, International Business Machines Corporation + * Copyright (c) 1997-2014, International Business Machines Corporation * and others. All Rights Reserved. ********************************************************************/ @@ -202,16 +202,16 @@ void CalendarRegressionTest::Test9019() { UErrorCode status = U_ZERO_ERROR; - LocalPointer cal1(new GregorianCalendar(status)); - LocalPointer cal2(new GregorianCalendar(status)); - cal1->set(UCAL_HOUR, 1); - cal2->set(UCAL_HOUR,2); - cal1->clear(); - cal2->clear(); + LocalPointer cal1(new GregorianCalendar(status), status); + LocalPointer cal2(new GregorianCalendar(status), status); if(U_FAILURE(status)) { dataerrln("Error creating Calendar: %s", u_errorName(status)); return; } + cal1->set(UCAL_HOUR, 1); + cal2->set(UCAL_HOUR,2); + cal1->clear(); + cal2->clear(); failure(status, "new GregorianCalendar"); cal1->set(2011,UCAL_MAY,06); cal2->set(2012,UCAL_JANUARY,06); diff --git a/icu4c/source/test/intltest/dcfmapts.cpp b/icu4c/source/test/intltest/dcfmapts.cpp index 17f7f8fc43f..9e66f3de986 100644 --- a/icu4c/source/test/intltest/dcfmapts.cpp +++ b/icu4c/source/test/intltest/dcfmapts.cpp @@ -601,14 +601,14 @@ void IntlTestDecimalFormatAPI::TestScale() void IntlTestDecimalFormatAPI::TestFixedDecimal() { UErrorCode status = U_ZERO_ERROR; - LocalPointer df(new DecimalFormat("###", status)); + LocalPointer df(new DecimalFormat("###", status), status); TEST_ASSERT_STATUS(status); FixedDecimal fd = df->getFixedDecimal(44, status); TEST_ASSERT_STATUS(status); ASSERT_EQUAL(44, fd.source); ASSERT_EQUAL(0, fd.visibleDecimalDigitCount); - df.adoptInstead(new DecimalFormat("###.00##", status)); + df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###.00##", status), status); TEST_ASSERT_STATUS(status); fd = df->getFixedDecimal(123.456, status); TEST_ASSERT_STATUS(status); @@ -619,7 +619,7 @@ void IntlTestDecimalFormatAPI::TestFixedDecimal() { ASSERT_EQUAL(FALSE, fd.hasIntegerValue); ASSERT_EQUAL(FALSE, fd.isNegative); - df.adoptInstead(new DecimalFormat("###", status)); + df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###", status), status); TEST_ASSERT_STATUS(status); fd = df->getFixedDecimal(123.456, status); TEST_ASSERT_STATUS(status); @@ -630,7 +630,7 @@ void IntlTestDecimalFormatAPI::TestFixedDecimal() { ASSERT_EQUAL(TRUE, fd.hasIntegerValue); ASSERT_EQUAL(FALSE, fd.isNegative); - df.adoptInstead(new DecimalFormat("###.0", status)); + df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###.0", status), status); TEST_ASSERT_STATUS(status); fd = df->getFixedDecimal(123.01, status); TEST_ASSERT_STATUS(status); @@ -641,7 +641,7 @@ void IntlTestDecimalFormatAPI::TestFixedDecimal() { ASSERT_EQUAL(TRUE, fd.hasIntegerValue); ASSERT_EQUAL(FALSE, fd.isNegative); - df.adoptInstead(new DecimalFormat("###.0", status)); + df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###.0", status), status); TEST_ASSERT_STATUS(status); fd = df->getFixedDecimal(123.06, status); TEST_ASSERT_STATUS(status); @@ -652,7 +652,7 @@ void IntlTestDecimalFormatAPI::TestFixedDecimal() { ASSERT_EQUAL(FALSE, fd.hasIntegerValue); ASSERT_EQUAL(FALSE, fd.isNegative); - df.adoptInstead(new DecimalFormat("@@@@@", status)); // Significant Digits + df.adoptInsteadAndCheckErrorCode(new DecimalFormat("@@@@@", status), status); // Significant Digits TEST_ASSERT_STATUS(status); fd = df->getFixedDecimal(123, status); TEST_ASSERT_STATUS(status); @@ -663,7 +663,7 @@ void IntlTestDecimalFormatAPI::TestFixedDecimal() { ASSERT_EQUAL(TRUE, fd.hasIntegerValue); ASSERT_EQUAL(FALSE, fd.isNegative); - df.adoptInstead(new DecimalFormat("@@@@@", status)); // Significant Digits + df.adoptInsteadAndCheckErrorCode(new DecimalFormat("@@@@@", status), status); // Significant Digits TEST_ASSERT_STATUS(status); fd = df->getFixedDecimal(1.23, status); TEST_ASSERT_STATUS(status); @@ -686,7 +686,8 @@ void IntlTestDecimalFormatAPI::TestFixedDecimal() { // Test Big Decimal input. // 22 digits before and after decimal, will exceed the precision of a double // and force DecimalFormat::getFixedDecimal() to work with a digit list. - df.adoptInstead(new DecimalFormat("#####################0.00####################", status)); + df.adoptInsteadAndCheckErrorCode( + new DecimalFormat("#####################0.00####################", status), status); TEST_ASSERT_STATUS(status); Formattable fable("12.34", status); TEST_ASSERT_STATUS(status); @@ -814,7 +815,7 @@ void IntlTestDecimalFormatAPI::TestFixedDecimal() { void IntlTestDecimalFormatAPI::TestBadFastpath() { UErrorCode status = U_ZERO_ERROR; - LocalPointer df(new DecimalFormat("###", status)); + LocalPointer df(new DecimalFormat("###", status), status); if (U_FAILURE(status)) { dataerrln("Error creating new DecimalFormat - %s", u_errorName(status)); return; @@ -838,7 +839,7 @@ void IntlTestDecimalFormatAPI::TestRequiredDecimalPoint() { UnicodeString pat1("##.0000"); UnicodeString pat2("00.0"); - LocalPointer df(new DecimalFormat(pat1, status)); + LocalPointer df(new DecimalFormat(pat1, status), status); if (U_FAILURE(status)) { dataerrln("Error creating new DecimalFormat - %s", u_errorName(status)); return; diff --git a/icu4c/source/test/intltest/dtfmttst.cpp b/icu4c/source/test/intltest/dtfmttst.cpp index dae599635ed..2a602ecb34b 100644 --- a/icu4c/source/test/intltest/dtfmttst.cpp +++ b/icu4c/source/test/intltest/dtfmttst.cpp @@ -4357,7 +4357,7 @@ void DateFormatTest::TestDateFormatLeniency() { Locale locale = Locale::createFromName(itemPtr->locale); status = U_ZERO_ERROR; ParsePosition pos(0); - sdmft.adoptInstead(new SimpleDateFormat(itemPtr->pattern, locale, status)); + sdmft.adoptInsteadAndCheckErrorCode(new SimpleDateFormat(itemPtr->pattern, locale, status), status); if (U_FAILURE(status)) { dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status)); continue; @@ -4548,7 +4548,7 @@ void DateFormatTest::TestNumberFormatOverride() { UnicodeString fields = (UnicodeString) "M"; LocalPointer fmt; - fmt.adoptInstead(new SimpleDateFormat((UnicodeString)"MM d", status)); + fmt.adoptInsteadAndCheckErrorCode(new SimpleDateFormat((UnicodeString)"MM d", status), status); if (!assertSuccess("SimpleDateFormat with pattern MM d", status)) { return; } @@ -4582,7 +4582,7 @@ void DateFormatTest::TestNumberFormatOverride() { fields = DATA[i][0]; LocalPointer fmt; - fmt.adoptInstead(new SimpleDateFormat((UnicodeString)"MM d", status)); + fmt.adoptInsteadAndCheckErrorCode(new SimpleDateFormat((UnicodeString)"MM d", status), status); assertSuccess("SimpleDateFormat with pattern MM d", status); NumberFormat* overrideNF = NumberFormat::createInstance(Locale::createFromName("zh@numbers=hanidays"),status); assertSuccess("NumberFormat zh@numbers=hanidays", status); diff --git a/icu4c/source/test/intltest/dtifmtts.cpp b/icu4c/source/test/intltest/dtifmtts.cpp index f2c55eabf05..224f5b9732b 100644 --- a/icu4c/source/test/intltest/dtifmtts.cpp +++ b/icu4c/source/test/intltest/dtifmtts.cpp @@ -165,7 +165,7 @@ void DateIntervalFormatTest::testAPI() { errln("Failure encountered: %s", u_errorName(status)); return; } - LocalPointer dii(new DateIntervalInfo(Locale::getEnglish(), status)); + LocalPointer dii(new DateIntervalInfo(Locale::getEnglish(), status), status); if (U_FAILURE(status)) { errln("Failure encountered: %s", u_errorName(status)); return; @@ -1160,7 +1160,7 @@ void DateIntervalFormatTest::testFormatUserDII() { void DateIntervalFormatTest::testSetIntervalPatternNoSideEffect() { UErrorCode ec = U_ZERO_ERROR; - LocalPointer dtitvinf(new DateIntervalInfo(ec)); + LocalPointer dtitvinf(new DateIntervalInfo(ec), ec); if (U_FAILURE(ec)) { errln("Failure encountered: %s", u_errorName(ec)); return; @@ -1172,7 +1172,7 @@ void DateIntervalFormatTest::testSetIntervalPatternNoSideEffect() { errln("Failure encountered: %s", u_errorName(ec)); return; } - dtitvinf.adoptInstead(new DateIntervalInfo(ec)); + dtitvinf.adoptInsteadAndCheckErrorCode(new DateIntervalInfo(ec), ec); if (U_FAILURE(ec)) { errln("Failure encountered: %s", u_errorName(ec)); return; diff --git a/icu4c/source/test/intltest/itutil.cpp b/icu4c/source/test/intltest/itutil.cpp index 6ff3fab7777..ce2c5a85d7a 100644 --- a/icu4c/source/test/intltest/itutil.cpp +++ b/icu4c/source/test/intltest/itutil.cpp @@ -12,6 +12,7 @@ #include "unicode/utypes.h" #include "unicode/errorcode.h" #include "unicode/localpointer.h" +#include "charstr.h" #include "itutil.h" #include "strtest.h" #include "loctest.h" @@ -262,15 +263,12 @@ void LocalPointerTest::runIndexedTest(int32_t index, UBool exec, const char *&na if(exec) { logln("TestSuite LocalPointerTest: "); } - switch (index) { - TESTCASE(0, TestLocalPointer); - TESTCASE(1, TestLocalArray); - TESTCASE(2, TestLocalXyzPointer); - TESTCASE(3, TestLocalXyzPointerNull); - default: - name=""; - break; // needed to end the loop - } + TESTCASE_AUTO_BEGIN; + TESTCASE_AUTO(TestLocalPointer); + TESTCASE_AUTO(TestLocalArray); + TESTCASE_AUTO(TestLocalXyzPointer); + TESTCASE_AUTO(TestLocalXyzPointerNull); + TESTCASE_AUTO_END; } // Exercise every LocalPointer and LocalPointerBase method. @@ -301,6 +299,43 @@ void LocalPointerTest::TestLocalPointer() { if(s->length()!=0) { errln("LocalPointer adoptInstead(empty) failure"); } + + // LocalPointer(p, errorCode) sets U_MEMORY_ALLOCATION_ERROR if p==NULL. + UErrorCode errorCode = U_ZERO_ERROR; + LocalPointer cs(new CharString("some chars", errorCode), errorCode); + if(cs.isNull() && U_SUCCESS(errorCode)) { + errln("LocalPointer(p, errorCode) failure"); + return; + } + errorCode = U_ZERO_ERROR; + cs.adoptInsteadAndCheckErrorCode(new CharString("different chars", errorCode), errorCode); + if(cs.isNull() && U_SUCCESS(errorCode)) { + errln("adoptInsteadAndCheckErrorCode(p, errorCode) failure"); + return; + } + // Incoming failure: Keep the current object and delete the input object. + errorCode = U_ILLEGAL_ARGUMENT_ERROR; + cs.adoptInsteadAndCheckErrorCode(new CharString("unused", errorCode), errorCode); + if(cs.isValid() && strcmp(cs->data(), "different chars") != 0) { + errln("adoptInsteadAndCheckErrorCode(p, U_FAILURE) did not retain the old object"); + return; + } + errorCode = U_ZERO_ERROR; + cs.adoptInsteadAndCheckErrorCode(NULL, errorCode); + if(errorCode != U_MEMORY_ALLOCATION_ERROR) { + errln("adoptInsteadAndCheckErrorCode(NULL, errorCode) did not set U_MEMORY_ALLOCATION_ERROR"); + return; + } + if(cs.isValid()) { + errln("adoptInsteadAndCheckErrorCode(NULL, errorCode) kept the object"); + return; + } + errorCode = U_ZERO_ERROR; + LocalPointer null(NULL, errorCode); + if(errorCode != U_MEMORY_ALLOCATION_ERROR) { + errln("LocalPointer(NULL, errorCode) did not set U_MEMORY_ALLOCATION_ERROR"); + return; + } } // Exercise every LocalArray method (but not LocalPointerBase). diff --git a/icu4c/source/test/intltest/numrgts.cpp b/icu4c/source/test/intltest/numrgts.cpp index bf5345284a5..772bbe8bbf3 100644 --- a/icu4c/source/test/intltest/numrgts.cpp +++ b/icu4c/source/test/intltest/numrgts.cpp @@ -2995,7 +2995,7 @@ void NumberFormatRegressionTest::Test10361(void) { // preventing formatting of big decimals. UErrorCode status = U_ZERO_ERROR; DecimalFormatSymbols symbols(Locale::getEnglish(), status); - LocalPointer df(new DecimalFormat("###.##", symbols, status)); + LocalPointer df(new DecimalFormat("###.##", symbols, status), status); TEST_CHECK_STATUS(status); // Create a decimal number with a million digits. diff --git a/icu4c/source/test/intltest/plurults.cpp b/icu4c/source/test/intltest/plurults.cpp index 14e24191946..1e3f3de6c1b 100644 --- a/icu4c/source/test/intltest/plurults.cpp +++ b/icu4c/source/test/intltest/plurults.cpp @@ -125,12 +125,16 @@ void PluralRulesTest::testAPI(/*char *par*/) logln("\n start default locale test case ..\n"); PluralRules defRule(status); - LocalPointer test(new PluralRules(status)); - LocalPointer newEnPlural(test->forLocale(Locale::getEnglish(), status)); + LocalPointer test(new PluralRules(status), status); if(U_FAILURE(status)) { dataerrln("ERROR: Could not create PluralRules (default) - exitting"); return; } + LocalPointer newEnPlural(test->forLocale(Locale::getEnglish(), status), status); + if(U_FAILURE(status)) { + dataerrln("ERROR: Could not create PluralRules (English) - exitting"); + return; + } // ======= Test clone, assignment operator && == operator. LocalPointer dupRule(defRule.clone()); diff --git a/icu4c/source/test/intltest/regcoll.cpp b/icu4c/source/test/intltest/regcoll.cpp index 0cc127e704a..0168ad68645 100644 --- a/icu4c/source/test/intltest/regcoll.cpp +++ b/icu4c/source/test/intltest/regcoll.cpp @@ -101,15 +101,19 @@ void CollationRegressionTest::Test4051866(/* char* par */) rules += "< p ,P"; // Build a collator containing expanding characters - LocalPointer c1(new RuleBasedCollator(rules, status)); - - // Build another using the rules from the first - LocalPointer c2(new RuleBasedCollator(c1->getRules(), status)); + LocalPointer c1(new RuleBasedCollator(rules, status), status); if (U_FAILURE(status)) { errln("RuleBasedCollator(rule string) failed - %s", u_errorName(status)); return; } + // Build another using the rules from the first + LocalPointer c2(new RuleBasedCollator(c1->getRules(), status), status); + if (U_FAILURE(status)) { + errln("RuleBasedCollator(rule string from other RBC) failed - %s", u_errorName(status)); + return; + } + // Make sure they're the same if (!(c1->getRules() == c2->getRules())) { diff --git a/icu4c/source/test/intltest/thcoll.cpp b/icu4c/source/test/intltest/thcoll.cpp index 1054b53abaa..87fa4c895cb 100644 --- a/icu4c/source/test/intltest/thcoll.cpp +++ b/icu4c/source/test/intltest/thcoll.cpp @@ -459,7 +459,7 @@ void CollationThaiTest::TestReordering(void) { const char *testcontraction[] = { "\\u0E41ab", ">", "\\u0E41c"}; // After UCA 4.1 Thai are normal so won't break a contraction UnicodeString rules; parseChars(rules, rule); - LocalPointer rcoll(new RuleBasedCollator(rules, status)); + LocalPointer rcoll(new RuleBasedCollator(rules, status), status); if(U_SUCCESS(status)) { compareArray(*rcoll, testcontraction, 3); } else { diff --git a/icu4c/source/test/intltest/tufmtts.cpp b/icu4c/source/test/intltest/tufmtts.cpp index 9a814d22fa6..8ed9b9f7956 100644 --- a/icu4c/source/test/intltest/tufmtts.cpp +++ b/icu4c/source/test/intltest/tufmtts.cpp @@ -441,7 +441,8 @@ void TimeUnitTest::test10219Plurals() { } UnicodeString actual; Formattable fmt; - LocalPointer tamt(new TimeUnitAmount(values[j], TimeUnit::UTIMEUNIT_MINUTE, status)); + LocalPointer tamt( + new TimeUnitAmount(values[j], TimeUnit::UTIMEUNIT_MINUTE, status), status); if (U_FAILURE(status)) { dataerrln("generating TimeUnitAmount Object failed: %s", u_errorName(status)); return; diff --git a/icu4c/source/test/intltest/tzfmttst.cpp b/icu4c/source/test/intltest/tzfmttst.cpp index c3a03317cc4..6bc0b74c1dc 100644 --- a/icu4c/source/test/intltest/tzfmttst.cpp +++ b/icu4c/source/test/intltest/tzfmttst.cpp @@ -960,7 +960,7 @@ TimeZoneFormatTest::TestISOFormat(void) { // Formatting UErrorCode status = U_ZERO_ERROR; - LocalPointer sdf(new SimpleDateFormat(status)); + LocalPointer sdf(new SimpleDateFormat(status), status); if (U_FAILURE(status)) { dataerrln("Fail new SimpleDateFormat: %s", u_errorName(status)); return; diff --git a/icu4c/source/tools/gennorm2/gennorm2.cpp b/icu4c/source/tools/gennorm2/gennorm2.cpp index c665d82e985..237d8de7c74 100644 --- a/icu4c/source/tools/gennorm2/gennorm2.cpp +++ b/icu4c/source/tools/gennorm2/gennorm2.cpp @@ -142,7 +142,7 @@ main(int argc, char* argv[]) { #else - LocalPointer builder(new Normalizer2DataBuilder(errorCode)); + LocalPointer builder(new Normalizer2DataBuilder(errorCode), errorCode); errorCode.assertSuccess(); if(options[UNICODE_VERSION].doesOccur) {