[libcxx-commits] [libcxx] ac4cca3 - [libc++] Fix regression about parsing leading decimal points (#93989)
via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Jun 3 08:29:02 PDT 2024
Author: A. Jiang
Date: 2024-06-03T11:28:58-04:00
New Revision: ac4cca3cb1186aa1e3e6a94c70cc3d34a91a67c3
URL: https://github.com/llvm/llvm-project/commit/ac4cca3cb1186aa1e3e6a94c70cc3d34a91a67c3
DIFF: https://github.com/llvm/llvm-project/commit/ac4cca3cb1186aa1e3e6a94c70cc3d34a91a67c3.diff
LOG: [libc++] Fix regression about parsing leading decimal points (#93989)
PR #77948 mistakenly rejected floating-point representation with a
leading decimal point, e.g. ".5".
This PR fixes the regression mentioned in
https://github.com/llvm/llvm-project/pull/77948#issuecomment-2141740346.
Added:
Modified:
libcxx/include/locale
libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp
libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_float.pass.cpp
libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/include/locale b/libcxx/include/locale
index 041d7bcd27fc5..c25861ff66987 100644
--- a/libcxx/include/locale
+++ b/libcxx/include/locale
@@ -986,12 +986,12 @@ _InputIterator num_get<_CharT, _InputIterator>::__do_get_floating_point(
// the leading character excluding the sign must be a decimal digit
if (!__is_leading_parsed) {
if (__a_end - __a >= 1 && __a[0] != '-' && __a[0] != '+') {
- if ('0' <= __a[0] && __a[0] <= '9')
+ if (('0' <= __a[0] && __a[0] <= '9') || __a[0] == '.')
__is_leading_parsed = true;
else
break;
} else if (__a_end - __a >= 2 && (__a[0] == '-' || __a[0] == '+')) {
- if ('0' <= __a[1] && __a[1] <= '9')
+ if (('0' <= __a[1] && __a[1] <= '9') || __a[1] == '.')
__is_leading_parsed = true;
else
break;
diff --git a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp
index fbd1c7c5715ea..e093737986c1c 100644
--- a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp
+++ b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp
@@ -401,6 +401,67 @@ int main(int, char**)
assert(err == ios.goodbit);
assert(std::abs(v - 3.14159265358979e+10)/3.14159265358979e+10 < 1.e-8);
}
+ ios.imbue(std::locale());
+ {
+ v = -1;
+ const char str[] = ".5";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
+ assert(base(iter) == str + 2);
+ assert(err == ios.goodbit);
+ assert(v == 0.5);
+ }
+ {
+ v = -1;
+ const char str[] = "-.5";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
+ assert(base(iter) == str + 3);
+ assert(err == ios.goodbit);
+ assert(v == -0.5);
+ }
+ {
+ v = -1;
+ const char str[] = ".5E1";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
+ assert(base(iter) == str + 4);
+ assert(err == ios.goodbit);
+ assert(v == 5.0);
+ }
+ {
+ v = -1;
+ const char str[] = "-.5e+1";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
+ assert(base(iter) == str + 6);
+ assert(err == ios.goodbit);
+ assert(v == -5.0);
+ }
+ {
+ v = -1;
+ const char str[] = ".625E-1";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
+ assert(base(iter) == str + 7);
+ assert(err == ios.goodbit);
+ assert(v == 0.0625);
+ }
+ {
+ v = -1;
+ const char str[] = "-.3125e-1";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
+ assert(base(iter) == str + 9);
+ assert(err == ios.goodbit);
+ assert(v == -0.03125);
+ }
return 0;
}
diff --git a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_float.pass.cpp b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_float.pass.cpp
index b5ac7d876157c..bc6cec45d89a3 100644
--- a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_float.pass.cpp
+++ b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_float.pass.cpp
@@ -331,6 +331,66 @@ int main(int, char**)
assert(err == ios.goodbit);
assert(v == 2);
}
+ {
+ v = -1;
+ const char str[] = ".5";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
+ assert(base(iter) == str + 2);
+ assert(err == ios.goodbit);
+ assert(v == 0.5f);
+ }
+ {
+ v = -1;
+ const char str[] = "-.5";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
+ assert(base(iter) == str + 3);
+ assert(err == ios.goodbit);
+ assert(v == -0.5f);
+ }
+ {
+ v = -1;
+ const char str[] = ".5E1";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
+ assert(base(iter) == str + 4);
+ assert(err == ios.goodbit);
+ assert(v == 5.0f);
+ }
+ {
+ v = -1;
+ const char str[] = "-.5e+1";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
+ assert(base(iter) == str + 6);
+ assert(err == ios.goodbit);
+ assert(v == -5.0f);
+ }
+ {
+ v = -1;
+ const char str[] = ".625E-1";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
+ assert(base(iter) == str + 7);
+ assert(err == ios.goodbit);
+ assert(v == 0.0625f);
+ }
+ {
+ v = -1;
+ const char str[] = "-.3125e-1";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
+ assert(base(iter) == str + 9);
+ assert(err == ios.goodbit);
+ assert(v == -0.03125f);
+ }
return 0;
}
diff --git a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp
index 9617899f749c6..f455981e89780 100644
--- a/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp
+++ b/libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp
@@ -390,6 +390,66 @@ int main(int, char**)
assert(err == ios.goodbit);
assert(v == 2);
}
+ {
+ v = -1;
+ const char str[] = ".5";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
+ assert(base(iter) == str + 2);
+ assert(err == ios.goodbit);
+ assert(v == 0.5l);
+ }
+ {
+ v = -1;
+ const char str[] = "-.5";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
+ assert(base(iter) == str + 3);
+ assert(err == ios.goodbit);
+ assert(v == -0.5l);
+ }
+ {
+ v = -1;
+ const char str[] = ".5E1";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
+ assert(base(iter) == str + 4);
+ assert(err == ios.goodbit);
+ assert(v == 5.0l);
+ }
+ {
+ v = -1;
+ const char str[] = "-.5e+1";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
+ assert(base(iter) == str + 6);
+ assert(err == ios.goodbit);
+ assert(v == -5.0l);
+ }
+ {
+ v = -1;
+ const char str[] = ".625E-1";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
+ assert(base(iter) == str + 7);
+ assert(err == ios.goodbit);
+ assert(v == 0.0625l);
+ }
+ {
+ v = -1;
+ const char str[] = "-.3125e-1";
+ std::ios_base::iostate err = ios.goodbit;
+ cpp17_input_iterator<const char*> iter = f.get(
+ cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
+ assert(base(iter) == str + 9);
+ assert(err == ios.goodbit);
+ assert(v == -0.03125l);
+ }
return 0;
}
More information about the libcxx-commits
mailing list