Propagate exceptions by default for cdef functions.
authorRobert Bradshaw <robertwb@math.washington.edu>
Wed, 16 Jul 2008 10:19:23 +0000 (03:19 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Wed, 16 Jul 2008 10:19:23 +0000 (03:19 -0700)
There should be a way to disable this...

Cython/Compiler/ExprNodes.py
Cython/Compiler/ModuleNode.py
Cython/Compiler/Naming.py
Cython/Compiler/Nodes.py

index 3ce905c801644d48df68600b66f127829b2ff396..3ace94e7a0b3dd4f21c37e2ec5bbac64be9b9460 100644 (file)
@@ -1668,6 +1668,17 @@ class SimpleCallNode(CallNode):
         if func_type.is_ptr:
             func_type = func_type.base_type
         return func_type
+        
+    def exception_checks(self):
+        func_type = self.function.type
+        exc_val = func_type.exception_value
+        exc_check = func_type.exception_check
+        if exc_val is None and self.function.entry.visibility != 'extern':
+            return_type = func_type.return_type
+            if not return_type.is_struct_or_union and not return_type.is_void:
+                exc_val = return_type.cast_code(Naming.default_error)
+            exc_check = 1
+        return exc_val, exc_check
     
     def analyse_c_function_call(self, env):
         func_type = self.function_type()
@@ -1710,12 +1721,13 @@ class SimpleCallNode(CallNode):
                     "Python object cannot be passed as a varargs parameter")
         # Calc result type and code fragment
         self.type = func_type.return_type
-        if self.type.is_pyobject \
-            or func_type.exception_value is not None \
-            or func_type.exception_check:
+        if self.type.is_pyobject:
+            self.is_temp = 1
+            self.result_ctype = py_object_type
+        else:
+            exc_val, exc_check = self.exception_checks()
+            if self.type.is_pyobject or exc_val is not None or exc_check:
                 self.is_temp = 1
-                if self.type.is_pyobject:
-                    self.result_ctype = py_object_type
         # C++ exception handler
         if func_type.exception_check == '+':
             if func_type.exception_value is None:
@@ -1780,8 +1792,7 @@ class SimpleCallNode(CallNode):
             if self.type.is_pyobject:
                 exc_checks.append("!%s" % self.result_code)
             else:
-                exc_val = func_type.exception_value
-                exc_check = func_type.exception_check
+                exc_val, exc_check = self.exception_checks()
                 if exc_val is not None:
                     exc_checks.append("%s == %s" % (self.result_code, exc_val))
                 if exc_check:
index 68394529e46eb2d20eeff18d98758827e4725808..b5d9a10988c2ac3070dd8398c69008384d099e84 100644 (file)
@@ -487,6 +487,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.putln("#ifndef __cdecl")
         code.putln("  #define __cdecl")
         code.putln("#endif")
+        code.putln('');
+        code.putln('#define %s 0xB0000000B000B0BBLL' % Naming.default_error);
+        code.putln('');
         self.generate_extern_c_macro_definition(code)
         code.putln("#include <math.h>")
         code.putln("#define %s" % Naming.api_guard_prefix + self.api_name(env))
index 4296bf71f024fc53de5a46928aea9cb3d7bcca22..ec70c6e280ef97c07c3da8b952a533722d53607b 100644 (file)
@@ -74,6 +74,7 @@ import_star      = pyrex_prefix + "import_star"
 import_star_set  = pyrex_prefix + "import_star_set"
 cur_scope_cname  = pyrex_prefix + "cur_scope"
 enc_scope_cname  = pyrex_prefix + "enc_scope"
+default_error    = pyrex_prefix + "ERROR"
 
 line_c_macro = "__LINE__"
 
index a3f312b898ac5c26067615feb8dcedec4bddbadc..33899c6f7ad1bb22b6cba91bdc1affc66d660fa7 100644 (file)
@@ -1207,11 +1207,18 @@ class CFuncDefNode(FuncDefNode):
         if self.return_type.is_pyobject:
             return "0"
         else:
-            #return None
-            return self.entry.type.exception_value
+            if self.entry.type.exception_value is not None:
+                return self.entry.type.exception_value
+            elif self.return_type.is_struct_or_union or self.return_type.is_void:
+                return None
+            else:
+                return self.return_type.cast_code(Naming.default_error)
             
     def caller_will_check_exceptions(self):
-        return self.entry.type.exception_check
+        if self.entry.type.exception_value is None:
+            return 1
+        else:
+            return self.entry.type.exception_check
                     
     def generate_optarg_wrapper_function(self, env, code):
         if self.type.optional_arg_count and \