mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-19 23:22:16 +03:00
WString: c_str() returns null pointer after move (#7611)
* (test) WString: c_str() returns null pointer target = std::move(source) does not reset buffer pointer back to the sso * wstring: correctly do move invalidation & copy based on the #7553 without isSSO -> isHeap rename and inline optimizations additionally, remove useless pre-c++11 preprocessor checks Co-authored-by: Takayuki 'January June' Suwa <jjsuwa@sys3175.com>
This commit is contained in:
parent
a3281fe2f3
commit
cc042b99d1
@ -45,7 +45,6 @@ String::String(const __FlashStringHelper *pstr) {
|
|||||||
*this = pstr; // see operator =
|
*this = pstr; // see operator =
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
|
||||||
String::String(String &&rval) noexcept {
|
String::String(String &&rval) noexcept {
|
||||||
init();
|
init();
|
||||||
move(rval);
|
move(rval);
|
||||||
@ -55,7 +54,6 @@ String::String(StringSumHelper &&rval) noexcept {
|
|||||||
init();
|
init();
|
||||||
move(rval);
|
move(rval);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
String::String(char c) {
|
String::String(char c) {
|
||||||
init();
|
init();
|
||||||
@ -223,36 +221,11 @@ String & String::copy(const __FlashStringHelper *pstr, unsigned int length) {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
|
||||||
void String::move(String &rhs) noexcept {
|
void String::move(String &rhs) noexcept {
|
||||||
if (buffer()) {
|
invalidate();
|
||||||
if (capacity() >= rhs.len()) {
|
sso = rhs.sso;
|
||||||
memmove_P(wbuffer(), rhs.buffer(), rhs.length() + 1);
|
rhs.init();
|
||||||
setLen(rhs.len());
|
|
||||||
rhs.invalidate();
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if (!isSSO()) {
|
|
||||||
free(wbuffer());
|
|
||||||
setBuffer(nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rhs.isSSO()) {
|
|
||||||
setSSO(true);
|
|
||||||
memmove_P(sso.buff, rhs.sso.buff, sizeof(sso.buff));
|
|
||||||
} else {
|
|
||||||
setSSO(false);
|
|
||||||
setBuffer(rhs.wbuffer());
|
|
||||||
}
|
|
||||||
setCapacity(rhs.capacity());
|
|
||||||
setLen(rhs.len());
|
|
||||||
rhs.setSSO(false);
|
|
||||||
rhs.setCapacity(0);
|
|
||||||
rhs.setLen(0);
|
|
||||||
rhs.setBuffer(nullptr);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
String & String::operator =(const String &rhs) {
|
String & String::operator =(const String &rhs) {
|
||||||
if (this == &rhs)
|
if (this == &rhs)
|
||||||
@ -266,7 +239,6 @@ String & String::operator =(const String &rhs) {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
|
||||||
String & String::operator =(String &&rval) noexcept {
|
String & String::operator =(String &&rval) noexcept {
|
||||||
if (this != &rval)
|
if (this != &rval)
|
||||||
move(rval);
|
move(rval);
|
||||||
@ -278,7 +250,6 @@ String & String::operator =(StringSumHelper &&rval) noexcept {
|
|||||||
move(rval);
|
move(rval);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
String & String::operator =(const char *cstr) {
|
String & String::operator =(const char *cstr) {
|
||||||
if (cstr)
|
if (cstr)
|
||||||
|
@ -53,13 +53,14 @@ class String {
|
|||||||
// if the initial value is null or invalid, or if memory allocation
|
// if the initial value is null or invalid, or if memory allocation
|
||||||
// fails, the string will be marked as invalid (i.e. "if (s)" will
|
// fails, the string will be marked as invalid (i.e. "if (s)" will
|
||||||
// be false).
|
// be false).
|
||||||
String(const char *cstr = nullptr);
|
String() {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
String(const char *cstr);
|
||||||
String(const String &str);
|
String(const String &str);
|
||||||
String(const __FlashStringHelper *str);
|
String(const __FlashStringHelper *str);
|
||||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
|
||||||
String(String &&rval) noexcept;
|
String(String &&rval) noexcept;
|
||||||
String(StringSumHelper &&rval) noexcept;
|
String(StringSumHelper &&rval) noexcept;
|
||||||
#endif
|
|
||||||
explicit String(char c);
|
explicit String(char c);
|
||||||
explicit String(unsigned char, unsigned char base = 10);
|
explicit String(unsigned char, unsigned char base = 10);
|
||||||
explicit String(int, unsigned char base = 10);
|
explicit String(int, unsigned char base = 10);
|
||||||
@ -95,10 +96,8 @@ class String {
|
|||||||
String & operator =(const String &rhs);
|
String & operator =(const String &rhs);
|
||||||
String & operator =(const char *cstr);
|
String & operator =(const char *cstr);
|
||||||
String & operator = (const __FlashStringHelper *str);
|
String & operator = (const __FlashStringHelper *str);
|
||||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
|
||||||
String & operator =(String &&rval) noexcept;
|
String & operator =(String &&rval) noexcept;
|
||||||
String & operator =(StringSumHelper &&rval) noexcept;
|
String & operator =(StringSumHelper &&rval) noexcept;
|
||||||
#endif
|
|
||||||
|
|
||||||
// concatenate (works w/ built-in types)
|
// concatenate (works w/ built-in types)
|
||||||
|
|
||||||
@ -316,9 +315,7 @@ class String {
|
|||||||
// copy and move
|
// copy and move
|
||||||
String & copy(const char *cstr, unsigned int length);
|
String & copy(const char *cstr, unsigned int length);
|
||||||
String & copy(const __FlashStringHelper *pstr, unsigned int length);
|
String & copy(const __FlashStringHelper *pstr, unsigned int length);
|
||||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
|
||||||
void move(String &rhs) noexcept;
|
void move(String &rhs) noexcept;
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class StringSumHelper: public String {
|
class StringSumHelper: public String {
|
||||||
|
@ -19,6 +19,19 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <StreamString.h>
|
#include <StreamString.h>
|
||||||
|
|
||||||
|
TEST_CASE("String::move", "[core][String]")
|
||||||
|
{
|
||||||
|
const char buffer[] = "this string goes over the sso limit";
|
||||||
|
|
||||||
|
String target;
|
||||||
|
String source(buffer);
|
||||||
|
|
||||||
|
target = std::move(source);
|
||||||
|
REQUIRE(source.c_str() != nullptr);
|
||||||
|
REQUIRE(!source.length());
|
||||||
|
REQUIRE(target == buffer);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("String::trim", "[core][String]")
|
TEST_CASE("String::trim", "[core][String]")
|
||||||
{
|
{
|
||||||
String str;
|
String str;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user