ack/lang/cem/cemcom/l_misc.c

156 lines
2.9 KiB
C

/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* Lint miscellaneous routines */
#include "lint.h"
#ifdef LINT
#include <alloc.h> /* for st_free */
#include "arith.h" /* definition arith */
#include "label.h" /* definition label */
#include "expr.h"
#include "idf.h"
#include "def.h"
#include "code.h" /* RVAL etc */
#include "LLlex.h"
#include "Lpars.h"
#include "stack.h"
#include "type.h"
#include "level.h"
#include "nofloat.h"
#include "l_state.h"
extern char *symbol2str();
extern struct type *func_type;
lint_conversion(oper, from_type, to_type)
struct type *from_type, *to_type;
{
register int from = from_type->tp_fund;
register int to = to_type->tp_fund;
switch (oper) {
case RETURN: /* not really an oper, but it works */
case INT2INT:
case '=':
case PLUSAB:
case MINAB:
case TIMESAB:
case DIVAB:
case MODAB:
case LEFTAB:
case RIGHTAB:
case ANDAB:
case XORAB:
case ORAB:
if ( (from == LONG && to != LONG)
|| (from == DOUBLE && to != DOUBLE)
) {
awarning("conversion from %s to %s may lose accuracy",
symbol2str(from), symbol2str(to));
}
}
}
lint_ret_conv(from_type)
struct type *from_type;
{
lint_conversion(RETURN, from_type, func_type);
}
lint_ptr_conv(from, to)
short from, to;
{
/* X -> X ok -- this includes struct -> struct, of any size
* X -> CHAR ok
* DOUBLE -> X ok
* FLOAT -> LONG -> INT -> SHORT ok
*/
if (from == to)
return;
if (to == CHAR)
return;
if (from == DOUBLE)
return;
switch (from) {
case FLOAT:
switch (to) {
case LONG:
case INT:
case SHORT:
return;
}
break;
case LONG:
switch (to) {
case INT:
case SHORT:
return;
}
break;
case INT:
switch (to) {
case SHORT:
return;
}
break;
}
if (from == CHAR) {
hwarning("pointer to char may not align correctly for a %s",
symbol2str(to));
}
else {
warning("pointer to %s may not align correctly for a %s",
symbol2str(from), symbol2str(to));
}
}
lint_relop(left, right, oper)
struct expr *left, *right;
int oper; /* '<', '>', LESSEQ, GREATEREQ, EQUAL, NOTEQUAL */
{
/* <unsigned> <relop> <neg-const|0> is doubtful */
if ( left->ex_type->tp_unsigned
&& right->ex_class == Value
&& right->VL_CLASS == Const
) {
if (right->VL_VALUE < 0) {
warning("unsigned compared to negative constant");
}
if (right->VL_VALUE == 0) {
switch (oper) {
case '<':
warning("unsigned < 0 will always fail");
break;
case LESSEQ:
warning("unsigned <= 0 is probably wrong");
break;
case GREATEREQ:
warning("unsigned >= 0 will always succeed");
break;
}
}
}
/* <char> <relop> <neg-const> is undefined */
if ( left->ex_type->tp_fund == CHAR
&& right->ex_class == Value
&& right->VL_CLASS == Const
&& (right->VL_VALUE < 0 || right->VL_VALUE > 127)
) {
warning("character compared to negative constant");
}
}
#endif LINT