From 46720c412089c719556858af27f9b34a0d0f37a4 Mon Sep 17 00:00:00 2001 From: Markus Scherer Date: Fri, 26 Mar 2021 14:09:11 -0700 Subject: [PATCH] ICU-21559 more guards for self-assignment --- icu4c/source/common/edits.cpp | 1 + icu4c/source/i18n/cpdtrans.cpp | 1 + icu4c/source/i18n/dtfmtsym.cpp | 1 + icu4c/source/i18n/number_decimfmtprops.h | 5 +++-- icu4c/source/i18n/number_fluent.cpp | 1 + icu4c/source/i18n/number_multiplier.cpp | 1 + icu4c/source/i18n/number_usageprefs.cpp | 1 + icu4c/source/i18n/numrange_fluent.cpp | 1 + icu4c/source/i18n/olsontz.cpp | 1 + icu4c/source/i18n/stsearch.cpp | 2 +- icu4c/source/i18n/translit.cpp | 1 + icu4c/source/i18n/windtfmt.cpp | 1 + icu4c/source/i18n/winnmfmt.cpp | 1 + icu4c/source/test/intltest/numbertest_api.cpp | 1 + icu4c/source/test/intltest/tsdtfmsy.cpp | 1 + icu4c/source/test/intltest/tztest.cpp | 4 +++- 16 files changed, 20 insertions(+), 4 deletions(-) diff --git a/icu4c/source/common/edits.cpp b/icu4c/source/common/edits.cpp index 95f0c19a728..92ca36fb5d0 100644 --- a/icu4c/source/common/edits.cpp +++ b/icu4c/source/common/edits.cpp @@ -86,6 +86,7 @@ Edits &Edits::moveArray(Edits &src) U_NOEXCEPT { } Edits &Edits::operator=(const Edits &other) { + if (this == &other) { return *this; } // self-assignment: no-op length = other.length; delta = other.delta; numChanges = other.numChanges; diff --git a/icu4c/source/i18n/cpdtrans.cpp b/icu4c/source/i18n/cpdtrans.cpp index 82ee54a77b5..dc0217ba612 100644 --- a/icu4c/source/i18n/cpdtrans.cpp +++ b/icu4c/source/i18n/cpdtrans.cpp @@ -282,6 +282,7 @@ void CompoundTransliterator::freeTransliterators(void) { CompoundTransliterator& CompoundTransliterator::operator=( const CompoundTransliterator& t) { + if (this == &t) { return *this; } // self-assignment: no-op Transliterator::operator=(t); int32_t i = 0; UBool failed = FALSE; diff --git a/icu4c/source/i18n/dtfmtsym.cpp b/icu4c/source/i18n/dtfmtsym.cpp index 81e3bf11090..937cf7036bc 100644 --- a/icu4c/source/i18n/dtfmtsym.cpp +++ b/icu4c/source/i18n/dtfmtsym.cpp @@ -450,6 +450,7 @@ DateFormatSymbols::copyData(const DateFormatSymbols& other) { */ DateFormatSymbols& DateFormatSymbols::operator=(const DateFormatSymbols& other) { + if (this == &other) { return *this; } // self-assignment: no-op dispose(); copyData(other); diff --git a/icu4c/source/i18n/number_decimfmtprops.h b/icu4c/source/i18n/number_decimfmtprops.h index 1ce84d9dc38..0ace241adae 100644 --- a/icu4c/source/i18n/number_decimfmtprops.h +++ b/icu4c/source/i18n/number_decimfmtprops.h @@ -38,7 +38,7 @@ namespace impl { // Exported as U_I18N_API because it is a public member field of exported DecimalFormatProperties // Using this wrapper is rather unfortunate, but is needed on Windows platforms in order to allow -// for DLL-exporting an fully specified template instantiation. +// for DLL-exporting a fully specified template instantiation. class U_I18N_API CurrencyPluralInfoWrapper { public: LocalPointer fPtr; @@ -52,7 +52,8 @@ public: } CurrencyPluralInfoWrapper& operator=(const CurrencyPluralInfoWrapper& other) { - if (!other.fPtr.isNull()) { + if (this != &other && // self-assignment: no-op + !other.fPtr.isNull()) { fPtr.adoptInstead(new CurrencyPluralInfo(*other.fPtr)); } return *this; diff --git a/icu4c/source/i18n/number_fluent.cpp b/icu4c/source/i18n/number_fluent.cpp index 0e27405132c..a79f224829d 100644 --- a/icu4c/source/i18n/number_fluent.cpp +++ b/icu4c/source/i18n/number_fluent.cpp @@ -442,6 +442,7 @@ LocalizedNumberFormatter::LocalizedNumberFormatter(NFS&& src) U_NOEXCEPT } LocalizedNumberFormatter& LocalizedNumberFormatter::operator=(const LNF& other) { + if (this == &other) { return *this; } // self-assignment: no-op NFS::operator=(static_cast&>(other)); UErrorCode localStatus = U_ZERO_ERROR; // Can't bubble up the error lnfCopyHelper(other, localStatus); diff --git a/icu4c/source/i18n/number_multiplier.cpp b/icu4c/source/i18n/number_multiplier.cpp index 8f07e548de1..58e1e441bd2 100644 --- a/icu4c/source/i18n/number_multiplier.cpp +++ b/icu4c/source/i18n/number_multiplier.cpp @@ -46,6 +46,7 @@ Scale::Scale(const Scale& other) } Scale& Scale::operator=(const Scale& other) { + if (this == &other) { return *this; } // self-assignment: no-op fMagnitude = other.fMagnitude; if (other.fArbitrary != nullptr) { UErrorCode localStatus = U_ZERO_ERROR; diff --git a/icu4c/source/i18n/number_usageprefs.cpp b/icu4c/source/i18n/number_usageprefs.cpp index ff285dbf972..ed426da086e 100644 --- a/icu4c/source/i18n/number_usageprefs.cpp +++ b/icu4c/source/i18n/number_usageprefs.cpp @@ -34,6 +34,7 @@ StringProp::StringProp(const StringProp &other) : StringProp() { // Copy assignment operator StringProp &StringProp::operator=(const StringProp &other) { + if (this == &other) { return *this; } // self-assignment: no-op fLength = 0; fError = other.fError; if (fValue != nullptr) { diff --git a/icu4c/source/i18n/numrange_fluent.cpp b/icu4c/source/i18n/numrange_fluent.cpp index d9286d1d713..f1060b3c21d 100644 --- a/icu4c/source/i18n/numrange_fluent.cpp +++ b/icu4c/source/i18n/numrange_fluent.cpp @@ -245,6 +245,7 @@ LocalizedNumberRangeFormatter::LocalizedNumberRangeFormatter(NFS&& src) U_N } LocalizedNumberRangeFormatter& LocalizedNumberRangeFormatter::operator=(const LNF& other) { + if (this == &other) { return *this; } // self-assignment: no-op NFS::operator=(static_cast&>(other)); // Do not steal; just clear delete fAtomicFormatter.exchange(nullptr); diff --git a/icu4c/source/i18n/olsontz.cpp b/icu4c/source/i18n/olsontz.cpp index 1d0fa804b20..b56c4a7bac2 100644 --- a/icu4c/source/i18n/olsontz.cpp +++ b/icu4c/source/i18n/olsontz.cpp @@ -274,6 +274,7 @@ OlsonTimeZone::OlsonTimeZone(const OlsonTimeZone& other) : * Assignment operator */ OlsonTimeZone& OlsonTimeZone::operator=(const OlsonTimeZone& other) { + if (this == &other) { return *this; } // self-assignment: no-op canonicalID = other.canonicalID; transitionTimesPre32 = other.transitionTimesPre32; diff --git a/icu4c/source/i18n/stsearch.cpp b/icu4c/source/i18n/stsearch.cpp index 3e6ed4648be..7fcd2bd93fe 100644 --- a/icu4c/source/i18n/stsearch.cpp +++ b/icu4c/source/i18n/stsearch.cpp @@ -184,7 +184,7 @@ StringSearch::clone() const { // operator overloading --------------------------------------------- StringSearch & StringSearch::operator=(const StringSearch &that) { - if ((*this) != that) { + if (this != &that) { UErrorCode status = U_ZERO_ERROR; m_text_ = that.m_text_; m_breakiterator_ = that.m_breakiterator_; diff --git a/icu4c/source/i18n/translit.cpp b/icu4c/source/i18n/translit.cpp index ef44f42aa66..9b2eaad77f0 100644 --- a/icu4c/source/i18n/translit.cpp +++ b/icu4c/source/i18n/translit.cpp @@ -170,6 +170,7 @@ Transliterator* Transliterator::clone() const { * Assignment operator. */ Transliterator& Transliterator::operator=(const Transliterator& other) { + if (this == &other) { return *this; } // self-assignment: no-op ID = other.ID; // NUL-terminate the ID string ID.getTerminatedBuffer(); diff --git a/icu4c/source/i18n/windtfmt.cpp b/icu4c/source/i18n/windtfmt.cpp index bcf272bc612..f6a990ea29e 100644 --- a/icu4c/source/i18n/windtfmt.cpp +++ b/icu4c/source/i18n/windtfmt.cpp @@ -193,6 +193,7 @@ Win32DateFormat::~Win32DateFormat() Win32DateFormat &Win32DateFormat::operator=(const Win32DateFormat &other) { + if (this == &other) { return *this; } // self-assignment: no-op // The following handles fCalendar DateFormat::operator=(other); diff --git a/icu4c/source/i18n/winnmfmt.cpp b/icu4c/source/i18n/winnmfmt.cpp index 72da1be28b8..8b2a9a4f958 100644 --- a/icu4c/source/i18n/winnmfmt.cpp +++ b/icu4c/source/i18n/winnmfmt.cpp @@ -268,6 +268,7 @@ Win32NumberFormat::~Win32NumberFormat() Win32NumberFormat &Win32NumberFormat::operator=(const Win32NumberFormat &other) { + if (this == &other) { return *this; } // self-assignment: no-op NumberFormat::operator=(other); this->fCurrency = other.fCurrency; diff --git a/icu4c/source/test/intltest/numbertest_api.cpp b/icu4c/source/test/intltest/numbertest_api.cpp index 689af5c4885..eedf4524dfe 100644 --- a/icu4c/source/test/intltest/numbertest_api.cpp +++ b/icu4c/source/test/intltest/numbertest_api.cpp @@ -1209,6 +1209,7 @@ void NumberFormatterApiTest::unitArbitraryMeasureUnits() { .unit(MeasureUnit::forIdentifier("pow4-mile", status)) .unitWidth(UNUM_UNIT_WIDTH_FULL_NAME) .locale("en-ZA"); + lnf.operator=(lnf); // self-assignment should be a no-op lnf.formatInt(1, status); status.expectErrorAndReset(U_RESOURCE_TYPE_MISMATCH); diff --git a/icu4c/source/test/intltest/tsdtfmsy.cpp b/icu4c/source/test/intltest/tsdtfmsy.cpp index c1efcc2ad85..2c1a1832e75 100644 --- a/icu4c/source/test/intltest/tsdtfmsy.cpp +++ b/icu4c/source/test/intltest/tsdtfmsy.cpp @@ -149,6 +149,7 @@ void IntlTestDateFormatSymbols::TestGetSetSpecificItems() dataerrln("ERROR: Couldn't create English DateFormatSymbols " + (UnicodeString)u_errorName(status)); return; } + symbol->operator=(*symbol); // self-assignment should be a no-op int32_t cntFmtAbbrev, cntFmtShort, cntStdAloneShort; const UnicodeString * wdFmtAbbrev = symbol->getWeekdays(cntFmtAbbrev,DateFormatSymbols::FORMAT,DateFormatSymbols::ABBREVIATED); const UnicodeString * wdFmtShort = symbol->getWeekdays(cntFmtShort,DateFormatSymbols::FORMAT,DateFormatSymbols::SHORT); diff --git a/icu4c/source/test/intltest/tztest.cpp b/icu4c/source/test/intltest/tztest.cpp index 93d992f778f..b877db5161f 100644 --- a/icu4c/source/test/intltest/tztest.cpp +++ b/icu4c/source/test/intltest/tztest.cpp @@ -1171,8 +1171,10 @@ void TimeZoneTest::TestCustomParse() TimeZone *zone = TimeZone::createTimeZone(id); UnicodeString itsID, temp; - if (dynamic_cast(zone) != NULL) { + OlsonTimeZone *ozone = dynamic_cast(zone); + if (ozone != nullptr) { logln(id + " -> Olson time zone"); + ozone->operator=(*ozone); // self-assignment should be a no-op } else { zone->getID(itsID); int32_t ioffset = zone->getRawOffset()/1000;