2011/1/27 Stefan Behnel <stefan...@behnel.de>:
> Vitja Makarov, 27.01.2011 10:49:
>>>>>>>>>>>         def x():
>>>>>>>>>>>             do_some_stuff()
>>>>>>>>>>>
>>>>>>>>>>>             return # disable rest of code, e.g. during debugging
>>>>>>>>>>>
>>>>>>>>>>>             unreachable_code()
>>>>>>>>>>>
>>>>>>>>>>> Cython shouldn't bother generating dead code here (even if the C 
>>>>>>>>>>> compiler
>>>>>>>>>>> would drop it anyway).
>>>>>>>>>>
>>>>>>>>>> That should be rather easy to do: remove all the nodes in StatList
>>>>>>>>>> after: break, continue, return, raise, something else?
>>>>>>>>>
>>>>>>>>> Careful, this may involve recursive propagation through helper nodes. 
>>>>>>>>> The
>>>>>>>>> tree isn't always as simple as that.
>>>>>>>>>
>>>>>>>>> I think an attribute "is_terminator" on Nodes might do the job.
>>>>> the StatListNode (and
>>>>> other nodes) should inherit the flag from their last child.
>>>
>>>> I don't actually understand where could be that used later?
>>>
>>> Well, if you recursively propagate the flag through nodes that support it,
>>> you may end up in another StatListNode that strip its trailing dead code.
>>> Look through UtilNodes.py, there are a couple of nodes that can wrap
>>> Stat(List)Nodes. Maybe check Nodes.py also, not sure if there aren't any
>>> other nodes that can safely assume that a terminator at the end of their
>>> last child makes them a terminator as well.
>>
>> return and loop-controls are very different here
>>
>> if cond:
>>     return 1
>> else:
>>     return 0
>> # dead code follows
>>
>> We can set is_terminator here if all the clauses are terminators
>>
>> for i in a:
>>      if i>  0:
>>           continue
>>      else
>>           break
>>      # dead code here
>>
>> for i in a:
>>     return
>> # not dead
>>
>> for i in a:
>>      return
>> else:
>>      return
>> # dead
>>
>> It seems to me that each case should be handled its own way.
>> We can't simply say: this node have child with is_terminator set so
>> it's terminator too.
>
> That's what I meant, yes. You may also consider making is_terminator a
> method instead of a simple attribute. That would allow nodes to reimplement
> it (even recursively) and make decisions based on their context.
>
>
>> Is there a way to write tests for warnings? If no think we should create one.
>
> Not yet, it wasn't really a high priority back when I wrote the error test
> support.
>

I would try to handle this.

>
>>>>>> Some error tests do fail because nodes are removed and code generation
>>>>>> time error is omited.
>>>>>
>>>>> That should be fixable in most cases. We could also use a compiler option
>>>>> that disables dead code removal, and then use it in the error tests.
>>>>
>>>> Hmm, not sure here.
>>>> I think it should be better to move checks outside code generation.
>>>
>>> Ah, ok, I misunderstood you then. Yes, errors should no longer occur at
>>> code generation time.
>>
>> Think that's whole lot of work.
>
> Steps in that direction have been taken several times already. Hopefully,
> they will eventually converge to the expected state.
>
>
>> When implementing generators I've moved error checking into 
>> ParseTreeTransforms
>> and left 'yield not supported' in YieldExprNode. That could be later
>> replaced with: raise InternalError
>
> Hmm? YieldExprNode is used and generates code, doesn't it? Or did you mean
> to raise InternalError on errors that should have been caught before? I
> don't think there's a need to retest inside of the node. If someone
> disables that transform, I'm fine with seeing Cython crash.
>

https://github.com/vitek/cython/blob/master/Cython/Compiler/ExprNodes.py#L4995

....
    def analyse_types(self, env):
        if not self.label_num:
            error(self.pos, "'yield' not supported here")
....

This error message should be replaced with assertion on self.label_num
or internal error.


-- 
vitja.
_______________________________________________
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to