re PR libstdc++/65049 (Undefined behaviour with std::char_traits<char>)
PR libstdc++/65049 * include/bits/char_traits.h (char_traits<char>::compare, char_traits<char>::find, char_traits<char>::move, char_traits<char>::copy, char_traits<char>::assign): Check for zero length. (char_traits<wchar_t>::compare, char_traits<wchar_t>::find, char_traits<wchar_t>::move, char_traits<wchar_t>::copy, char_traits<wchar_t>::assign): Likewise. (char_traits<char16_t>::move, char_traits<char16_t>::copy): Likewise. (char_traits<char32_t>::move, char_traits<char32_t>::copy): Likewise. * include/ext/pod_char_traits.h (char_traits<character<>>::move, char_traits<character<>>::copy): Likewise. * testsuite/21_strings/char_traits/requirements/char/65049.cc: New. * testsuite/21_strings/char_traits/requirements/char16_t/65049.cc: New. * testsuite/21_strings/char_traits/requirements/char32_t/65049.cc: New. * testsuite/21_strings/char_traits/requirements/wchar_t/65049.cc: New. From-SVN: r227127
This commit is contained in:
parent
3af7efb7d9
commit
4a88769c96
|
@ -1,5 +1,25 @@
|
||||||
2015-08-24 Jonathan Wakely <jwakely@redhat.com>
|
2015-08-24 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
PR libstdc++/65049
|
||||||
|
* include/bits/char_traits.h (char_traits<char>::compare,
|
||||||
|
char_traits<char>::find, char_traits<char>::move,
|
||||||
|
char_traits<char>::copy, char_traits<char>::assign): Check for zero
|
||||||
|
length.
|
||||||
|
(char_traits<wchar_t>::compare, char_traits<wchar_t>::find,
|
||||||
|
char_traits<wchar_t>::move, char_traits<wchar_t>::copy,
|
||||||
|
char_traits<wchar_t>::assign): Likewise.
|
||||||
|
(char_traits<char16_t>::move, char_traits<char16_t>::copy): Likewise.
|
||||||
|
(char_traits<char32_t>::move, char_traits<char32_t>::copy): Likewise.
|
||||||
|
* include/ext/pod_char_traits.h (char_traits<character<>>::move,
|
||||||
|
char_traits<character<>>::copy): Likewise.
|
||||||
|
* testsuite/21_strings/char_traits/requirements/char/65049.cc: New.
|
||||||
|
* testsuite/21_strings/char_traits/requirements/char16_t/65049.cc:
|
||||||
|
New.
|
||||||
|
* testsuite/21_strings/char_traits/requirements/char32_t/65049.cc:
|
||||||
|
New.
|
||||||
|
* testsuite/21_strings/char_traits/requirements/wchar_t/65049.cc:
|
||||||
|
New.
|
||||||
|
|
||||||
PR libstdc++/67309
|
PR libstdc++/67309
|
||||||
* include/bits/random.tcc
|
* include/bits/random.tcc
|
||||||
(poisson_distribution::param_type::_M_initialize): Use max<double>.
|
(poisson_distribution::param_type::_M_initialize): Use max<double>.
|
||||||
|
|
|
@ -256,7 +256,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compare(const char_type* __s1, const char_type* __s2, size_t __n)
|
compare(const char_type* __s1, const char_type* __s2, size_t __n)
|
||||||
{ return __builtin_memcmp(__s1, __s2, __n); }
|
{
|
||||||
|
if (__n == 0)
|
||||||
|
return 0;
|
||||||
|
return __builtin_memcmp(__s1, __s2, __n);
|
||||||
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
length(const char_type* __s)
|
length(const char_type* __s)
|
||||||
|
@ -264,19 +268,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
static const char_type*
|
static const char_type*
|
||||||
find(const char_type* __s, size_t __n, const char_type& __a)
|
find(const char_type* __s, size_t __n, const char_type& __a)
|
||||||
{ return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); }
|
{
|
||||||
|
if (__n == 0)
|
||||||
|
return 0;
|
||||||
|
return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
|
||||||
|
}
|
||||||
|
|
||||||
static char_type*
|
static char_type*
|
||||||
move(char_type* __s1, const char_type* __s2, size_t __n)
|
move(char_type* __s1, const char_type* __s2, size_t __n)
|
||||||
{ return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); }
|
{
|
||||||
|
if (__n == 0)
|
||||||
|
return __s1;
|
||||||
|
return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
|
||||||
|
}
|
||||||
|
|
||||||
static char_type*
|
static char_type*
|
||||||
copy(char_type* __s1, const char_type* __s2, size_t __n)
|
copy(char_type* __s1, const char_type* __s2, size_t __n)
|
||||||
{ return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); }
|
{
|
||||||
|
if (__n == 0)
|
||||||
|
return __s1;
|
||||||
|
return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
|
||||||
|
}
|
||||||
|
|
||||||
static char_type*
|
static char_type*
|
||||||
assign(char_type* __s, size_t __n, char_type __a)
|
assign(char_type* __s, size_t __n, char_type __a)
|
||||||
{ return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); }
|
{
|
||||||
|
if (__n == 0)
|
||||||
|
return __s;
|
||||||
|
return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
|
||||||
|
}
|
||||||
|
|
||||||
static _GLIBCXX_CONSTEXPR char_type
|
static _GLIBCXX_CONSTEXPR char_type
|
||||||
to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
|
to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
|
||||||
|
@ -327,7 +347,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compare(const char_type* __s1, const char_type* __s2, size_t __n)
|
compare(const char_type* __s1, const char_type* __s2, size_t __n)
|
||||||
{ return wmemcmp(__s1, __s2, __n); }
|
{
|
||||||
|
if (__n == 0)
|
||||||
|
return 0;
|
||||||
|
return wmemcmp(__s1, __s2, __n);
|
||||||
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
length(const char_type* __s)
|
length(const char_type* __s)
|
||||||
|
@ -335,19 +359,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
static const char_type*
|
static const char_type*
|
||||||
find(const char_type* __s, size_t __n, const char_type& __a)
|
find(const char_type* __s, size_t __n, const char_type& __a)
|
||||||
{ return wmemchr(__s, __a, __n); }
|
{
|
||||||
|
if (__n == 0)
|
||||||
|
return 0;
|
||||||
|
return wmemchr(__s, __a, __n);
|
||||||
|
}
|
||||||
|
|
||||||
static char_type*
|
static char_type*
|
||||||
move(char_type* __s1, const char_type* __s2, size_t __n)
|
move(char_type* __s1, const char_type* __s2, size_t __n)
|
||||||
{ return wmemmove(__s1, __s2, __n); }
|
{
|
||||||
|
if (__n == 0)
|
||||||
|
return __s1;
|
||||||
|
return wmemmove(__s1, __s2, __n);
|
||||||
|
}
|
||||||
|
|
||||||
static char_type*
|
static char_type*
|
||||||
copy(char_type* __s1, const char_type* __s2, size_t __n)
|
copy(char_type* __s1, const char_type* __s2, size_t __n)
|
||||||
{ return wmemcpy(__s1, __s2, __n); }
|
{
|
||||||
|
if (__n == 0)
|
||||||
|
return __s1;
|
||||||
|
return wmemcpy(__s1, __s2, __n);
|
||||||
|
}
|
||||||
|
|
||||||
static char_type*
|
static char_type*
|
||||||
assign(char_type* __s, size_t __n, char_type __a)
|
assign(char_type* __s, size_t __n, char_type __a)
|
||||||
{ return wmemset(__s, __a, __n); }
|
{
|
||||||
|
if (__n == 0)
|
||||||
|
return __s;
|
||||||
|
return wmemset(__s, __a, __n);
|
||||||
|
}
|
||||||
|
|
||||||
static _GLIBCXX_CONSTEXPR char_type
|
static _GLIBCXX_CONSTEXPR char_type
|
||||||
to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
|
to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
|
||||||
|
@ -436,6 +476,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
static char_type*
|
static char_type*
|
||||||
move(char_type* __s1, const char_type* __s2, size_t __n)
|
move(char_type* __s1, const char_type* __s2, size_t __n)
|
||||||
{
|
{
|
||||||
|
if (__n == 0)
|
||||||
|
return __s1;
|
||||||
return (static_cast<char_type*>
|
return (static_cast<char_type*>
|
||||||
(__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
|
(__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
|
||||||
}
|
}
|
||||||
|
@ -443,6 +485,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
static char_type*
|
static char_type*
|
||||||
copy(char_type* __s1, const char_type* __s2, size_t __n)
|
copy(char_type* __s1, const char_type* __s2, size_t __n)
|
||||||
{
|
{
|
||||||
|
if (__n == 0)
|
||||||
|
return __s1;
|
||||||
return (static_cast<char_type*>
|
return (static_cast<char_type*>
|
||||||
(__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
|
(__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
|
||||||
}
|
}
|
||||||
|
@ -529,6 +573,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
static char_type*
|
static char_type*
|
||||||
move(char_type* __s1, const char_type* __s2, size_t __n)
|
move(char_type* __s1, const char_type* __s2, size_t __n)
|
||||||
{
|
{
|
||||||
|
if (__n == 0)
|
||||||
|
return __s1;
|
||||||
return (static_cast<char_type*>
|
return (static_cast<char_type*>
|
||||||
(__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
|
(__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
|
||||||
}
|
}
|
||||||
|
@ -536,6 +582,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
static char_type*
|
static char_type*
|
||||||
copy(char_type* __s1, const char_type* __s2, size_t __n)
|
copy(char_type* __s1, const char_type* __s2, size_t __n)
|
||||||
{
|
{
|
||||||
|
if (__n == 0)
|
||||||
|
return __s1;
|
||||||
return (static_cast<char_type*>
|
return (static_cast<char_type*>
|
||||||
(__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
|
(__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,6 +144,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
static char_type*
|
static char_type*
|
||||||
move(char_type* __s1, const char_type* __s2, size_t __n)
|
move(char_type* __s1, const char_type* __s2, size_t __n)
|
||||||
{
|
{
|
||||||
|
if (__n == 0)
|
||||||
|
return __s1;
|
||||||
return static_cast<char_type*>
|
return static_cast<char_type*>
|
||||||
(__builtin_memmove(__s1, __s2, __n * sizeof(char_type)));
|
(__builtin_memmove(__s1, __s2, __n * sizeof(char_type)));
|
||||||
}
|
}
|
||||||
|
@ -151,6 +153,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
static char_type*
|
static char_type*
|
||||||
copy(char_type* __s1, const char_type* __s2, size_t __n)
|
copy(char_type* __s1, const char_type* __s2, size_t __n)
|
||||||
{
|
{
|
||||||
|
if (__n == 0)
|
||||||
|
return __s1;
|
||||||
std::copy(__s2, __s2 + __n, __s1);
|
std::copy(__s2, __s2 + __n, __s1);
|
||||||
return __s1;
|
return __s1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Copyright (C) 2015 Free Software Foundation, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of the GNU ISO C++ Library. This library is free
|
||||||
|
// software; you can redistribute it and/or modify it under the
|
||||||
|
// terms of the GNU General Public License as published by the
|
||||||
|
// Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this library; see the file COPYING3. If not see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// { dg-options "-std=gnu++11" }
|
||||||
|
|
||||||
|
// libstdc++/65049
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
|
||||||
|
using C = char;
|
||||||
|
|
||||||
|
void
|
||||||
|
test01()
|
||||||
|
{
|
||||||
|
const C* p = 0;
|
||||||
|
C* q = 0;
|
||||||
|
auto c = std::char_traits<C>::compare(p, q, 0);
|
||||||
|
VERIFY( c == 0 );
|
||||||
|
auto r = std::char_traits<C>::find(p, 0, '0');
|
||||||
|
VERIFY( r == nullptr );
|
||||||
|
r = std::char_traits<C>::move(q, p, 0);
|
||||||
|
VERIFY( r == q );
|
||||||
|
r = std::char_traits<C>::copy(q, p, 0);
|
||||||
|
VERIFY( r == q );
|
||||||
|
r = std::char_traits<C>::assign(q, 0, '0');
|
||||||
|
VERIFY( r == q );
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
test01();
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Copyright (C) 2015 Free Software Foundation, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of the GNU ISO C++ Library. This library is free
|
||||||
|
// software; you can redistribute it and/or modify it under the
|
||||||
|
// terms of the GNU General Public License as published by the
|
||||||
|
// Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this library; see the file COPYING3. If not see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// { dg-options "-std=gnu++11" }
|
||||||
|
|
||||||
|
// libstdc++/65049
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
|
||||||
|
using C = char16_t;
|
||||||
|
|
||||||
|
void
|
||||||
|
test01()
|
||||||
|
{
|
||||||
|
const C* p = 0;
|
||||||
|
C* q = 0;
|
||||||
|
auto c = std::char_traits<C>::compare(p, q, 0);
|
||||||
|
VERIFY( c == 0 );
|
||||||
|
auto r = std::char_traits<C>::find(p, 0, '0');
|
||||||
|
VERIFY( r == nullptr );
|
||||||
|
r = std::char_traits<C>::move(q, p, 0);
|
||||||
|
VERIFY( r == q );
|
||||||
|
r = std::char_traits<C>::copy(q, p, 0);
|
||||||
|
VERIFY( r == q );
|
||||||
|
r = std::char_traits<C>::assign(q, 0, '0');
|
||||||
|
VERIFY( r == q );
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
test01();
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Copyright (C) 2015 Free Software Foundation, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of the GNU ISO C++ Library. This library is free
|
||||||
|
// software; you can redistribute it and/or modify it under the
|
||||||
|
// terms of the GNU General Public License as published by the
|
||||||
|
// Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this library; see the file COPYING3. If not see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// { dg-options "-std=gnu++11" }
|
||||||
|
|
||||||
|
// libstdc++/65049
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
|
||||||
|
using C = char32_t;
|
||||||
|
|
||||||
|
void
|
||||||
|
test01()
|
||||||
|
{
|
||||||
|
const C* p = 0;
|
||||||
|
C* q = 0;
|
||||||
|
auto c = std::char_traits<C>::compare(p, q, 0);
|
||||||
|
VERIFY( c == 0 );
|
||||||
|
auto r = std::char_traits<C>::find(p, 0, '0');
|
||||||
|
VERIFY( r == nullptr );
|
||||||
|
r = std::char_traits<C>::move(q, p, 0);
|
||||||
|
VERIFY( r == q );
|
||||||
|
r = std::char_traits<C>::copy(q, p, 0);
|
||||||
|
VERIFY( r == q );
|
||||||
|
r = std::char_traits<C>::assign(q, 0, '0');
|
||||||
|
VERIFY( r == q );
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
test01();
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Copyright (C) 2015 Free Software Foundation, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of the GNU ISO C++ Library. This library is free
|
||||||
|
// software; you can redistribute it and/or modify it under the
|
||||||
|
// terms of the GNU General Public License as published by the
|
||||||
|
// Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this library; see the file COPYING3. If not see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// { dg-options "-std=gnu++11" }
|
||||||
|
|
||||||
|
// libstdc++/65049
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
|
||||||
|
using C = wchar_t;
|
||||||
|
|
||||||
|
void
|
||||||
|
test01()
|
||||||
|
{
|
||||||
|
const C* p = 0;
|
||||||
|
C* q = 0;
|
||||||
|
auto c = std::char_traits<C>::compare(p, q, 0);
|
||||||
|
VERIFY( c == 0 );
|
||||||
|
auto r = std::char_traits<C>::find(p, 0, '0');
|
||||||
|
VERIFY( r == nullptr );
|
||||||
|
r = std::char_traits<C>::move(q, p, 0);
|
||||||
|
VERIFY( r == q );
|
||||||
|
r = std::char_traits<C>::copy(q, p, 0);
|
||||||
|
VERIFY( r == q );
|
||||||
|
r = std::char_traits<C>::assign(q, 0, '0');
|
||||||
|
VERIFY( r == q );
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
test01();
|
||||||
|
}
|
Loading…
Reference in New Issue