Fix __builtin_constant_p(1000/x)
was incorrectly treated as constant because the vpop removed all traces of non-constness.
This commit is contained in:
		
							parent
							
								
									5bd8aeb917
								
							
						
					
					
						commit
						49bb5a7e06
					
				
					 2 changed files with 27 additions and 0 deletions
				
			
		
							
								
								
									
										17
									
								
								tccgen.c
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								tccgen.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1787,6 +1787,13 @@ static void gen_opic(int op)
 | 
			
		|||
                    gen_opi(op);
 | 
			
		||||
            } else {
 | 
			
		||||
                vtop--;
 | 
			
		||||
		/* Ensure vtop isn't marked VT_CONST in case something
 | 
			
		||||
		   up our callchain is interested in const-ness of the
 | 
			
		||||
		   expression.  Also make it a non-LVAL if it was,
 | 
			
		||||
		   so that further code can't accidentally generate
 | 
			
		||||
		   a deref (happen only for buggy uses of e.g.
 | 
			
		||||
		   gv() under nocode_wanted).  */
 | 
			
		||||
		vtop->r &= ~(VT_VALMASK | VT_LVAL);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -5014,6 +5021,16 @@ static void expr_cond(void)
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
	    /* XXX This doesn't handle nocode_wanted correctly at all.
 | 
			
		||||
	       It unconditionally calls gv/gvtst and friends.  That's
 | 
			
		||||
	       the case for many of the expr_ routines.  Currently
 | 
			
		||||
	       that should generate only useless code, but depending
 | 
			
		||||
	       on other operand handling this might also generate
 | 
			
		||||
	       pointer derefs for lvalue conversions whose result
 | 
			
		||||
	       is useless, but nevertheless can lead to segfault.
 | 
			
		||||
 | 
			
		||||
	       Somewhen we need to overhaul the whole nocode_wanted
 | 
			
		||||
	       handling.  */
 | 
			
		||||
            if (vtop != vstack) {
 | 
			
		||||
                /* needed to avoid having different registers saved in
 | 
			
		||||
                   each branch */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1082,6 +1082,14 @@ static int toupper1(int a)
 | 
			
		|||
    return TOUPPER(a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static unsigned int calc_vm_flags(unsigned int prot)
 | 
			
		||||
{
 | 
			
		||||
  unsigned int prot_bits;
 | 
			
		||||
  /* This used to segfault in some revisions: */
 | 
			
		||||
  prot_bits = ((0x1==0x00000001)?(prot&0x1):(prot&0x1)?0x00000001:0);
 | 
			
		||||
  return prot_bits;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void bool_test()
 | 
			
		||||
{
 | 
			
		||||
    int *s, a, b, t, f, i;
 | 
			
		||||
| 
						 | 
				
			
			@ -1154,6 +1162,7 @@ void bool_test()
 | 
			
		|||
        if (toupper1 (i) != TOUPPER (i))
 | 
			
		||||
            printf("error %d\n", i);
 | 
			
		||||
    }
 | 
			
		||||
    printf ("bits = 0x%x\n", calc_vm_flags (0x1));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* GCC accepts that */
 | 
			
		||||
| 
						 | 
				
			
			@ -2880,6 +2889,7 @@ void builtin_test(void)
 | 
			
		|||
    printf("res = %d\n", __builtin_constant_p(1 + 2));
 | 
			
		||||
    printf("res = %d\n", __builtin_constant_p(&constant_p_var));
 | 
			
		||||
    printf("res = %d\n", __builtin_constant_p(constant_p_var));
 | 
			
		||||
    printf("res = %d\n", __builtin_constant_p(100000 / constant_p_var));
 | 
			
		||||
    s = 1;
 | 
			
		||||
    ll = 2;
 | 
			
		||||
    i = __builtin_choose_expr (1 != 0, ll, s);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue