diff --git a/.github/workflows/icu4c.yml b/.github/workflows/icu4c.yml index 9821c95feba4..a24fc512fb73 100644 --- a/.github/workflows/icu4c.yml +++ b/.github/workflows/icu4c.yml @@ -185,6 +185,25 @@ jobs: cd $PREFIX/bin; LD_LIBRARY_PATH=../lib ./icuinfo + gcc-warnings-as-errors: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: ICU4C with gcc and treat warnings as errors. + env: + PREFIX: /tmp/icu-prefix + CXXFLAGS: -Wextra -Werror -Wno-return-local-addr + CFLAGS: -Werror + run: | + mkdir build; + cd build; + ../icu4c/source/runConfigureICU Linux/gcc --disable-layout --disable-layoutex --prefix=$PREFIX; + make -j -l4.5 check; + make -j -l4.5 install; + cd $PREFIX/bin; + LD_LIBRARY_PATH=../lib ./icuinfo + # Clang Linux with address sanitizer. clang-asan: runs-on: ubuntu-latest @@ -915,4 +934,4 @@ jobs: uses: actions/upload-artifact@v4 with: name: icuexportdata_output - path: icuexportdata_tag-goes-here.zip \ No newline at end of file + path: icuexportdata_tag-goes-here.zip diff --git a/icu4c/source/common/ucnvmbcs.cpp b/icu4c/source/common/ucnvmbcs.cpp index 6b4d1491a2a6..a6629668f9bf 100644 --- a/icu4c/source/common/ucnvmbcs.cpp +++ b/icu4c/source/common/ucnvmbcs.cpp @@ -3144,13 +3144,14 @@ ucnv_MBCSGetNextUChar(UConverterToUnicodeArgs *pArgs, } if(c<0) { - if(U_SUCCESS(*pErrorCode) && source==sourceLimit && lastSourcetoUBytes)) { /* incomplete character byte sequence */ uint8_t *bytes=cnv->toUBytes; cnv->toULength = static_cast(source - lastSource); do { *bytes++=*lastSource++; - } while(lastSourcetoUBytes[sizeof(cnv->toUBytes)-1])); *pErrorCode=U_TRUNCATED_CHAR_FOUND; } else if(U_FAILURE(*pErrorCode)) { /* callback(illegal) */ diff --git a/icu4c/source/common/ucurr.cpp b/icu4c/source/common/ucurr.cpp index 282199257376..9eceb43aeb37 100644 --- a/icu4c/source/common/ucurr.cpp +++ b/icu4c/source/common/ucurr.cpp @@ -372,12 +372,8 @@ struct CReg : public icu::UMemory { CReg(const char16_t* _iso, const char* _id) : next(nullptr) { - int32_t len = static_cast(uprv_strlen(_id)); - if (len > static_cast(sizeof(id) - 1)) { - len = (sizeof(id)-1); - } - uprv_strncpy(id, _id, len); - id[len] = 0; + uprv_strncpy(id, _id, sizeof(id)-1); + id[sizeof(id)-1] = 0; u_memcpy(iso, _iso, ISO_CURRENCY_CODE_LENGTH); iso[ISO_CURRENCY_CODE_LENGTH] = 0; } diff --git a/icu4c/source/common/ushape.cpp b/icu4c/source/common/ushape.cpp index 0843889d2dd4..c9464326727b 100644 --- a/icu4c/source/common/ushape.cpp +++ b/icu4c/source/common/ushape.cpp @@ -28,6 +28,7 @@ #include "ubidi_props.h" #include "uassert.h" +#include /* * This implementation is designed for 16-bit Unicode strings. * The main assumption is that the Arabic characters and their @@ -747,6 +748,10 @@ handleGeneratedSpaces(char16_t *dest, int32_t sourceLength, } } + if (static_cast((sourceLength + 1)) > (std::numeric_limits::max() / U_SIZEOF_UCHAR)) { + *pErrorCode = U_INDEX_OUTOFBOUNDS_ERROR; + return 0; + } tempbuffer = static_cast(uprv_malloc((sourceLength + 1) * U_SIZEOF_UCHAR)); /* Test for nullptr */ if(tempbuffer == nullptr) { diff --git a/icu4c/source/i18n/calendar.cpp b/icu4c/source/i18n/calendar.cpp index f74446b43765..c58563e8de25 100644 --- a/icu4c/source/i18n/calendar.cpp +++ b/icu4c/source/i18n/calendar.cpp @@ -828,9 +828,9 @@ Calendar::operator=(const Calendar &right) fWeekendCease = right.fWeekendCease; fWeekendCeaseMillis = right.fWeekendCeaseMillis; fNextStamp = right.fNextStamp; - uprv_strncpy(validLocale, right.validLocale, sizeof(validLocale)); - uprv_strncpy(actualLocale, right.actualLocale, sizeof(actualLocale)); + uprv_strncpy(validLocale, right.validLocale, sizeof(validLocale)-1); validLocale[sizeof(validLocale)-1] = 0; + uprv_strncpy(actualLocale, right.actualLocale, sizeof(actualLocale)-1); actualLocale[sizeof(validLocale)-1] = 0; } diff --git a/icu4c/source/i18n/decNumber.cpp b/icu4c/source/i18n/decNumber.cpp index 96ad3d7f986a..b35c76624cbe 100644 --- a/icu4c/source/i18n/decNumber.cpp +++ b/icu4c/source/i18n/decNumber.cpp @@ -267,8 +267,10 @@ static decNumber * decExpOp(decNumber *, const decNumber *, static void decFinalize(decNumber *, decContext *, Int *, uInt *); static Int decGetDigits(Unit *, Int); static Int decGetInt(const decNumber *); +#ifdef UNUSED_AND_WARNING_FUNCTIONS static decNumber * decLnOp(decNumber *, const decNumber *, decContext *, uInt *); +#endif // #ifdef UNUSED_AND_WARNING_FUNCTIONS static decNumber * decMultiplyOp(decNumber *, const decNumber *, const decNumber *, decContext *, uInt *); @@ -1289,6 +1291,7 @@ U_CAPI decNumber * U_EXPORT2 uprv_decNumberInvert(decNumber *res, const decNumbe /* (+11) range needed by Ln, Log10, etc. (which may have to be able */ /* to calculate at p+e+2). */ /* ------------------------------------------------------------------ */ +#ifdef UNUSED_AND_WARNING_FUNCTIONS U_CAPI decNumber * U_EXPORT2 uprv_decNumberLn(decNumber *res, const decNumber *rhs, decContext *set) { uInt status=0; /* accumulator */ @@ -1330,6 +1333,7 @@ U_CAPI decNumber * U_EXPORT2 uprv_decNumberLn(decNumber *res, const decNumber *r #endif return res; } /* decNumberLn */ +#endif // #ifdef UNUSED_AND_WARNING_FUNCTIONS /* ------------------------------------------------------------------ */ /* decNumberLogB - get adjusted exponent, by 754 rules */ @@ -1411,6 +1415,7 @@ U_CAPI decNumber * U_EXPORT2 uprv_decNumberLogB(decNumber *res, const decNumber /* fastpath in decLnOp. The final division is done to the requested */ /* precision. */ /* ------------------------------------------------------------------ */ +#ifdef UNUSED_AND_WARNING_FUNCTIONS #if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warray-bounds" @@ -1553,6 +1558,7 @@ U_CAPI decNumber * U_EXPORT2 uprv_decNumberLog10(decNumber *res, const decNumber #if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406 #pragma GCC diagnostic pop #endif +#endif // #ifdef UNUSED_AND_WARNING_FUNCTIONS /* ------------------------------------------------------------------ */ /* decNumberMax -- compare two Numbers and return the maximum */ @@ -1971,6 +1977,7 @@ U_CAPI decNumber * U_EXPORT2 uprv_decNumberMultiply(decNumber *res, const decNum /* almost always be correctly rounded, but may be up to 1 ulp in */ /* error in rare cases. */ /* ------------------------------------------------------------------ */ +#ifdef UNUSED_AND_WARNING_FUNCTIONS U_CAPI decNumber * U_EXPORT2 uprv_decNumberPower(decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set) { #if DECSUBSET @@ -2297,6 +2304,7 @@ U_CAPI decNumber * U_EXPORT2 uprv_decNumberPower(decNumber *res, const decNumber #endif return res; } /* decNumberPower */ +#endif // #ifdef UNUSED_AND_WARNING_FUNCTIONS /* ------------------------------------------------------------------ */ /* decNumberQuantize -- force exponent to requested value */ @@ -2826,6 +2834,7 @@ U_CAPI decNumber * U_EXPORT2 uprv_decNumberShift(decNumber *res, const decNumber /* result setexp(approx, e div 2) % fix exponent */ /* end sqrt */ /* ------------------------------------------------------------------ */ +#ifdef UNUSED_AND_WARNING_FUNCTIONS #if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warray-bounds" @@ -3162,6 +3171,7 @@ U_CAPI decNumber * U_EXPORT2 uprv_decNumberSquareRoot(decNumber *res, const decN #if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406 #pragma GCC diagnostic pop #endif +#endif // #ifdef UNUSED_AND_WARNING_FUNCTIONS /* ------------------------------------------------------------------ */ /* decNumberSubtract -- subtract two Numbers */ @@ -5550,6 +5560,7 @@ decNumber * decExpOp(decNumber *res, const decNumber *rhs, /* where x is truncated (NB) into the range 10 through 99, */ /* and then c = k>>2 and e = k&3. */ /* ------------------------------------------------------------------ */ +#ifdef UNUSED_AND_WARNING_FUNCTIONS static const uShort LNnn[90]={9016, 8652, 8316, 8008, 7724, 7456, 7208, 6972, 6748, 6540, 6340, 6148, 5968, 5792, 5628, 5464, 5312, 5164, 5020, 4884, 4748, 4620, 4496, 4376, 4256, 4144, 4032, @@ -5560,6 +5571,7 @@ static const uShort LNnn[90]={9016, 8652, 8316, 8008, 7724, 7456, 7208, 10197, 9685, 9177, 8677, 8185, 7697, 7213, 6737, 6269, 5801, 5341, 4889, 4437, 39930, 35534, 31186, 26886, 22630, 18418, 14254, 10130, 6046, 20055}; +#endif // #ifdef UNUSED_AND_WARNING_FUNCTIONS /* ------------------------------------------------------------------ */ /* decLnOp -- effect natural logarithm */ @@ -5622,6 +5634,7 @@ static const uShort LNnn[90]={9016, 8652, 8316, 8008, 7724, 7456, 7208, /* 5. The static buffers are larger than might be expected to allow */ /* for calls from decNumberPower. */ /* ------------------------------------------------------------------ */ +#ifdef UNUSED_AND_WARNING_FUNCTIONS #if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warray-bounds" @@ -5850,6 +5863,7 @@ decNumber * decLnOp(decNumber *res, const decNumber *rhs, #if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406 #pragma GCC diagnostic pop #endif +#endif // #ifdef UNUSED_AND_WARNING_FUNCTIONS /* ------------------------------------------------------------------ */ /* decQuantizeOp -- force exponent to requested value */ diff --git a/icu4c/source/i18n/formattedvalue.cpp b/icu4c/source/i18n/formattedvalue.cpp index aacd6ac70e09..3c15b14f05a8 100644 --- a/icu4c/source/i18n/formattedvalue.cpp +++ b/icu4c/source/i18n/formattedvalue.cpp @@ -193,6 +193,12 @@ ucfpos_close(UConstrainedFieldPosition* ptr) { } +// -Wreturn-local-addr first found in https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/Warning-Options.html#Warning-Options +#if U_GCC_MAJOR_MINOR >= 409 +#pragma GCC diagnostic push +#pragma GCC diagnostic warning "-Wreturn-local-addr" +#pragma GCC diagnostic ignored "-Wreturn-local-addr" +#endif U_CAPI const char16_t* U_EXPORT2 ufmtval_getString( const UFormattedValue* ufmtval, @@ -213,6 +219,9 @@ ufmtval_getString( // defined to return memory owned by the ufmtval argument. return readOnlyAlias.getBuffer(); } +#if U_GCC_MAJOR_MINOR >= 409 +#pragma GCC diagnostic pop +#endif U_CAPI UBool U_EXPORT2 diff --git a/icu4c/source/i18n/number_rounding.cpp b/icu4c/source/i18n/number_rounding.cpp index 8f1aa453ada4..cdf180d85616 100644 --- a/icu4c/source/i18n/number_rounding.cpp +++ b/icu4c/source/i18n/number_rounding.cpp @@ -283,6 +283,10 @@ FractionPrecision Precision::constructFraction(int32_t minFrac, int32_t maxFrac) settings.fMaxFrac = static_cast(maxFrac); settings.fMinSig = -1; settings.fMaxSig = -1; + // The following are not used under RND_FRACTION but initialize to avoid + // warning. + settings.fPriority = UNUM_ROUNDING_PRIORITY_RELAXED; + settings.fRetain = false; PrecisionUnion union_; union_.fracSig = settings; return {RND_FRACTION, union_}; @@ -294,6 +298,10 @@ Precision Precision::constructSignificant(int32_t minSig, int32_t maxSig) { settings.fMaxFrac = -1; settings.fMinSig = static_cast(minSig); settings.fMaxSig = static_cast(maxSig); + // The following are not used under RND_SIGNIFICANT, but initialize to avoid + // warning. + settings.fPriority = UNUM_ROUNDING_PRIORITY_RELAXED; + settings.fRetain = false; PrecisionUnion union_; union_.fracSig = settings; return {RND_SIGNIFICANT, union_}; diff --git a/icu4c/source/i18n/number_skeletons.cpp b/icu4c/source/i18n/number_skeletons.cpp index 562a8663d057..67a38dad0737 100644 --- a/icu4c/source/i18n/number_skeletons.cpp +++ b/icu4c/source/i18n/number_skeletons.cpp @@ -1015,6 +1015,12 @@ blueprint_helpers::parseExponentSignOption(const StringSegment& segment, MacroPr return true; } +// The function is called by skeleton::parseOption which called by skeleton::parseSkeleton +// the data pointed in the return macros.unit is stack allocated in the parseSkeleton function. +#if U_GCC_MAJOR_MINOR >= 1204 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdangling-pointer" +#endif void blueprint_helpers::parseCurrencyOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status) { // Unlike ICU4J, have to check length manually because ICU4C CurrencyUnit does not check it for us @@ -1034,6 +1040,9 @@ void blueprint_helpers::parseCurrencyOption(const StringSegment& segment, MacroP // Slicing is OK macros.unit = currency; // NOLINT } +#if U_GCC_MAJOR_MINOR >= 1204 +#pragma GCC diagnostic pop +#endif void blueprint_helpers::generateCurrencyOption(const CurrencyUnit& currency, UnicodeString& sb, UErrorCode&) { diff --git a/icu4c/source/test/cintltst/cbiditst.c b/icu4c/source/test/cintltst/cbiditst.c index 8b0a01057045..ee80366090aa 100644 --- a/icu4c/source/test/cintltst/cbiditst.c +++ b/icu4c/source/test/cintltst/cbiditst.c @@ -4730,6 +4730,7 @@ checkMaps(UBiDi *pBiDi, int32_t stringIndex, const char *src, const char *dest, ); testOK = false; } + memset(getIndexMap, 0, sizeof(getIndexMap)); for (i = 0; i < srcLen; i++) { idx = ubidi_getVisualIndex(pBiDi, i, &rc); assertSuccessful("ubidi_getVisualIndex", &rc); diff --git a/icu4c/source/test/cintltst/custrtrn.c b/icu4c/source/test/cintltst/custrtrn.c index 7987dacc9ff6..6a7890baec35 100644 --- a/icu4c/source/test/cintltst/custrtrn.c +++ b/icu4c/source/test/cintltst/custrtrn.c @@ -1527,7 +1527,7 @@ static void Test_strToJavaModifiedUTF8(void) { 0xee, 0x80, 0x81, 0xee, 0x80, 0x82, 0xee, 0x80, 0x83, 0xed, 0xa0, 0x80, 0xed, 0xb0, 0x80, 0xed, 0xb0, 0x80, 0xed, 0xa0, 0x80, 0xc0, 0x80, 0xed, 0xaf, 0xbf, 0xed, 0xbf, 0xbf, - 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0xc3, 0xad, 0xe0, 0xb8, 0x8e, 0x6f + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0xc3, 0xad, 0xe0, 0xb8, 0x8e, 0x6f, 0 }; static const UChar shortSrc[]={ 0xe01, 0xe1, 0x61 @@ -1554,7 +1554,7 @@ static void Test_strToJavaModifiedUTF8(void) { p=u_strToJavaModifiedUTF8(dest, (int32_t)sizeof(dest), &length, src, UPRV_LENGTHOF(src), &errorCode); if( U_FAILURE(errorCode) || p!=dest || - length!=UPRV_LENGTHOF(expected) || 0!=memcmp(dest, expected, length) || + length!=(UPRV_LENGTHOF(expected)-1) || 0!=memcmp(dest, expected, length) || dest[length]!=0 ) { log_err("u_strToJavaModifiedUTF8(normal) failed - %s\n", u_errorName(errorCode)); @@ -1565,18 +1565,18 @@ static void Test_strToJavaModifiedUTF8(void) { p=u_strToJavaModifiedUTF8(dest, (int32_t)sizeof(dest), NULL, src, UPRV_LENGTHOF(src), &errorCode); if( U_FAILURE(errorCode) || p!=dest || - 0!=memcmp(dest, expected, UPRV_LENGTHOF(expected)) || - dest[UPRV_LENGTHOF(expected)]!=0 + 0!=memcmp(dest, expected, (UPRV_LENGTHOF(expected)-1)) || + dest[(UPRV_LENGTHOF(expected)-1)]!=0 ) { log_err("u_strToJavaModifiedUTF8(normal, pLength=NULL) failed - %s\n", u_errorName(errorCode)); } memset(dest, 0xff, sizeof(dest)); errorCode=U_ZERO_ERROR; length=-5; - p=u_strToJavaModifiedUTF8(dest, UPRV_LENGTHOF(expected), &length, + p=u_strToJavaModifiedUTF8(dest, (UPRV_LENGTHOF(expected)-1), &length, src, UPRV_LENGTHOF(src), &errorCode); if( errorCode!=U_STRING_NOT_TERMINATED_WARNING || p!=dest || - length!=UPRV_LENGTHOF(expected) || 0!=memcmp(dest, expected, length) || + length!=(UPRV_LENGTHOF(expected)-1) || 0!=memcmp(dest, expected, length) || dest[length]!=(char)0xff ) { log_err("u_strToJavaModifiedUTF8(tight) failed - %s\n", u_errorName(errorCode)); @@ -1604,10 +1604,10 @@ static void Test_strToJavaModifiedUTF8(void) { memset(dest, 0xff, sizeof(dest)); errorCode=U_ZERO_ERROR; length=-5; - p=u_strToJavaModifiedUTF8(dest, UPRV_LENGTHOF(expected)/2, &length, + p=u_strToJavaModifiedUTF8(dest, (UPRV_LENGTHOF(expected)-1)/2, &length, src, UPRV_LENGTHOF(src), &errorCode); if( errorCode!=U_BUFFER_OVERFLOW_ERROR || - length!=UPRV_LENGTHOF(expected) || dest[UPRV_LENGTHOF(expected)/2]!=(char)0xff + length!=(UPRV_LENGTHOF(expected)-1) || dest[(UPRV_LENGTHOF(expected)-1)/2]!=(char)0xff ) { log_err("u_strToJavaModifiedUTF8(overflow) failed - %s\n", u_errorName(errorCode)); } @@ -1617,7 +1617,7 @@ static void Test_strToJavaModifiedUTF8(void) { p=u_strToJavaModifiedUTF8(NULL, 0, &length, src, UPRV_LENGTHOF(src), &errorCode); if( errorCode!=U_BUFFER_OVERFLOW_ERROR || - length!=UPRV_LENGTHOF(expected) || dest[0]!=(char)0xff + length!=(UPRV_LENGTHOF(expected)-1) || dest[0]!=(char)0xff ) { log_err("u_strToJavaModifiedUTF8(pure preflighting) failed - %s\n", u_errorName(errorCode)); } diff --git a/icu4c/source/test/cintltst/hpmufn.c b/icu4c/source/test/cintltst/hpmufn.c index f27e57939959..959a4cbd8ba0 100644 --- a/icu4c/source/test/cintltst/hpmufn.c +++ b/icu4c/source/test/cintltst/hpmufn.c @@ -116,7 +116,7 @@ static void * U_CALLCONV myMemRealloc(const void *context, void *mem, size_t siz } retPtr = realloc(p, size+sizeof(ctest_AlignedMemory)); if (retPtr != NULL) { - p += sizeof(ctest_AlignedMemory); + retPtr += sizeof(ctest_AlignedMemory); } return retPtr; } diff --git a/icu4c/source/test/cintltst/ucptrietest.c b/icu4c/source/test/cintltst/ucptrietest.c index 1a75a3a2f0dc..18258f8f31fc 100644 --- a/icu4c/source/test/cintltst/ucptrietest.c +++ b/icu4c/source/test/cintltst/ucptrietest.c @@ -744,7 +744,13 @@ trieTestGolden(const char *testName, goto cleanup; } fseek(stream, 0, SEEK_SET); - fread(memoryBuffer, 1, fsize, stream); + long rsize = fread(memoryBuffer, 1, fsize, stream); + if (rsize != fsize) { + log_err( + "Golden files for '%s' fread %d bytes fail. Only get %d", + testName, fsize, rsize); + } + int32_t testResult = uprv_compareGoldenFiles( memoryBuffer, fsize, diff --git a/icu4c/source/test/cintltst/uformattedvaluetst.c b/icu4c/source/test/cintltst/uformattedvaluetst.c index edc745a3a888..5cc086d3e3b0 100644 --- a/icu4c/source/test/cintltst/uformattedvaluetst.c +++ b/icu4c/source/test/cintltst/uformattedvaluetst.c @@ -143,7 +143,7 @@ static void AssertAllPartsEqual( UErrorCode status = U_ZERO_ERROR; - char message[256]; + char message[257]; uprv_strncpy(message, messagePrefix, 256); int32_t prefixEnd = (int32_t)uprv_strlen(messagePrefix); message[prefixEnd++] = ':'; diff --git a/icu4c/source/test/cintltst/utf16tst.c b/icu4c/source/test/cintltst/utf16tst.c index d6253f9c7ddc..3be25f9b4676 100644 --- a/icu4c/source/test/cintltst/utf16tst.c +++ b/icu4c/source/test/cintltst/utf16tst.c @@ -397,6 +397,10 @@ static void TestNextPrevChar(void){ } +#if U_GCC_MAJOR_MINOR >= 406 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" +#endif /* keep this in sync with utf8tst.c's TestNulTerminated() */ static void TestNulTerminated(void) { static const UChar input[]={ @@ -477,6 +481,9 @@ static void TestNulTerminated(void) { } while(++j= 406 +#pragma GCC diagnostic pop +#endif static void TestFwdBack(void){ static UChar input[]={0x0061, 0xd800, 0xdc00, 0xdbff, 0xdfff, 0x0062, 0xd841, 0xd7ff, 0xd841, 0xdc41, 0xdc00, 0x0000}; diff --git a/icu4c/source/test/cintltst/utf8tst.c b/icu4c/source/test/cintltst/utf8tst.c index a5f3379fe028..44fc9faba30c 100644 --- a/icu4c/source/test/cintltst/utf8tst.c +++ b/icu4c/source/test/cintltst/utf8tst.c @@ -449,6 +449,10 @@ static void TestNextPrevChar(void) { } } +#if U_GCC_MAJOR_MINOR >= 406 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" +#endif /* keep this in sync with utf16tst.c's TestNulTerminated() */ static void TestNulTerminated(void) { static const uint8_t input[]={ @@ -543,6 +547,9 @@ static void TestNulTerminated(void) { } while(++j= 406 +#pragma GCC diagnostic pop +#endif static void TestNextPrevNonCharacters(void) { /* test non-characters */ diff --git a/icu4c/source/test/intltest/caltest.cpp b/icu4c/source/test/intltest/caltest.cpp index bae5eac77bc6..502f6b69ac51 100644 --- a/icu4c/source/test/intltest/caltest.cpp +++ b/icu4c/source/test/intltest/caltest.cpp @@ -2442,7 +2442,7 @@ void CalendarTest::TestRepeatedWallTime() { calFirst.setRepeatedWallTimeOption(UCAL_WALLTIME_FIRST); for (int32_t i = 0; RPDATA[i].tzid != nullptr; i++) { - char buf[32]; + char buf[33]; TimeZone *tz = TimeZone::createTimeZone(RPDATA[i].tzid); // UCAL_WALLTIME_LAST @@ -2544,7 +2544,7 @@ void CalendarTest::TestSkippedWallTime() { for (int32_t i = 0; SKDATA[i].tzid != nullptr; i++) { UDate d; - char buf[32]; + char buf[33]; TimeZone *tz = TimeZone::createTimeZone(SKDATA[i].tzid); for (int32_t j = 0; j < 2; j++) { @@ -3824,7 +3824,7 @@ void CalendarTest::TestAddAcrossZoneTransition() { if (!AAZTDATA[i].expected.isEquivalentTo(cal, status)) { CalFields res(cal, status); TEST_CHECK_STATUS; - char buf[32]; + char buf[33]; const char *optDisp = AAZTDATA[i].skippedWTOpt == UCAL_WALLTIME_FIRST ? "FIRST" : AAZTDATA[i].skippedWTOpt == UCAL_WALLTIME_LAST ? "LAST" : "NEXT_VALID"; dataerrln(UnicodeString("Error: base:") + AAZTDATA[i].base.toString(buf, sizeof(buf)) + ", tz:" + AAZTDATA[i].zone diff --git a/icu4c/source/test/intltest/rbbitst.cpp b/icu4c/source/test/intltest/rbbitst.cpp index 0ad50993b65f..1fe1cadcfb45 100644 --- a/icu4c/source/test/intltest/rbbitst.cpp +++ b/icu4c/source/test/intltest/rbbitst.cpp @@ -4584,7 +4584,7 @@ void RBBITest::RunMonkey(BreakIterator *bi, RBBIMonkeyKind &mk, const char *name UErrorCode status = U_ZERO_ERROR; u_charName(c, U_EXTENDED_CHAR_NAME, cName, sizeof(cName), &status); - char buffer[200]; + char buffer[280]; auto ret = snprintf(buffer, sizeof(buffer), "%4s %3i : %1s %1s %10s %-*s %-40s %-40s", currentLineFlag.c_str(), diff --git a/icu4c/source/test/iotest/stream.cpp b/icu4c/source/test/iotest/stream.cpp index 1b6303f1ee3e..907914daf3a5 100644 --- a/icu4c/source/test/iotest/stream.cpp +++ b/icu4c/source/test/iotest/stream.cpp @@ -76,7 +76,7 @@ static void U_CALLCONV TestStream() return; } ucnv_close(defConv); - strncpy(defConvName, ucnv_getDefaultName(), UPRV_LENGTHOF(defConvName)); + strncpy(defConvName, ucnv_getDefaultName(), UPRV_LENGTHOF(defConvName)-1); ucnv_setDefaultName("UTF-8"); static const char * const TESTSTRING = "\x20\x74\x48\x69\x73\xCE\xBC\xE2\x80\x82\x20\x6D\x75\x20\x77\x6F\x72\x6C\x64"; diff --git a/icu4c/source/tools/ctestfw/ctest.c b/icu4c/source/tools/ctestfw/ctest.c index 3ae9694a8308..7634526ad4e5 100644 --- a/icu4c/source/tools/ctestfw/ctest.c +++ b/icu4c/source/tools/ctestfw/ctest.c @@ -181,7 +181,9 @@ static TestNode *createTestNode(const char* name, int32_t nameLen) newNode->sibling = NULL; newNode->child = NULL; - strncpy( newNode->name, name, nameLen ); + if (nameLen > 0) { + strncpy( newNode->name, name, nameLen ); + } newNode->name[nameLen] = 0; return newNode; diff --git a/icu4c/source/tools/icuexportdata/icuexportdata.cpp b/icu4c/source/tools/icuexportdata/icuexportdata.cpp index 987a6bc7f6f8..0a96c9e0e62a 100644 --- a/icu4c/source/tools/icuexportdata/icuexportdata.cpp +++ b/icu4c/source/tools/icuexportdata/icuexportdata.cpp @@ -331,13 +331,13 @@ void dumpGeneralCategoryMask(FILE* f) { fprintf(f, "mask_for = \"General_Category\"\n"); - uint32_t minValue = u_getIntPropertyMinValue(UCHAR_GENERAL_CATEGORY); + int32_t minValue = u_getIntPropertyMinValue(UCHAR_GENERAL_CATEGORY); U_ASSERT(minValue >= 0); - uint32_t maxValue = u_getIntPropertyMaxValue(UCHAR_GENERAL_CATEGORY); + int32_t maxValue = u_getIntPropertyMaxValue(UCHAR_GENERAL_CATEGORY); U_ASSERT(maxValue >= 0); fprintf(f, "values = [\n"); - for (uint32_t v = minValue; v <= maxValue; v++) { + for (int32_t v = minValue; v <= maxValue; v++) { dumpValueEntry(uproperty, U_MASK(v), true, f); // We want to dump these masks "in order", which means they diff --git a/icu4c/source/tools/makeconv/genmbcs.cpp b/icu4c/source/tools/makeconv/genmbcs.cpp index 774cdc6045d1..5b909b574df4 100644 --- a/icu4c/source/tools/makeconv/genmbcs.cpp +++ b/icu4c/source/tools/makeconv/genmbcs.cpp @@ -113,9 +113,9 @@ hexDigit(uint8_t digit) { } static inline char * -printBytes(char *buffer, const uint8_t *bytes, int32_t length) { +printBytes(char *buffer, size_t bufferLength, const uint8_t *bytes, int32_t length) { char *s=buffer; - while(length>0) { + while(length>0 && (static_cast(s-buffer) < bufferLength-3)) { *s++ = hexDigit(static_cast(*bytes >> 4)); *s++ = hexDigit(static_cast(*bytes & 0xf)); ++bytes; @@ -400,7 +400,7 @@ MBCSAddToUnicode(MBCSData *mbcsData, if(MBCS_ENTRY_IS_TRANSITION(entry)) { if(i==length) { fprintf(stderr, "error: byte sequence too short, ends in non-final state %hu: 0x%s (U+%x)\n", - static_cast(state), printBytes(buffer, bytes, length), static_cast(c)); + static_cast(state), printBytes(buffer, sizeof(buffer), bytes, length), static_cast(c)); return false; } state = static_cast(MBCS_ENTRY_TRANSITION_STATE(entry)); @@ -408,21 +408,21 @@ MBCSAddToUnicode(MBCSData *mbcsData, } else { if(i(length - i), state, printBytes(buffer, bytes, length), static_cast(c)); + static_cast(length - i), state, printBytes(buffer, sizeof(buffer), bytes, length), static_cast(c)); return false; } switch(MBCS_ENTRY_FINAL_ACTION(entry)) { case MBCS_STATE_ILLEGAL: fprintf(stderr, "error: byte sequence ends in illegal state at U+%04x<->0x%s\n", - static_cast(c), printBytes(buffer, bytes, length)); + static_cast(c), printBytes(buffer, sizeof(buffer), bytes, length)); return false; case MBCS_STATE_CHANGE_ONLY: fprintf(stderr, "error: byte sequence ends in state-change-only at U+%04x<->0x%s\n", - static_cast(c), printBytes(buffer, bytes, length)); + static_cast(c), printBytes(buffer, sizeof(buffer), bytes, length)); return false; case MBCS_STATE_UNASSIGNED: fprintf(stderr, "error: byte sequence ends in unassigned state at U+%04x<->0x%s\n", - static_cast(c), printBytes(buffer, bytes, length)); + static_cast(c), printBytes(buffer, sizeof(buffer), bytes, length)); return false; case MBCS_STATE_FALLBACK_DIRECT_16: case MBCS_STATE_VALID_DIRECT_16: @@ -437,11 +437,11 @@ MBCSAddToUnicode(MBCSData *mbcsData, } if(flag>=0) { fprintf(stderr, "error: duplicate codepage byte sequence at U+%04x<->0x%s see U+%04x\n", - static_cast(c), printBytes(buffer, bytes, length), static_cast(old)); + static_cast(c), printBytes(buffer, sizeof(buffer), bytes, length), static_cast(old)); return false; } else if(VERBOSE) { fprintf(stderr, "duplicate codepage byte sequence at U+%04x<->0x%s see U+%04x\n", - static_cast(c), printBytes(buffer, bytes, length), static_cast(old)); + static_cast(c), printBytes(buffer, sizeof(buffer), bytes, length), static_cast(old)); } /* * Continue after the above warning @@ -467,16 +467,16 @@ MBCSAddToUnicode(MBCSData *mbcsData, if((old=mbcsData->unicodeCodeUnits[offset])!=0xfffe || (old=removeFallback(mbcsData, offset))!=-1) { if(flag>=0) { fprintf(stderr, "error: duplicate codepage byte sequence at U+%04x<->0x%s see U+%04x\n", - static_cast(c), printBytes(buffer, bytes, length), static_cast(old)); + static_cast(c), printBytes(buffer, sizeof(buffer), bytes, length), static_cast(old)); return false; } else if(VERBOSE) { fprintf(stderr, "duplicate codepage byte sequence at U+%04x<->0x%s see U+%04x\n", - static_cast(c), printBytes(buffer, bytes, length), static_cast(old)); + static_cast(c), printBytes(buffer, sizeof(buffer), bytes, length), static_cast(old)); } } if(c>=0x10000) { fprintf(stderr, "error: code point does not fit into valid-16-bit state at U+%04x<->0x%s\n", - static_cast(c), printBytes(buffer, bytes, length)); + static_cast(c), printBytes(buffer, sizeof(buffer), bytes, length)); return false; } if(flag>0) { @@ -505,11 +505,11 @@ MBCSAddToUnicode(MBCSData *mbcsData, } if(flag>=0) { fprintf(stderr, "error: duplicate codepage byte sequence at U+%04x<->0x%s see U+%04x\n", - static_cast(c), printBytes(buffer, bytes, length), static_cast(real)); + static_cast(c), printBytes(buffer, sizeof(buffer), bytes, length), static_cast(real)); return false; } else if(VERBOSE) { fprintf(stderr, "duplicate codepage byte sequence at U+%04x<->0x%s see U+%04x\n", - static_cast(c), printBytes(buffer, bytes, length), static_cast(real)); + static_cast(c), printBytes(buffer, sizeof(buffer), bytes, length), static_cast(real)); } } if(flag>0) { @@ -543,7 +543,7 @@ MBCSAddToUnicode(MBCSData *mbcsData, default: /* reserved, must never occur */ fprintf(stderr, "internal error: byte sequence reached reserved action code, entry 0x%02x: 0x%s (U+%x)\n", - static_cast(entry), printBytes(buffer, bytes, length), static_cast(c)); + static_cast(entry), printBytes(buffer, sizeof(buffer), bytes, length), static_cast(c)); return false; } @@ -699,7 +699,7 @@ MBCSAddFromUnicode(MBCSData *mbcsData, (!IGNORE_SISO_CHECK && (*bytes==0xe || *bytes==0xf)) ) { fprintf(stderr, "error: illegal mapping to SI or SO for SI/SO codepage: U+%04x<->0x%s\n", - static_cast(c), printBytes(buffer, bytes, length)); + static_cast(c), printBytes(buffer, sizeof(buffer), bytes, length)); return false; } @@ -738,7 +738,7 @@ MBCSAddFromUnicode(MBCSData *mbcsData, if(newTop>MBCS_MAX_STAGE_2_TOP) { fprintf(stderr, "error: too many stage 2 entries at U+%04x<->0x%s\n", - static_cast(c), printBytes(buffer, bytes, length)); + static_cast(c), printBytes(buffer, sizeof(buffer), bytes, length)); return false; } @@ -786,7 +786,7 @@ MBCSAddFromUnicode(MBCSData *mbcsData, if (newTop > MBCS_STAGE_3_MBCS_SIZE * static_cast(maxCharLength)) { fprintf(stderr, "error: too many code points at U+%04x<->0x%s\n", - static_cast(c), printBytes(buffer, bytes, length)); + static_cast(c), printBytes(buffer, sizeof(buffer), bytes, length)); return false; } /* each block has 16*maxCharLength bytes */ @@ -881,11 +881,11 @@ MBCSAddFromUnicode(MBCSData *mbcsData, if((mbcsData->stage2[idx+(nextOffset>>MBCS_STAGE_2_SHIFT)]&(1UL<<(16+(c&0xf))))!=0 || old!=0) { if(flag>=0) { fprintf(stderr, "error: duplicate Unicode code point at U+%04x<->0x%s see 0x%02x\n", - static_cast(c), printBytes(buffer, bytes, length), static_cast(old)); + static_cast(c), printBytes(buffer, sizeof(buffer), bytes, length), static_cast(old)); return false; } else if(VERBOSE) { fprintf(stderr, "duplicate Unicode code point at U+%04x<->0x%s see 0x%02x\n", - static_cast(c), printBytes(buffer, bytes, length), static_cast(old)); + static_cast(c), printBytes(buffer, sizeof(buffer), bytes, length), static_cast(old)); } /* continue after the above warning if the precision of the mapping is unspecified */