std::remove_if doesn't remove anything from the string, it just shuffles
the later characters down to replace spaces. That means given " 123456 "
as input, it will produce "1234566 " which is not the same value, and
will also cause the strtof128 result to be treated as an error because
the pend pointer will point to the trailing space not the null
terminator.

The return value of std::remove_if should not be ignored. Instead it
should be used to terminate the resulting string, so that a '\0' is
placed after the

Also, don't use isspace as a functor, for the same reasons as given at
https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.simple
(isspace is an overloaded name, and has undefined behaviour if given a
char with a negative value). Use the safe-ctype.h ISSPACE instead, via a
lambda expression.

gcc/cobol/ChangeLog:

        * parse.y: Fix use of std::remove_if and isspace.
---
 gcc/cobol/parse.y | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y
index c45dc333ec7..ae1dec4ecb7 100644
--- a/gcc/cobol/parse.y
+++ b/gcc/cobol/parse.y
@@ -10294,7 +10294,9 @@ intrinsic:      function_udf
                       auto input = $r1->field->data.initial;
                       auto local = xstrdup(input), pend = local;
                       std::replace(local, local + strlen(local), ',', '.');
-                      std::remove_if(local, local + strlen(local), isspace);
+                      pend = std::remove_if(local, local + strlen(local),
+                                            [](char c) { return ISSPACE(c); });
+                      *pend = '\0';
                       output = strtof128(local, &pend);
                       // bad if strtof128 could not convert input
                       if( *pend != '\0' ) {
-- 
2.48.1

Reply via email to