Tcl Source Code

View Ticket
Login
Ticket UUID: 04e26c02c04596869907b5240ffa0c97457df352
Title: Warning
Type: Patch Version: trunk
Submitter: gahr Created on: 2017-04-27 10:35:36
Subsystem: 47. Bytecode Compiler Assigned To: dgp
Priority: 5 Medium Severity: Minor
Status: Closed Last Modified: 2017-04-28 14:16:27
Resolution: Fixed Closed By: dgp
    Closed on: 2017-04-28 14:16:27
Description:
Warning in tclExecute.c. A branch is never taken - TclCompareTwoNumbers states as prerequisite that the arguments are known to be of numeric and not NaN - but the compiler doesn't know it.

generic/tclExecute.c:9244:12: warning: variable 'type1' is used uninitialized whenever '?:' condition is true [-Wsometimes-uninitialized]                                                                                                                                 
    (void) GetNumberFromObj(NULL, valuePtr, &ptr1, &type1);                     
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                      
generic/tclExecute.c:513:5: note: expanded from macro 'GetNumberFromObj'                                  
    ((((objPtr)->typePtr == NULL) && ((objPtr)->bytes == NULL)) ||      \       
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~       
generic/tclExecute.c:9247:13: note: uninitialized use occurs here                                         
    switch (type1) {                                                            
            ^~~~~                                                               
generic/tclExecute.c:9244:12: note: remove the '?:' if its condition is always false                      
    (void) GetNumberFromObj(NULL, valuePtr, &ptr1, &type1);                     
           ^                                                                    
generic/tclExecute.c:513:5: note: expanded from macro 'GetNumberFromObj'                                  
    ((((objPtr)->typePtr == NULL) && ((objPtr)->bytes == NULL)) ||      \       
    ^
User Comments: gahr added on 2017-04-28 06:04:42:
I fear this won't be enough: there is still an error case that isn't checked by the two expansions in TclCompareTwoNumbers. This function assumes that the objects are of some numeric type, so the value of the expression is just discarded and type is expected to be set after the expansion.


generic/tclExecute.c:9242:12: warning: variable 'type1' is used uninitialized whenever '?:' condition is true
      [-Wsometimes-uninitialized]
    (void) GetNumberFromObj(NULL, valuePtr, &ptr1, &type1);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
generic/tclExecute.c:513:5: note: expanded from macro 'GetNumberFromObj'
    (((objPtr)->bytes != NULL) && ((objPtr)->length == 0))              \
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
generic/tclExecute.c:9245:13: note: uninitialized use occurs here
    switch (type1) {
            ^~~~~
generic/tclExecute.c:9242:12: note: remove the '?:' if its condition is always false
    (void) GetNumberFromObj(NULL, valuePtr, &ptr1, &type1);
           ^
generic/tclExecute.c:513:5: note: expanded from macro 'GetNumberFromObj'
    (((objPtr)->bytes != NULL) && ((objPtr)->length == 0))              \
    ^
generic/tclExecute.c:9233:14: note: initialize the variable 'type1' to silence this warning
    int type1, type2, compare;
             ^
              = 0
1 warning generated.

dgp added on 2017-04-27 17:26:57:
fixed on all dev branches.

dgp added on 2017-04-27 16:34:53:
That test is present to preserve the same test
done in earlier versions of the bytecode engine
that trace back to this March 2000 "optimization":

http://core.tcl.tk/tcl/info/6f0ee764c164f12f

Best I can tell, that was just always (harmlessly)
wrong, testing a condition that always has a known
truth value.  The comment alongside it is just 
blatantly false.  Even back in that day, we were
using tclEmptyString to represent our empty strings.
A NULL objPtr->bytes was always a sign of a pure
internal value, unless someone can show me otherwise.

Whether it was always wrong, or became outdated and wrong,
no need to keep the vestige anymore.

dgp added on 2017-04-27 13:47:00:
It appears the error is in testing this condition at all:

((objPtr)->typePtr == NULL) && ((objPtr)->bytes == NULL))

A valid Tcl_Obj must follow the stork model. It must be
standing on at least one leg.  The condition above is
testing

  "If this stork is standing on 0 legs..."

which has to always report false.

Removing that seems to be the better solution, unless
we can find some reason it was placed there that makes
sense.

gahr (claiming to be [email protected]) added on 2017-04-27 10:37:53:
A fix is available in the [tkt-04e26c02c0] branch.