From 2c3e76e2e821dd18b670bd0f0b6a3533848d4768 Mon Sep 17 00:00:00 2001
From: Robert Bradshaw <robertwb@math.washington.edu>
Date: Wed, 4 Nov 2009 21:41:14 -0800
Subject: [PATCH] Fix bug #252, mangle illegal optional c argument names.

---
 Cython/Compiler/ExprNodes.py    | 2 +-
 Cython/Compiler/Nodes.py        | 4 +---
 Cython/Compiler/PyrexTypes.py   | 3 +++
 tests/bugs.txt                  | 1 -
 tests/run/bad_c_struct_T252.pyx | 8 ++++----
 5 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py
index bd6b2ff88..bc05047b6 100644
--- a/Cython/Compiler/ExprNodes.py
+++ b/Cython/Compiler/ExprNodes.py
@@ -2572,7 +2572,7 @@ class SimpleCallNode(CallNode):
                 for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
                     code.putln("%s.%s = %s;" % (
                             self.opt_arg_struct,
-                            formal_arg.name,
+                            func_type.opt_arg_cname(formal_arg.name),
                             actual_arg.result_as(formal_arg.type)))
             exc_checks = []
             if self.type.is_pyobject:
diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py
index 386e58eb0..dd9036566 100644
--- a/Cython/Compiler/Nodes.py
+++ b/Cython/Compiler/Nodes.py
@@ -1473,13 +1473,11 @@ class CFuncDefNode(FuncDefNode):
             code.putln('if (%s) {' % Naming.optional_args_cname)
             for arg in self.args:
                 if arg.default:
-                    # FIXME: simple name prefixing doesn't work when
-                    # argument name mangling is in place
                     code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
                     declarator = arg.declarator
                     while not hasattr(declarator, 'name'):
                         declarator = declarator.base
-                    code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
+                    code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
                     i += 1
             for _ in range(self.type.optional_arg_count):
                 code.putln('}')
diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py
index 05ee63804..a50760a4e 100644
--- a/Cython/Compiler/PyrexTypes.py
+++ b/Cython/Compiler/PyrexTypes.py
@@ -1535,6 +1535,9 @@ class CFuncType(CType):
     def signature_cast_string(self):
         s = self.declaration_code("(*)", with_calling_convention=False)
         return '(%s)' % s
+    
+    def opt_arg_cname(self, arg_name):
+        return self.op_arg_struct.base_type.scope.lookup(arg_name).cname
 
 
 class CFuncTypeArg(object):
diff --git a/tests/bugs.txt b/tests/bugs.txt
index 31d6ff3a8..23dca0c7b 100644
--- a/tests/bugs.txt
+++ b/tests/bugs.txt
@@ -5,5 +5,4 @@ methodmangling_T5
 class_attribute_init_values_T18
 numpy_ValueError_T172
 unsignedbehaviour_T184
-bad_c_struct_T252
 missing_baseclass_in_predecl_T262
diff --git a/tests/run/bad_c_struct_T252.pyx b/tests/run/bad_c_struct_T252.pyx
index e011ec2d3..2b457f235 100644
--- a/tests/run/bad_c_struct_T252.pyx
+++ b/tests/run/bad_c_struct_T252.pyx
@@ -1,10 +1,10 @@
 cdef cf(default=None):
     return default
 
-cpdef cpf(default=None):
+cpdef cpf(default=100):
     """
     >>> cpf()
-    None
+    100
     >>> cpf(1)
     1
     >>> cpf(default=2)
@@ -13,10 +13,10 @@ cpdef cpf(default=None):
     default = cf(default)
     return default
 
-def pf(default=None):
+def pf(default=100):
     """
     >>> pf()
-    None
+    100
     >>> pf(1)
     1
     >>> pf(default=2)
-- 
2.30.9