Skip to content

Commit 1949f21

Browse files
[libc++] Fix regression about parsing leading decimal points
PR llvm#77948 mistakenly rejected floating-point representation with a leading decimal point, e.g. ".5". This PR fixes the regression.
1 parent 68a6481 commit 1949f21

File tree

4 files changed

+183
-2
lines changed

4 files changed

+183
-2
lines changed

libcxx/include/locale

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -986,12 +986,12 @@ _InputIterator num_get<_CharT, _InputIterator>::__do_get_floating_point(
986986
// the leading character excluding the sign must be a decimal digit
987987
if (!__is_leading_parsed) {
988988
if (__a_end - __a >= 1 && __a[0] != '-' && __a[0] != '+') {
989-
if ('0' <= __a[0] && __a[0] <= '9')
989+
if (('0' <= __a[0] && __a[0] <= '9') || __a[0] == '.')
990990
__is_leading_parsed = true;
991991
else
992992
break;
993993
} else if (__a_end - __a >= 2 && (__a[0] == '-' || __a[0] == '+')) {
994-
if ('0' <= __a[1] && __a[1] <= '9')
994+
if (('0' <= __a[1] && __a[1] <= '9') || __a[1] == '.')
995995
__is_leading_parsed = true;
996996
else
997997
break;

libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,67 @@ int main(int, char**)
401401
assert(err == ios.goodbit);
402402
assert(std::abs(v - 3.14159265358979e+10)/3.14159265358979e+10 < 1.e-8);
403403
}
404+
ios.imbue(std::locale());
405+
{
406+
v = -1;
407+
const char str[] = ".5";
408+
std::ios_base::iostate err = ios.goodbit;
409+
cpp17_input_iterator<const char*> iter = f.get(
410+
cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
411+
assert(base(iter) == str + 2);
412+
assert(err == ios.goodbit);
413+
assert(v == 0.5);
414+
}
415+
{
416+
v = -1;
417+
const char str[] = "-.5";
418+
std::ios_base::iostate err = ios.goodbit;
419+
cpp17_input_iterator<const char*> iter = f.get(
420+
cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
421+
assert(base(iter) == str + 3);
422+
assert(err == ios.goodbit);
423+
assert(v == -0.5);
424+
}
425+
{
426+
v = -1;
427+
const char str[] = ".5E1";
428+
std::ios_base::iostate err = ios.goodbit;
429+
cpp17_input_iterator<const char*> iter = f.get(
430+
cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
431+
assert(base(iter) == str + 4);
432+
assert(err == ios.goodbit);
433+
assert(v == 5.0);
434+
}
435+
{
436+
v = -1;
437+
const char str[] = "-.5e+1";
438+
std::ios_base::iostate err = ios.goodbit;
439+
cpp17_input_iterator<const char*> iter = f.get(
440+
cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
441+
assert(base(iter) == str + 6);
442+
assert(err == ios.goodbit);
443+
assert(v == -5.0);
444+
}
445+
{
446+
v = -1;
447+
const char str[] = ".625E-1";
448+
std::ios_base::iostate err = ios.goodbit;
449+
cpp17_input_iterator<const char*> iter = f.get(
450+
cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
451+
assert(base(iter) == str + 7);
452+
assert(err == ios.goodbit);
453+
assert(v == 0.0625);
454+
}
455+
{
456+
v = -1;
457+
const char str[] = "-.3125e-1";
458+
std::ios_base::iostate err = ios.goodbit;
459+
cpp17_input_iterator<const char*> iter = f.get(
460+
cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
461+
assert(base(iter) == str + 9);
462+
assert(err == ios.goodbit);
463+
assert(v == -0.03125);
464+
}
404465

405466
return 0;
406467
}

libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_float.pass.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,66 @@ int main(int, char**)
331331
assert(err == ios.goodbit);
332332
assert(v == 2);
333333
}
334+
{
335+
v = -1;
336+
const char str[] = ".5";
337+
std::ios_base::iostate err = ios.goodbit;
338+
cpp17_input_iterator<const char*> iter = f.get(
339+
cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
340+
assert(base(iter) == str + 2);
341+
assert(err == ios.goodbit);
342+
assert(v == 0.5f);
343+
}
344+
{
345+
v = -1;
346+
const char str[] = "-.5";
347+
std::ios_base::iostate err = ios.goodbit;
348+
cpp17_input_iterator<const char*> iter = f.get(
349+
cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
350+
assert(base(iter) == str + 3);
351+
assert(err == ios.goodbit);
352+
assert(v == -0.5f);
353+
}
354+
{
355+
v = -1;
356+
const char str[] = ".5E1";
357+
std::ios_base::iostate err = ios.goodbit;
358+
cpp17_input_iterator<const char*> iter = f.get(
359+
cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
360+
assert(base(iter) == str + 4);
361+
assert(err == ios.goodbit);
362+
assert(v == 5.0f);
363+
}
364+
{
365+
v = -1;
366+
const char str[] = "-.5e+1";
367+
std::ios_base::iostate err = ios.goodbit;
368+
cpp17_input_iterator<const char*> iter = f.get(
369+
cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
370+
assert(base(iter) == str + 6);
371+
assert(err == ios.goodbit);
372+
assert(v == -5.0f);
373+
}
374+
{
375+
v = -1;
376+
const char str[] = ".625E-1";
377+
std::ios_base::iostate err = ios.goodbit;
378+
cpp17_input_iterator<const char*> iter = f.get(
379+
cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
380+
assert(base(iter) == str + 7);
381+
assert(err == ios.goodbit);
382+
assert(v == 0.0625f);
383+
}
384+
{
385+
v = -1;
386+
const char str[] = "-.3125e-1";
387+
std::ios_base::iostate err = ios.goodbit;
388+
cpp17_input_iterator<const char*> iter = f.get(
389+
cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
390+
assert(base(iter) == str + 9);
391+
assert(err == ios.goodbit);
392+
assert(v == -0.03125f);
393+
}
334394

335395
return 0;
336396
}

libcxx/test/std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,66 @@ int main(int, char**)
390390
assert(err == ios.goodbit);
391391
assert(v == 2);
392392
}
393+
{
394+
v = -1;
395+
const char str[] = ".5";
396+
std::ios_base::iostate err = ios.goodbit;
397+
cpp17_input_iterator<const char*> iter = f.get(
398+
cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
399+
assert(base(iter) == str + 2);
400+
assert(err == ios.goodbit);
401+
assert(v == 0.5l);
402+
}
403+
{
404+
v = -1;
405+
const char str[] = "-.5";
406+
std::ios_base::iostate err = ios.goodbit;
407+
cpp17_input_iterator<const char*> iter = f.get(
408+
cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
409+
assert(base(iter) == str + 3);
410+
assert(err == ios.goodbit);
411+
assert(v == -0.5l);
412+
}
413+
{
414+
v = -1;
415+
const char str[] = ".5E1";
416+
std::ios_base::iostate err = ios.goodbit;
417+
cpp17_input_iterator<const char*> iter = f.get(
418+
cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
419+
assert(base(iter) == str + 4);
420+
assert(err == ios.goodbit);
421+
assert(v == 5.0l);
422+
}
423+
{
424+
v = -1;
425+
const char str[] = "-.5e+1";
426+
std::ios_base::iostate err = ios.goodbit;
427+
cpp17_input_iterator<const char*> iter = f.get(
428+
cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
429+
assert(base(iter) == str + 6);
430+
assert(err == ios.goodbit);
431+
assert(v == -5.0l);
432+
}
433+
{
434+
v = -1;
435+
const char str[] = ".625E-1";
436+
std::ios_base::iostate err = ios.goodbit;
437+
cpp17_input_iterator<const char*> iter = f.get(
438+
cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
439+
assert(base(iter) == str + 7);
440+
assert(err == ios.goodbit);
441+
assert(v == 0.0625l);
442+
}
443+
{
444+
v = -1;
445+
const char str[] = "-.3125e-1";
446+
std::ios_base::iostate err = ios.goodbit;
447+
cpp17_input_iterator<const char*> iter = f.get(
448+
cpp17_input_iterator<const char*>(str), cpp17_input_iterator<const char*>(str + sizeof(str)), ios, err, v);
449+
assert(base(iter) == str + 9);
450+
assert(err == ios.goodbit);
451+
assert(v == -0.03125l);
452+
}
393453

394454
return 0;
395455
}

0 commit comments

Comments
 (0)