Commit 9a88d3ca authored by Stefan Behnel's avatar Stefan Behnel

Repair the coercion of C string literals to C++ strings for function...

Repair the coercion of C string literals to C++ strings for function arguments: must create a copy for non-const arguments and can use C++ coercion for const literals.
Closes #2132.
parent d4e15255
......@@ -130,6 +130,10 @@ Bugs fixed
* Iterator declarations in C++ ``deque`` and ``vector`` were corrected.
Patch by Alex Huszagh. (Github issue #1870)
* The const modifiers in the C++ ``string`` declarations were corrected, together
with the coercion behaviour of string literals into C++ strings.
(Github issue #2132)
* Some declaration types in ``libc.limits`` were corrected.
Patch by Jeroen Demeyer. (Github issue #2016)
......
......@@ -1451,8 +1451,10 @@ class BytesNode(ConstNode):
else PyrexTypes.c_char_ptr_type)
return CastNode(node, dst_type)
elif dst_type.assignable_from(PyrexTypes.c_char_ptr_type):
node.type = dst_type
return node
# Exclude the case of passing a C string literal into a non-const C++ string.
if not dst_type.is_cpp_class or dst_type.is_const:
node.type = dst_type
return node
# We still need to perform normal coerce_to processing on the
# result, because we might be coercing to an extension type,
......@@ -5542,8 +5544,6 @@ class SimpleCallNode(CallNode):
for i in range(min(max_nargs, actual_nargs)):
formal_arg = func_type.args[i]
formal_type = formal_arg.type
if formal_type.is_const:
formal_type = formal_type.const_base_type
arg = args[i].coerce_to(formal_type, env)
if formal_arg.not_none:
# C methods must do the None checks at *call* time
......
......@@ -9,9 +9,9 @@ cdef extern from "<string>" namespace "std" nogil:
cdef cppclass string:
string() except +
string(char *) except +
string(char *, size_t) except +
string(string&) except +
string(const char *) except +
string(const char *, size_t) except +
string(const string&) except +
# as a string formed by a repetition of character c, n times.
string(size_t, char) except +
......@@ -63,65 +63,65 @@ cdef extern from "<string>" namespace "std" nogil:
char& at(size_t)
char& operator[](size_t)
int compare(string&)
int compare(const string&)
string& append(string&)
string& append(string&, size_t, size_t)
string& append(char *)
string& append(char *, size_t)
string& append(const string&)
string& append(const string&, size_t, size_t)
string& append(const char *)
string& append(const char *, size_t)
string& append(size_t, char)
void push_back(char c)
string& assign (string&)
string& assign (string&, size_t, size_t)
string& assign (char *, size_t)
string& assign (char *)
string& assign (const string&)
string& assign (const string&, size_t, size_t)
string& assign (const char *, size_t)
string& assign (const char *)
string& assign (size_t n, char c)
string& insert(size_t, string&)
string& insert(size_t, string&, size_t, size_t)
string& insert(size_t, char* s, size_t)
string& insert(size_t, const string&)
string& insert(size_t, const string&, size_t, size_t)
string& insert(size_t, const char* s, size_t)
string& insert(size_t, char* s)
string& insert(size_t, const char* s)
string& insert(size_t, size_t, char c)
size_t copy(char *, size_t, size_t)
size_t find(string&)
size_t find(string&, size_t)
size_t find(char*, size_t pos, size_t)
size_t find(char*, size_t pos)
size_t find(const string&)
size_t find(const string&, size_t)
size_t find(const char*, size_t pos, size_t)
size_t find(const char*, size_t pos)
size_t find(char, size_t pos)
size_t rfind(string&, size_t)
size_t rfind(char* s, size_t, size_t)
size_t rfind(char*, size_t pos)
size_t rfind(const string&, size_t)
size_t rfind(const char* s, size_t, size_t)
size_t rfind(const char*, size_t pos)
size_t rfind(char c, size_t)
size_t rfind(char c)
size_t find_first_of(string&, size_t)
size_t find_first_of(char* s, size_t, size_t)
size_t find_first_of(char*, size_t pos)
size_t find_first_of(const string&, size_t)
size_t find_first_of(const char* s, size_t, size_t)
size_t find_first_of(const char*, size_t pos)
size_t find_first_of(char c, size_t)
size_t find_first_of(char c)
size_t find_first_not_of(string&, size_t)
size_t find_first_not_of(char* s, size_t, size_t)
size_t find_first_not_of(char*, size_t pos)
size_t find_first_not_of(const string&, size_t)
size_t find_first_not_of(const char* s, size_t, size_t)
size_t find_first_not_of(const char*, size_t pos)
size_t find_first_not_of(char c, size_t)
size_t find_first_not_of(char c)
size_t find_last_of(string&, size_t)
size_t find_last_of(char* s, size_t, size_t)
size_t find_last_of(char*, size_t pos)
size_t find_last_of(const string&, size_t)
size_t find_last_of(const char* s, size_t, size_t)
size_t find_last_of(const char*, size_t pos)
size_t find_last_of(char c, size_t)
size_t find_last_of(char c)
size_t find_last_not_of(string&, size_t)
size_t find_last_not_of(char* s, size_t, size_t)
size_t find_last_not_of(char*, size_t pos)
size_t find_last_not_of(const string&, size_t)
size_t find_last_not_of(const char* s, size_t, size_t)
size_t find_last_not_of(const char*, size_t pos)
string substr(size_t, size_t)
string substr()
......@@ -130,27 +130,27 @@ cdef extern from "<string>" namespace "std" nogil:
size_t find_last_not_of(char c, size_t)
size_t find_last_not_of(char c)
#string& operator= (string&)
#string& operator= (char*)
#string& operator= (const string&)
#string& operator= (const char*)
#string& operator= (char)
string operator+ (string& rhs)
string operator+ (char* rhs)
string operator+ (const string& rhs)
string operator+ (const char* rhs)
bint operator==(string&)
bint operator==(char*)
bint operator==(const string&)
bint operator==(const char*)
bint operator!= (string& rhs )
bint operator!= (char* )
bint operator!= (const string& rhs )
bint operator!= (const char* )
bint operator< (string&)
bint operator< (char*)
bint operator< (const string&)
bint operator< (const char*)
bint operator> (string&)
bint operator> (char*)
bint operator> (const string&)
bint operator> (const char*)
bint operator<= (string&)
bint operator<= (char*)
bint operator<= (const string&)
bint operator<= (const char*)
bint operator>= (string&)
bint operator>= (char*)
bint operator>= (const string&)
bint operator>= (const char*)
......@@ -19,5 +19,5 @@ cdef long long e = constructor_overload(17)
_ERRORS = u"""
18:40: Cannot assign type 'long' to 'wrapped_int'
18:40: Cannot assign type 'long' to 'const wrapped_int'
"""
# mode: run
# tag: cpp, werror
# tag: cpp, warnings
cimport cython
......@@ -9,6 +9,40 @@ b_asdf = b'asdf'
b_asdg = b'asdg'
b_s = b's'
cdef int compare_to_asdf_ref(string& s) except -999:
return s.compare(b"asdf")
def test_coerced_literal_ref():
"""
>>> test_coerced_literal_ref()
0
"""
return compare_to_asdf_ref("asdf")
cdef int compare_to_asdf_const_ref(const string& s) except -999:
return s.compare(b"asdf")
def test_coerced_literal_const_ref():
"""
>>> test_coerced_literal_const_ref()
0
"""
return compare_to_asdf_const_ref("asdf")
cdef int compare_to_asdf_const(const string s) except -999:
return s.compare(b"asdf")
def test_coerced_literal_const():
"""
>>> test_coerced_literal_const()
0
"""
return compare_to_asdf_const("asdf")
def test_conversion(py_obj):
"""
>>> test_conversion(b_asdf) == b_asdf or test_conversion(b_asdf)
......@@ -310,3 +344,8 @@ def test_iteration(string s):
[]
"""
return [c for c in s]
_WARNINGS = """
21:31: Cannot pass Python object as C++ data structure reference (string &), will pass by copy.
"""
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment