123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- /*
- * (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
|