Comment in fnmatch.c explains that:
/* We use strcoll(3) for range comparisons in bracket expressions,
even though it can have unwanted side effects in locales
other than POSIX or US. For instance, in the de locale, [A-Z] matches
all characters. */
Previous bash versions up to bash-2.04 have different comment:
/* We don't use strcoll(3) for range comparisons in bracket expressions,
even if we have it, since it can have unwanted side effects in locales
other than POSIX or US. For instance, in the de locale, [A-Z] matches
all characters. So, for ranges we use ASCII collation, and for
collating symbol equivalence we use strcoll(). The casts to int are
to handle tests that use unsigned chars. */
Which seems to be much reasonable.