--- /dev/null
+# ticket: 676
+# tag: cpp
+
+from cython cimport typeof
+
+cdef extern from "arithmetic_analyse_types_helper.h":
+ cdef struct short_return:
+ char *msg
+ cdef struct int_return:
+ char *msg
+ cdef struct longlong_return:
+ char *msg
+ cdef short_return f(short)
+ cdef int_return f(int)
+ cdef longlong_return f(long long)
+
+def short_binop(short val):
+ """
+ Arithmetic in C is always done with at least int precision.
+
+ >>> short_binop(3)
+ 'int called'
+ """
+ assert typeof(val + val) == "int", typeof(val + val)
+ assert typeof(val - val) == "int", typeof(val - val)
+ assert typeof(val & val) == "int", typeof(val & val)
+ cdef int_return x = f(val + val)
+ return x.msg
+
+def short_unnop(short val):
+ """
+ Arithmetic in C is always done with at least int precision.
+
+ >>> short_unnop(3)
+ 'int called'
+ """
+ cdef int_return x = f(-val)
+ return x.msg
+
+def longlong_binop(long long val):
+ """
+ >>> longlong_binop(3)
+ 'long long called'
+ """
+ cdef longlong_return x = f(val * val)
+ return x.msg
+
+def longlong_unnop(long long val):
+ """
+ >>> longlong_unnop(3)
+ 'long long called'
+ """
+ cdef longlong_return x = f(~val)
+ return x.msg
+
+
+def test_bint(bint a):
+ """
+ >>> test_bint(True)
+ """
+ assert typeof(a + a) == "int", typeof(a + a)
+ assert typeof(a & a) == "bint", typeof(a & a)
--- /dev/null
+/* A set of mutually incompatable return types. */
+
+struct short_return { const char *msg; };
+struct int_return { const char *msg; };
+struct longlong_return { const char *msg; };
+
+/* A set of overloaded methods. */
+
+short_return f(short arg) {
+ short_return val;
+ val.msg = "short called";
+ return val;
+}
+
+int_return f(int arg) {
+ int_return val;
+ val.msg = "int called";
+ return val;
+}
+
+longlong_return f(long long arg) {
+ longlong_return val;
+ val.msg = "long long called";
+ return val;
+}
+
+