Skip to content

Commit

Permalink
Warn about discarting const qualifier (cython#5987)
Browse files Browse the repository at this point in the history
  • Loading branch information
matusvalo committed Feb 11, 2024
1 parent b5bdf9c commit 4099448
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
19 changes: 19 additions & 0 deletions Cython/Compiler/Nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6022,8 +6022,19 @@ class AssignmentNode(StatNode):
# parallel assignment to be evaluated before assigning
# to any of the left hand sides.

def _warn_on_const_assignment(self, lhs, rhs):
rhs_t = rhs.type
lhs_t = lhs.type
if rhs_t.is_ptr and rhs_t.base_type.is_const and lhs_t.is_ptr and not lhs_t.base_type.is_const:
warning(self.pos, "Assigning to '{}' from '{}' discards const qualifier".format(lhs_t, rhs_t), level=1)

def _check_const_assignment(self, node):
if isinstance(node, AssignmentNode):
self._warn_on_const_assignment(node.lhs, node.rhs)

def analyse_expressions(self, env):
node = self.analyse_types(env)
self._check_const_assignment(node)
if isinstance(node, AssignmentNode) and not isinstance(node, ParallelAssignmentNode):
if node.rhs.type.is_ptr and node.rhs.is_ephemeral():
error(self.pos, "Storing unsafe C derivative of temporary Python reference")
Expand Down Expand Up @@ -6374,6 +6385,11 @@ class CascadedAssignmentNode(AssignmentNode):
coerced_values = None
assignment_overloads = None

def _check_const_assignment(self, node):
if isinstance(node, CascadedAssignmentNode):
for lhs in node.lhs_list:
self._warn_on_const_assignment(lhs, node.rhs)

def analyse_declarations(self, env):
for lhs in self.lhs_list:
lhs.analyse_target_declaration(env)
Expand Down Expand Up @@ -6480,6 +6496,9 @@ def analyse_declarations(self, env):
def analyse_expressions(self, env):
self.stats = [stat.analyse_types(env, use_temp=1)
for stat in self.stats]

for stat in self.stats:
stat._check_const_assignment(stat)
return self

# def analyse_expressions(self, env):
Expand Down
23 changes: 22 additions & 1 deletion tests/errors/const_decl_errors.pyx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# mode: error

# tag: warnings
cdef const object o

# TODO: This requires making the assignment at declaration time.
Expand Down Expand Up @@ -27,6 +27,19 @@ cdef func(const int a, const int* b, const (int*) c, const S s, int *const d, in

cdef volatile object v

cdef const_warn(const int *b, const int *c):
cdef int *x = b
cdef int *y
cdef int *z
y, z = b, c
z = y = b

cdef const_ok(const int *b, const int *c):
cdef const int *x = b
cdef const int *y
cdef const int *z
y, z = b, c
z = y = b

_ERRORS = """
3:5: Const/volatile base type cannot be a Python object
Expand All @@ -41,3 +54,11 @@ _ERRORS = """
26:4: Assignment to const 't'
28:5: Const/volatile base type cannot be a Python object
"""

_WARNINGS = """
31:9: Assigning to 'int *' from 'const int *' discards const qualifier
34:11: Assigning to 'int *' from 'const int *' discards const qualifier
34:14: Assigning to 'int *' from 'const int *' discards const qualifier
35:12: Assigning to 'int *' from 'const int *' discards const qualifier
35:12: Assigning to 'int *' from 'const int *' discards const qualifier
"""

0 comments on commit 4099448

Please sign in to comment.