Commit db1f0ad5 authored by Stefan Behnel's avatar Stefan Behnel

make analyse_const_expression() pass on the return value of its internal call to analyse_types()

parent 6075a3c6
...@@ -372,8 +372,9 @@ class ExprNode(Node): ...@@ -372,8 +372,9 @@ class ExprNode(Node):
# constant expression. Analyses the expression's type, # constant expression. Analyses the expression's type,
# checks whether it is a legal const expression, # checks whether it is a legal const expression,
# and determines its value. # and determines its value.
self.analyse_types(env) node = self.analyse_types(env)
return self.check_const() node.check_const()
return node
def analyse_expressions(self, env): def analyse_expressions(self, env):
# Convenience routine performing both the Type # Convenience routine performing both the Type
......
...@@ -537,7 +537,7 @@ class CArrayDeclaratorNode(CDeclaratorNode): ...@@ -537,7 +537,7 @@ class CArrayDeclaratorNode(CDeclaratorNode):
base_type = base_type.specialize_here(self.pos, values) base_type = base_type.specialize_here(self.pos, values)
return self.base.analyse(base_type, env, nonempty = nonempty) return self.base.analyse(base_type, env, nonempty = nonempty)
if self.dimension: if self.dimension:
self.dimension.analyse_const_expression(env) self.dimension = self.dimension.analyse_const_expression(env)
if not self.dimension.type.is_int: if not self.dimension.type.is_int:
error(self.dimension.pos, "Array dimension not integer") error(self.dimension.pos, "Array dimension not integer")
size = self.dimension.get_constant_c_result_code() size = self.dimension.get_constant_c_result_code()
...@@ -621,33 +621,35 @@ class CFuncDeclaratorNode(CDeclaratorNode): ...@@ -621,33 +621,35 @@ class CFuncDeclaratorNode(CDeclaratorNode):
env.add_include_file('new') # for std::bad_alloc env.add_include_file('new') # for std::bad_alloc
env.add_include_file('stdexcept') env.add_include_file('stdexcept')
env.add_include_file('typeinfo') # for std::bad_cast env.add_include_file('typeinfo') # for std::bad_cast
if return_type.is_pyobject \ if (return_type.is_pyobject
and (self.exception_value or self.exception_check) \ and (self.exception_value or self.exception_check)
and self.exception_check != '+': and self.exception_check != '+'):
error(self.pos, error(self.pos,
"Exception clause not allowed for function returning Python object") "Exception clause not allowed for function returning Python object")
else: else:
if self.exception_value: if self.exception_value:
self.exception_value.analyse_const_expression(env) self.exception_value = self.exception_value.analyse_const_expression(env)
if self.exception_check == '+': if self.exception_check == '+':
self.exception_value = self.exception_value.analyse_types(env)
exc_val_type = self.exception_value.type exc_val_type = self.exception_value.type
if not exc_val_type.is_error and \ if (not exc_val_type.is_error
not exc_val_type.is_pyobject and \ and not exc_val_type.is_pyobject
not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0): and not (exc_val_type.is_cfunction
and not exc_val_type.return_type.is_pyobject
and not exc_val_type.args)):
error(self.exception_value.pos, error(self.exception_value.pos,
"Exception value must be a Python exception or cdef function with no arguments.") "Exception value must be a Python exception or cdef function with no arguments.")
exc_val = self.exception_value exc_val = self.exception_value
else: else:
self.exception_value = self.exception_value.coerce_to(return_type, env) self.exception_value = self.exception_value.coerce_to(
if self.exception_value.analyse_const_expression(env): return_type, env).analyse_const_expression(env)
exc_val = self.exception_value.get_constant_c_result_code() exc_val = self.exception_value.get_constant_c_result_code()
if exc_val is None: if exc_val is None:
raise InternalError("get_constant_c_result_code not implemented for %s" % raise InternalError(
self.exception_value.__class__.__name__) "get_constant_c_result_code not implemented for %s" %
if not return_type.assignable_from(self.exception_value.type): self.exception_value.__class__.__name__)
error(self.exception_value.pos, if not return_type.assignable_from(self.exception_value.type):
"Exception value incompatible with function return type") error(self.exception_value.pos,
"Exception value incompatible with function return type")
exc_check = self.exception_check exc_check = self.exception_check
if return_type.is_cfunction: if return_type.is_cfunction:
error(self.pos, error(self.pos,
...@@ -1376,10 +1378,10 @@ class CEnumDefItemNode(StatNode): ...@@ -1376,10 +1378,10 @@ class CEnumDefItemNode(StatNode):
def analyse_declarations(self, env, enum_entry): def analyse_declarations(self, env, enum_entry):
if self.value: if self.value:
self.value.analyse_const_expression(env) self.value = self.value.analyse_const_expression(env)
if not self.value.type.is_int: if not self.value.type.is_int:
self.value = self.value.coerce_to(PyrexTypes.c_int_type, env) self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
self.value.analyse_const_expression(env) self.value = self.value.analyse_const_expression(env)
entry = env.declare_const(self.name, enum_entry.type, entry = env.declare_const(self.name, enum_entry.type,
self.value, self.pos, cname = self.cname, self.value, self.pos, cname = self.cname,
visibility = enum_entry.visibility, api = enum_entry.api) visibility = enum_entry.visibility, api = enum_entry.api)
......
...@@ -35,3 +35,14 @@ def test3(): ...@@ -35,3 +35,14 @@ def test3():
cdef int a[MY_SIZE_A] cdef int a[MY_SIZE_A]
cdef int b[MY_SIZE_B] cdef int b[MY_SIZE_B]
return sizeof(a)/sizeof(int), sizeof(b)/sizeof(int) return sizeof(a)/sizeof(int), sizeof(b)/sizeof(int)
from libc cimport limits
def test_cimported_attribute():
"""
>>> test_cimported_attribute()
True
"""
cdef char a[limits.CHAR_MAX]
return sizeof(a) >= 127
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