Disable array literals outside of pointer declaration
authorDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Tue, 14 Oct 2008 07:08:43 +0000 (09:08 +0200)
committerDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Tue, 14 Oct 2008 07:08:43 +0000 (09:08 +0200)
Cython/Compiler/ExprNodes.py
Cython/Compiler/Optimize.py
tests/errors/literal_lists.pyx [new file with mode: 0644]

index 7f993eeb20eb105e28ed210ef9619098aa231efc..ba049fff4f7b7754cbe421eaffbdc9719928c911 100644 (file)
@@ -935,7 +935,7 @@ class NameNode(AtomicExprNode):
     is_name = True
     is_cython_module = False
     cython_attribute = None
-    skip_assignment_decref = False
+    lhs_of_first_assignment = False
     entry = None
 
     def create_analysed_rvalue(pos, env, entry):
@@ -1156,6 +1156,10 @@ class NameNode(AtomicExprNode):
         entry = self.entry
         if entry is None:
             return # There was an error earlier
+
+        if (self.entry.type.is_ptr and isinstance(rhs, ListNode)
+            and not self.lhs_of_first_assignment):
+            error(self.pos, "Literal list must be assigned to pointer at time of declaration")
         
         # is_pyglobal seems to be True for module level-globals only.
         # We use this to access class->tp_dict if necessary.
@@ -1200,7 +1204,7 @@ class NameNode(AtomicExprNode):
                 #print "...from", rhs ###
                 #print "...LHS type", self.type, "ctype", self.ctype() ###
                 #print "...RHS type", rhs.type, "ctype", rhs.ctype() ###
-                if not self.skip_assignment_decref:
+                if not self.lhs_of_first_assignment:
                     if entry.is_local and not Options.init_local_none:
                         initalized = entry.scope.control_flow.get_state((entry.name, 'initalized'), self.pos)
                         if initalized is True:
@@ -1223,7 +1227,7 @@ class NameNode(AtomicExprNode):
 
         import Buffer
         Buffer.put_assign_to_buffer(self.result(), rhstmp, buffer_aux, self.entry.type,
-                                    is_initialized=not self.skip_assignment_decref,
+                                    is_initialized=not self.lhs_of_first_assignment,
                                     pos=self.pos, code=code)
         code.putln("%s = 0;" % rhstmp)
         code.funcstate.release_temp(rhstmp)
index 7422b82ed562894bb2db88c8aec80d862c609bd3..2e4641497e4fa4e685b0b2f6f8e32368169e49fa 100644 (file)
@@ -152,12 +152,11 @@ class FinalOptimizePhase(Visitor.CythonTransform):
     def visit_SingleAssignmentNode(self, node):
         if node.first:
             lhs = node.lhs
+            lhs.lhs_of_first_assignment = True
             if isinstance(lhs, ExprNodes.NameNode) and lhs.entry.type.is_pyobject:
                 # Have variable initialized to 0 rather than None
                 lhs.entry.init_to_none = False
                 lhs.entry.init = 0
-                # Set a flag in NameNode to skip the decref
-                lhs.skip_assignment_decref = True
         return node
 
     def visit_SimpleCallNode(self, node):
diff --git a/tests/errors/literal_lists.pyx b/tests/errors/literal_lists.pyx
new file mode 100644 (file)
index 0000000..adbff03
--- /dev/null
@@ -0,0 +1,8 @@
+def f():
+    cdef int* p
+    if False:
+        p = [1, 2, 3]
+
+_ERRORS = u"""
+4:10: Literal list must be assigned to pointer at time of declaration
+"""