1. No warnings for unreferenced code in eu40b2 build r3025

Hi, I did not find an open ticket for this.. perhaps I missed it?

-- show missing warnings about procedure / function never used 
-- Euphoria 4.0B2 build r3025 
-- 
with warning 
with trace 
with type_check 
without profile 
-- 
procedure proc_not_called() 
          atom a1, a2 
          a2 = 0 
          a1 = a2 
          a2 = a1 
end procedure 
 
procedure proc_is_called() 
          atom a1, a2 
          a2 = 0 
          a1 = a2 
          a2 = a1 
end procedure 
 
function func_never_called(sequence junk) 
         integer i1 
         i1 = 0 
         return i1 
end function 
 
proc_is_called() 


There are no eui (interpreter) or euc (watcom compiled) warnings about either the function or procedure never being used.
Regards, Alan

new topic     » topic index » view message » categorize

2. Re: No warnings for unreferenced code in eu40b2 build r3025

Same thing for Euphoria v3.1.1
I'll check earlier releases.. I'm sure there used to be warnings about this before!

new topic     » goto parent     » topic index » view message » categorize

3. Re: No warnings for unreferenced code in eu40b2 build r3025

No warnings from Euphoria v2.5 official,
Euphoria v2.4 official gives a (correct) warning about parameter "junk" not used.
I'll keep checking back versions up to my oldest v1.4; hopefully I find it ;)
Regards, Alan

new topic     » goto parent     » topic index » view message » categorize

4. Re: No warnings for unreferenced code in eu40b2 build r3025

alanjohnoxley said...

Hi, I did not find an open ticket for this.. perhaps I missed it?

-- show missing warnings about procedure / function never used 
-- Euphoria 4.0B2 build r3025 
-- 
with warning 
with trace 
with type_check 
without profile 
-- 
procedure proc_not_called() 
          atom a1, a2 
          a2 = 0 
          a1 = a2 
          a2 = a1 
end procedure 
 
procedure proc_is_called() 
          atom a1, a2 
          a2 = 0 
          a1 = a2 
          a2 = a1 
end procedure 
 
function func_never_called(sequence junk) 
         integer i1 
         i1 = 0 
         return i1 
end function 
 
proc_is_called() 


There are no eui (interpreter) or euc (watcom compiled) warnings about either the function or procedure never being used.
Regards, Alan

I believe this was a deliberate design decision, not a bug.

The problem is that it could be virtually impossible for the interpreter to reliably determine if a function or procedure is actually referenced. It may be called like this:

call_proc(routine_id("proc_not_called"),{}) 


This statement may or may not be called in a particular program run and may be in another file. The parameter for routine_id() isn't necessarily a literal but could be calculated at run time. In some programs specific procedures or functions are always called this way.

I believe that Rob Craig mentioned this in a post some years ago after v2.5 was released. At that time he was the only developer.

new topic     » goto parent     » topic index » view message » categorize

5. Re: No warnings for unreferenced code in eu40b2 build r3025

Hmm...
But what about the linker when the object code is compiled and linked...
Its job is make sure a jump/goto/branch target is valid?
Else it must be a self modifying program to know where to branch to..
If all possible entry points (procedure / function) are compared with all branches, won't this show what is redundant?


Regards, Alan

new topic     » goto parent     » topic index » view message » categorize

6. Re: No warnings for unreferenced code in eu40b2 build r3025

alanjohnoxley said...

Hmm...
But what about the linker when the object code is compiled and linked...
Its job is make sure a jump/goto/branch target is valid?
Else it must be a self modifying program to know where to branch to..
If all possible entry points (procedure / function) are compared with all branches, won't this show what is redundant?

It would be possible to add a warning for this, but if the application contains just one routine_id() whose argument is not a literal, then all bets are off - any routine could be called and the parser would not know if an unreferenced routine is not being indirectly called via the routine_id() facility.

For example...

procedure notcalled() 
   puts(1, "I wasn't called\n") 
end procedure 
 
sequence cmd 
 
cmd = command_line() 
for i = 3 to length(cmd) do 
   r = routine_id(cmd[i]) 
   if r != -1 then 
      call_proc(r,{}) 
   end if 
end for 

Given this program, the routine notcalled is not directly referenced, but it might still be called if the user runs the program as ...

eui myapp notcalled 

new topic     » goto parent     » topic index » view message » categorize

7. Re: No warnings for unreferenced code in eu40b2 build r3025

By the way, if you want a list of unused routines, you can run the bind command with the -list option.

bind -list myapp.ex 

And the list is created in a file called 'deleted.txt'.

new topic     » goto parent     » topic index » view message » categorize

8. Re: No warnings for unreferenced code in eu40b2 build r3025

DerekParnell said...
alanjohnoxley said...

Hmm...
But what about the linker when the object code is compiled and linked...
Its job is make sure a jump/goto/branch target is valid?
Else it must be a self modifying program to know where to branch to..
If all possible entry points (procedure / function) are compared with all branches, won't this show what is redundant?

It would be possible to add a warning for this, but if the application contains just one routine_id() whose argument is not a literal, then all bets are off - any routine could be called and the parser would not know if an unreferenced routine is not being indirectly called via the routine_id() facility.

For example...

procedure notcalled() 
   puts(1, "I wasn't called\n") 
end procedure 
 
sequence cmd 
 
cmd = command_line() 
for i = 3 to length(cmd) do 
   r = routine_id(cmd[i]) 
   if r != -1 then 
      call_proc(r,{}) 
   end if 
end for 

Given this program, the routine notcalled is not directly referenced, but it might still be called if the user runs the program as ...

eui myapp notcalled 

