mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	Warn more duplicate literal hash keys
Following non-special_const literals: * T_BIGNUM * T_FLOAT (non-flonum) * T_RATIONAL * T_COMPLEX
This commit is contained in:
		
							parent
							
								
									a023db49bf
								
							
						
					
					
						commit
						37eb5e7439
					
				
				
				Notes:
				
					git
				
				2021-06-03 15:11:39 +09:00 
				
			
			
			
		
		
					 4 changed files with 47 additions and 9 deletions
				
			
		
							
								
								
									
										16
									
								
								compile.c
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								compile.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1967,8 +1967,8 @@ iseq_set_local_table(rb_iseq_t *iseq, const ID *tbl)
 | 
			
		|||
    return COMPILE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
cdhash_cmp(VALUE val, VALUE lit)
 | 
			
		||||
int
 | 
			
		||||
rb_iseq_cdhash_cmp(VALUE val, VALUE lit)
 | 
			
		||||
{
 | 
			
		||||
    int tval, tlit;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2004,20 +2004,20 @@ cdhash_cmp(VALUE val, VALUE lit)
 | 
			
		|||
    else if (tlit == T_RATIONAL) {
 | 
			
		||||
        const struct RRational *rat1 = RRATIONAL(val);
 | 
			
		||||
        const struct RRational *rat2 = RRATIONAL(lit);
 | 
			
		||||
        return cdhash_cmp(rat1->num, rat2->num) || cdhash_cmp(rat1->den, rat2->den);
 | 
			
		||||
        return rb_iseq_cdhash_cmp(rat1->num, rat2->num) || rb_iseq_cdhash_cmp(rat1->den, rat2->den);
 | 
			
		||||
    }
 | 
			
		||||
    else if (tlit == T_COMPLEX) {
 | 
			
		||||
        const struct RComplex *comp1 = RCOMPLEX(val);
 | 
			
		||||
        const struct RComplex *comp2 = RCOMPLEX(lit);
 | 
			
		||||
        return cdhash_cmp(comp1->real, comp2->real) || cdhash_cmp(comp1->imag, comp2->imag);
 | 
			
		||||
        return rb_iseq_cdhash_cmp(comp1->real, comp2->real) || rb_iseq_cdhash_cmp(comp1->imag, comp2->imag);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        UNREACHABLE_RETURN(-1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static st_index_t
 | 
			
		||||
cdhash_hash(VALUE a)
 | 
			
		||||
st_index_t
 | 
			
		||||
rb_iseq_cdhash_hash(VALUE a)
 | 
			
		||||
{
 | 
			
		||||
    switch (OBJ_BUILTIN_TYPE(a)) {
 | 
			
		||||
      case -1:
 | 
			
		||||
| 
						 | 
				
			
			@ -2039,8 +2039,8 @@ cdhash_hash(VALUE a)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static const struct st_hash_type cdhash_type = {
 | 
			
		||||
    cdhash_cmp,
 | 
			
		||||
    cdhash_hash,
 | 
			
		||||
    rb_iseq_cdhash_cmp,
 | 
			
		||||
    rb_iseq_cdhash_hash,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct cdhash_set_label_struct {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,8 @@ int rb_dvar_defined(ID, const struct rb_iseq_struct *);
 | 
			
		|||
int rb_local_defined(ID, const struct rb_iseq_struct *);
 | 
			
		||||
const char *rb_insns_name(int i);
 | 
			
		||||
VALUE rb_insns_name_array(void);
 | 
			
		||||
int rb_iseq_cdhash_cmp(VALUE val, VALUE lit);
 | 
			
		||||
st_index_t rb_iseq_cdhash_hash(VALUE a);
 | 
			
		||||
 | 
			
		||||
/* iseq.c */
 | 
			
		||||
int rb_vm_insn_addr2insn(const void *);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										34
									
								
								parse.y
									
										
									
									
									
								
							
							
						
						
									
										34
									
								
								parse.y
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -12184,10 +12184,42 @@ append_literal_keys(st_data_t k, st_data_t v, st_data_t h)
 | 
			
		|||
    return ST_CONTINUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
hash_literal_key_p(VALUE k)
 | 
			
		||||
{
 | 
			
		||||
    switch (OBJ_BUILTIN_TYPE(k)) {
 | 
			
		||||
      case T_NODE:
 | 
			
		||||
      case T_REGEXP:
 | 
			
		||||
	return false;
 | 
			
		||||
      default:
 | 
			
		||||
	return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
literal_cmp(VALUE val, VALUE lit)
 | 
			
		||||
{
 | 
			
		||||
    if (val == lit) return 0;
 | 
			
		||||
    if (!hash_literal_key_p(val) || !hash_literal_key_p(lit)) return -1;
 | 
			
		||||
    return rb_iseq_cdhash_cmp(val, lit);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static st_index_t
 | 
			
		||||
literal_hash(VALUE a)
 | 
			
		||||
{
 | 
			
		||||
    if (!hash_literal_key_p(a)) return (st_index_t)a;
 | 
			
		||||
    return rb_iseq_cdhash_hash(a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct st_hash_type literal_type = {
 | 
			
		||||
    literal_cmp,
 | 
			
		||||
    literal_hash,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static NODE *
 | 
			
		||||
remove_duplicate_keys(struct parser_params *p, NODE *hash)
 | 
			
		||||
{
 | 
			
		||||
    st_table *literal_keys = st_init_numtable_with_size(hash->nd_alen / 2);
 | 
			
		||||
    st_table *literal_keys = st_init_table_with_size(&literal_type, hash->nd_alen / 2);
 | 
			
		||||
    NODE *result = 0;
 | 
			
		||||
    rb_code_location_t loc = hash->nd_loc;
 | 
			
		||||
    while (hash && hash->nd_head && hash->nd_next) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -480,6 +480,10 @@ class TestRubyLiteral < Test::Unit::TestCase
 | 
			
		|||
      '"a"',
 | 
			
		||||
      '1000',
 | 
			
		||||
      '1.0',
 | 
			
		||||
      '1_000_000_000_000_000_000_000',
 | 
			
		||||
      '1.0r',
 | 
			
		||||
      '1.0i',
 | 
			
		||||
      '1.72723e-77',
 | 
			
		||||
    ) do |key|
 | 
			
		||||
      assert_warning(/key #{Regexp.quote(eval(key).inspect)} is duplicated/) do
 | 
			
		||||
        eval("{#{key} => :bar, #{key} => :foo}")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue