Skip to content

Commit ef8143d

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 97c34eb commit ef8143d

File tree

4 files changed

+182
-2
lines changed

4 files changed

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

405465
return 0;
406466
}

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)