Thanks Derek, I'll use the bind -list to find unreferenced code, when I am suspicious that there may be some.
Can I request a new interpreter feature to issue a warning for where a code block is not explicitly referenced,
that that code is possibly never executed?
Im more interested in the "show me redundant code" angle than the "your call may be branching to nowhere" side.
It does not have to be smart, like should a call be within an if statement, will it be called. That would be impossible I think. ;)
A simple comparison of callable targets with calls (within the global scope) to reveal unreachable code.
Writing code, and debugging it is normally done using the interpreter (not the binder) after all.

Regards, Alan

new topic     » goto parent     » topic index » view message » categorize

9. Re: No warnings for unreferenced code in eu40b2 build r3025

alanjohnoxley said...
DerekParnell said...
alanjohnoxley said...

Hmm...
But what about the linker when the object code is compiled and linked...
Its job is make sure a jump/goto/branch target is valid?
Else it must be a self modifying program to know where to branch to..
If all possible entry points (procedure / function) are compared with all branches, won't this show what is redundant?

It would be possible to add a warning for this, but if the application contains just one routine_id() whose argument is not a literal, then all bets are off - any routine could be called and the parser would not know if an unreferenced routine is not being indirectly called via the routine_id() facility.

For example...

procedure notcalled() 
   puts(1, "I wasn't called\n") 
end procedure 
 
sequence cmd 
 
cmd = command_line() 
for i = 3 to length(cmd) do 
   r = routine_id(cmd[i]) 
   if r != -1 then 
      call_proc(r,{}) 
   end if 
end for 

Given this program, the routine notcalled is not directly referenced, but it might still be called if the user runs the program as ...

eui myapp notcalled 

Thanks Derek, I'll use the bind -list to find unreferenced code, when I am suspicious that there may be some.
Can I request a new interpreter feature to issue a warning for where a code block is not explicitly referenced,
that that code is possibly never executed?
Im more interested in the "show me redundant code" angle than the "your call may be branching to nowhere" side.
It does not have to be smart, like should a call be within an if statement, will it be called. That would be impossible I think. ;)
A simple comparison of callable targets with calls (within the global scope) to reveal unreachable code.
Writing code, and debugging it is normally done using the interpreter (not the binder) after all.

Regards, Alan

Hi Alan,

I'm not sure that I agree with Derek that even "one routine_id() whose argument is not a literal" automatically means that "any routine could be called" thus defeating a check for unreferenced code. This is because routine_id() can only reach as far as it's scope allows - anything outside that is fair game for analysis.

I wrote the Orac compiler as a way of overcoming certain problems in Euphoria. To be honest, I don't know how routine_id functions under the 4.0 environment but what I did with Orac was simply to decree that the scope of routine_id() be limited to those modules visible at that point. That way I can be sure that any modules outside that scope could be optimized.

When I run the compiler using itself as the target I can analyse the source to see that there are scores of routines not directly referenced in the code and could delete these if so desired. The compiler has an option to ignore these in the output anyway.

Probably most Euphoria programmers would consider it too much trouble to use Orac because of the conversion step required and incompatibility issues (and a few compiler bugs). Still, ..

regards,
Mike

new topic     » goto parent     » topic index » view message » categorize

10. Re: No warnings for unreferenced code in eu40b2 build r3025

Spock said...

I'm not sure that I agree with Derek that even "one routine_id() whose argument is not a literal" automatically means that "any routine could be called" thus defeating a check for unreferenced code. This is because routine_id() can only reach as far as it's scope allows - anything outside that is fair game for analysis.

While that is true, it's actually the call_proc() that is in question here. For example, a call to routine_id() can fetch a valid ID value then pass that value to another routine that in turn runs call_proc().

A library file ...

--- filea.e 
procedure PROC_foo() 
   puts(1, "called\n") 
end procedure 
 
public function getrid( sequence name) 
   return routine_id("PROC_" & name) 
end function 
---- end of filea.e --- 


The app file ...

-- myapp.ex 
include filea.e 
integer rid 
sequence cmds 
 
cmds = command_line() 
rid = getrid(cmds[3]) 
call_proc( rid,{}) 
-- end of myapp.ex 

Here is an example of the parser not knowing if 'PROC_foo' is ever called, and notice that if the user runs it as eui myapp foo then it will be called even though it is out of myapp's scope.

new topic     » goto parent     » topic index » view message » categorize

11. Re: No warnings for unreferenced code in eu40b2 build r3025

DerekParnell said...
Spock said...

I'm not sure that I agree with Derek that even "one routine_id() whose argument is not a literal" automatically means that "any routine could be called" thus defeating a check for unreferenced code. This is because routine_id() can only reach as far as it's scope allows - anything outside that is fair game for analysis.

While that is true, it's actually the call_proc() that is in question here. For example, a call to routine_id() can fetch a valid ID value then pass that value to another routine that in turn runs call_proc().


Derek,

I think you're missing the point. Any module not part of the scope of a routine_id() call could potentially have non-referenced routines in it that a parser can detect and ignore. Let's consider your very own example with a small adjustment:

A library file ...

--- filea.e 
procedure PROC_foo() 
   puts(1, "called\n") 
end procedure 
 
public function getrid( sequence name) 
   return routine_id("PROC_" & name) 
end function 
---- end of filea.e --- 


The app file ...

-- myapp.ex 
include filea.e 
integer rid 
sequence cmds 
 
procedure nop() -- redundant routine 
return 
end procedure 
 
cmds = command_line() 
rid = getrid(cmds[3]) 
call_proc( rid,{}) 
-- end of myapp.ex 


In this case nop() is not in the scope of routine_id. It is also not called directly from anywhere in the code. Logically it could be omitted from the compiler output and have no impact whatsoever on the program execution.

How would nop() be called inadvertently? No routine_id() can see it to pass its' id to another part of the cade to be called indirectly. And it's not called directly either. So, how?

regards,
Mike

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu