improved qualifier checking
This commit is contained in:
		
							parent
							
								
									c30769327b
								
							
						
					
					
						commit
						776233c718
					
				
					 3 changed files with 29 additions and 28 deletions
				
			
		| 
						 | 
				
			
			@ -170,6 +170,7 @@ ch3cast(expp, oper, tp)
 | 
			
		|||
		expression of class Type.
 | 
			
		||||
	*/
 | 
			
		||||
	register struct type *oldtp;
 | 
			
		||||
	int qual_lev;
 | 
			
		||||
 | 
			
		||||
	if (oper == RETURN && tp->tp_fund == VOID) {
 | 
			
		||||
		expr_strict(*expp, "return <expression> in function returning void");
 | 
			
		||||
| 
						 | 
				
			
			@ -195,8 +196,19 @@ ch3cast(expp, oper, tp)
 | 
			
		|||
	}
 | 
			
		||||
	else
 | 
			
		||||
#endif NOBITFIELD
 | 
			
		||||
	if (equal_type(tp, oldtp, oper != CAST)) {
 | 
			
		||||
	if (oper == CASTAB || oper == '=' || oper == RETURN) {
 | 
			
		||||
		qual_lev = -2;
 | 
			
		||||
	} else if (oper == CAST) qual_lev = -999;	/* ??? hack */
 | 
			
		||||
	else qual_lev = -1;
 | 
			
		||||
 | 
			
		||||
	if (equal_type(tp, oldtp, qual_lev)) {
 | 
			
		||||
		/* life is easy */
 | 
			
		||||
		if (qual_lev == -2 && tp->tp_fund == POINTER) {
 | 
			
		||||
			if ((tp->tp_up->tp_typequal & oldtp->tp_up->tp_typequal)
 | 
			
		||||
			    != oldtp->tp_up->tp_typequal) {
 | 
			
		||||
				expr_strict( *expp, "qualifier error");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		(*expp)->ex_type = tp;	/* so qualifiers are allright */
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
| 
						 | 
				
			
			@ -336,11 +348,11 @@ ch3cast(expp, oper, tp)
 | 
			
		|||
 | 
			
		||||
/*	Determine whether two types are equal.
 | 
			
		||||
*/
 | 
			
		||||
equal_type(tp, otp, check_qual)
 | 
			
		||||
equal_type(tp, otp, qual_lev)
 | 
			
		||||
	register struct type *tp, *otp;
 | 
			
		||||
	int check_qual;
 | 
			
		||||
	int qual_lev;
 | 
			
		||||
{
 | 
			
		||||
	if (tp == otp)
 | 
			
		||||
	 if (tp == otp)
 | 
			
		||||
		return 1;
 | 
			
		||||
	if (!tp
 | 
			
		||||
	    || !otp
 | 
			
		||||
| 
						 | 
				
			
			@ -352,6 +364,10 @@ equal_type(tp, otp, check_qual)
 | 
			
		|||
		if (tp->tp_size != otp->tp_size)
 | 
			
		||||
			return 0;
 | 
			
		||||
	}
 | 
			
		||||
	if (qual_lev >= 0) {
 | 
			
		||||
		if (tp->tp_typequal != otp->tp_typequal)
 | 
			
		||||
			strict("illegal qualifiers");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch (tp->tp_fund) {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -367,7 +383,7 @@ equal_type(tp, otp, check_qual)
 | 
			
		|||
			if (!legal_mixture(tp, otp))
 | 
			
		||||
				return 0;
 | 
			
		||||
		}
 | 
			
		||||
		return equal_type(tp->tp_up, otp->tp_up, 0);
 | 
			
		||||
		return equal_type(tp->tp_up, otp->tp_up, qual_lev + 1);
 | 
			
		||||
 | 
			
		||||
	case ARRAY:
 | 
			
		||||
		/*	If one type is an array of known size, the composite
 | 
			
		||||
| 
						 | 
				
			
			@ -376,28 +392,13 @@ equal_type(tp, otp, check_qual)
 | 
			
		|||
		if (tp->tp_size != otp->tp_size &&
 | 
			
		||||
		     (tp->tp_size != -1 && otp->tp_size != -1))
 | 
			
		||||
			return 0;
 | 
			
		||||
		return equal_type(tp->tp_up, otp->tp_up, check_qual);
 | 
			
		||||
		return equal_type(tp->tp_up, otp->tp_up, qual_lev); /* ??? +1 */
 | 
			
		||||
 | 
			
		||||
	case POINTER:
 | 
			
		||||
		if (equal_type(tp->tp_up, otp->tp_up, check_qual)) {
 | 
			
		||||
		    if (check_qual) {
 | 
			
		||||
			if (otp->tp_up->tp_typequal & TQ_CONST) {
 | 
			
		||||
			    if (!(tp->tp_up->tp_typequal & TQ_CONST)) {
 | 
			
		||||
				strict("illegal use of pointer to const object");
 | 
			
		||||
			    }
 | 
			
		||||
			}
 | 
			
		||||
			if (otp->tp_up->tp_typequal & TQ_VOLATILE) {
 | 
			
		||||
			    if (!(tp->tp_up->tp_typequal & TQ_VOLATILE)) {
 | 
			
		||||
				strict("illegal use of pointer to volatile object");
 | 
			
		||||
			    }
 | 
			
		||||
			}
 | 
			
		||||
		    }
 | 
			
		||||
		    return 1;
 | 
			
		||||
		}
 | 
			
		||||
		else return 0;
 | 
			
		||||
		return equal_type(tp->tp_up, otp->tp_up, qual_lev + 1);
 | 
			
		||||
 | 
			
		||||
	case FIELD:
 | 
			
		||||
		return equal_type(tp->tp_up, otp->tp_up, check_qual);
 | 
			
		||||
		return equal_type(tp->tp_up, otp->tp_up, qual_lev); /* ??? +1 */
 | 
			
		||||
 | 
			
		||||
	case STRUCT:
 | 
			
		||||
	case UNION:
 | 
			
		||||
| 
						 | 
				
			
			@ -426,7 +427,7 @@ check_pseudoproto(pl, opl)
 | 
			
		|||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	while (pl && opl) {
 | 
			
		||||
	    if (!equal_type(pl->pl_type, opl->pl_type, 0)) {
 | 
			
		||||
	    if (!equal_type(pl->pl_type, opl->pl_type, -1)) {
 | 
			
		||||
		if (!(pl->pl_flag & PL_ERRGIVEN)
 | 
			
		||||
		    && !(opl->pl_flag & PL_ERRGIVEN))
 | 
			
		||||
			error("incorrect type for parameter %s of definition",
 | 
			
		||||
| 
						 | 
				
			
			@ -500,7 +501,7 @@ equal_proto(pl, opl)
 | 
			
		|||
	while ( pl && opl) {
 | 
			
		||||
 | 
			
		||||
	    if ((pl->pl_flag & ~PL_ERRGIVEN) != (opl->pl_flag & ~PL_ERRGIVEN) ||
 | 
			
		||||
	        !equal_type(pl->pl_type, opl->pl_type, 0))
 | 
			
		||||
	        !equal_type(pl->pl_type, opl->pl_type, -1))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	    pl = pl->next;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -236,7 +236,7 @@ ch3bin(expp, oper, expr)
 | 
			
		|||
		if (	is_struct_or_union(expp_tp->tp_fund)
 | 
			
		||||
		||	is_struct_or_union(expr->ex_type->tp_fund)
 | 
			
		||||
		)	{
 | 
			
		||||
			if (!equal_type(expp_tp, expr->ex_type, 0))
 | 
			
		||||
			if (!equal_type(expp_tp, expr->ex_type, -1))
 | 
			
		||||
				expr_error(*expp, "illegal balance");
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
| 
						 | 
				
			
			@ -284,7 +284,7 @@ pntminuspnt(expp, oper, expr)
 | 
			
		|||
	*/
 | 
			
		||||
	struct type *up_type = (*expp)->ex_type->tp_up;
 | 
			
		||||
 | 
			
		||||
	if (!equal_type(up_type, expr->ex_type->tp_up, 0)) {
 | 
			
		||||
	if (!equal_type(up_type, expr->ex_type->tp_up, -1)) {
 | 
			
		||||
		expr_error(*expp, "subtracting incompatible pointers");
 | 
			
		||||
		free_expression(expr);
 | 
			
		||||
		erroneous2int(expp);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -610,7 +610,7 @@ check_formals(idf, dc)
 | 
			
		|||
		}
 | 
			
		||||
		while(fm && pl) {
 | 
			
		||||
		    if (!equal_type(promoted_type(fm->fm_idf->id_def->df_type)
 | 
			
		||||
					, pl->pl_type, 0)) {
 | 
			
		||||
					, pl->pl_type, -1)) {
 | 
			
		||||
			if (!(pl->pl_flag & PL_ERRGIVEN))
 | 
			
		||||
			    error("incorrect type for parameter %s"
 | 
			
		||||
						, fm->fm_idf->id_text);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue