reorganisation of lint code
This commit is contained in:
parent
fb854c82ff
commit
3d549e7932
8 changed files with 296 additions and 239 deletions
|
@ -418,6 +418,7 @@ ch7bin.o: botch_free.h
|
|||
ch7bin.o: expr.h
|
||||
ch7bin.o: idf.h
|
||||
ch7bin.o: label.h
|
||||
ch7bin.o: lint.h
|
||||
ch7bin.o: noRoption.h
|
||||
ch7bin.o: nobitfield.h
|
||||
ch7bin.o: nofloat.h
|
||||
|
@ -891,6 +892,10 @@ l_comment.o: arith.h
|
|||
l_comment.o: l_state.h
|
||||
l_comment.o: lint.h
|
||||
l_comment.o: spec_arith.h
|
||||
l_dummy.o: arith.h
|
||||
l_dummy.o: label.h
|
||||
l_dummy.o: lint.h
|
||||
l_dummy.o: spec_arith.h
|
||||
tokenfile.o: Lpars.h
|
||||
declar.o: LLlex.h
|
||||
declar.o: Lpars.h
|
||||
|
@ -946,7 +951,6 @@ expression.o: expr.h
|
|||
expression.o: file_info.h
|
||||
expression.o: idf.h
|
||||
expression.o: label.h
|
||||
expression.o: lint.h
|
||||
expression.o: noRoption.h
|
||||
expression.o: nobitfield.h
|
||||
expression.o: nofloat.h
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "botch_free.h"
|
||||
#include <alloc.h>
|
||||
#include "nofloat.h"
|
||||
#include "lint.h"
|
||||
#include "idf.h"
|
||||
#include "arith.h"
|
||||
#include "type.h"
|
||||
|
@ -65,6 +66,7 @@ ch7bin(expp, oper, expr)
|
|||
ch7bin(expp, '+', expr);
|
||||
ch7mon('*', expp);
|
||||
break;
|
||||
|
||||
case '(': /* RM 7.1 */
|
||||
if ( (*expp)->ex_type->tp_fund == POINTER &&
|
||||
(*expp)->ex_type->tp_up->tp_fund == FUNCTION
|
||||
|
@ -86,11 +88,13 @@ ch7bin(expp, oper, expr)
|
|||
*expp, '(', expr);
|
||||
(*expp)->ex_flags |= EX_SIDEEFFECTS;
|
||||
break;
|
||||
|
||||
case PARCOMMA: /* RM 7.1 */
|
||||
if ((*expp)->ex_type->tp_fund == FUNCTION)
|
||||
function2pointer(*expp);
|
||||
*expp = new_oper(expr->ex_type, *expp, PARCOMMA, expr);
|
||||
break;
|
||||
|
||||
case '%':
|
||||
case MODAB:
|
||||
case ANDAB:
|
||||
|
@ -105,6 +109,7 @@ ch7bin(expp, oper, expr)
|
|||
arithbalance(expp, oper, &expr);
|
||||
non_commutative_binop(expp, oper, expr);
|
||||
break;
|
||||
|
||||
case '&':
|
||||
case '^':
|
||||
case '|':
|
||||
|
@ -115,6 +120,7 @@ ch7bin(expp, oper, expr)
|
|||
arithbalance(expp, oper, &expr);
|
||||
commutative_binop(expp, oper, expr);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
if (expr->ex_type->tp_fund == POINTER) { /* swap operands */
|
||||
struct expr *etmp = expr;
|
||||
|
@ -139,6 +145,7 @@ ch7bin(expp, oper, expr)
|
|||
non_commutative_binop(expp, oper, expr);
|
||||
}
|
||||
break;
|
||||
|
||||
case '-':
|
||||
case MINAB:
|
||||
case POSTDECR:
|
||||
|
@ -156,6 +163,7 @@ ch7bin(expp, oper, expr)
|
|||
non_commutative_binop(expp, oper, expr);
|
||||
}
|
||||
break;
|
||||
|
||||
case LEFT:
|
||||
case RIGHT:
|
||||
case LEFTAB:
|
||||
|
@ -166,6 +174,7 @@ ch7bin(expp, oper, expr)
|
|||
ch7cast(&expr, oper, int_type); /* cvt. rightop to int */
|
||||
non_commutative_binop(expp, oper, expr);
|
||||
break;
|
||||
|
||||
case '<':
|
||||
case '>':
|
||||
case LESSEQ:
|
||||
|
@ -176,6 +185,7 @@ ch7bin(expp, oper, expr)
|
|||
non_commutative_binop(expp, oper, expr);
|
||||
(*expp)->ex_type = int_type;
|
||||
break;
|
||||
|
||||
case AND:
|
||||
case OR:
|
||||
opnd2test(expp, oper);
|
||||
|
@ -220,6 +230,7 @@ ch7bin(expp, oper, expr)
|
|||
*expp = new_oper(int_type, *expp, oper, expr);
|
||||
(*expp)->ex_flags |= EX_LOGICAL;
|
||||
break;
|
||||
|
||||
case ':':
|
||||
if ( is_struct_or_union((*expp)->ex_type->tp_fund)
|
||||
|| is_struct_or_union(expr->ex_type->tp_fund)
|
||||
|
@ -229,16 +240,30 @@ ch7bin(expp, oper, expr)
|
|||
}
|
||||
else
|
||||
relbalance(expp, oper, &expr);
|
||||
#ifdef LINT
|
||||
if ( (is_cp_cst(*expp) && is_cp_cst(expr))
|
||||
&& (*expp)->VL_VALUE == expr->VL_VALUE
|
||||
) {
|
||||
hwarning("operands of : are constant and equal");
|
||||
}
|
||||
#endif LINT
|
||||
*expp = new_oper((*expp)->ex_type, *expp, oper, expr);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
opnd2logical(expp, oper);
|
||||
if (is_cp_cst(*expp))
|
||||
if (is_cp_cst(*expp)) {
|
||||
#ifdef LINT
|
||||
hwarning("condition in ?: expression is constant");
|
||||
#endif LINT
|
||||
*expp = (*expp)->VL_VALUE ?
|
||||
expr->OP_LEFT : expr->OP_RIGHT;
|
||||
else
|
||||
}
|
||||
else {
|
||||
*expp = new_oper(expr->ex_type, *expp, oper, expr);
|
||||
}
|
||||
break;
|
||||
|
||||
case ',':
|
||||
if (is_cp_cst(*expp))
|
||||
*expp = expr;
|
||||
|
|
|
@ -225,7 +225,6 @@ initializer(struct idf *idf; int sc;)
|
|||
#endif DEBUG
|
||||
#ifdef LINT
|
||||
change_state(idf, SET);
|
||||
pre_lint_expr(expr, RVAL, USED);
|
||||
#endif LINT
|
||||
code_declaration(idf, expr, level, sc);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
/* EXPRESSION SYNTAX PARSER */
|
||||
|
||||
{
|
||||
#include "lint.h"
|
||||
#include "arith.h"
|
||||
#include "LLlex.h"
|
||||
#include "type.h"
|
||||
|
@ -208,10 +207,6 @@ conditional_expression(struct expr **expp;)
|
|||
#endif
|
||||
ch7bin(&e1, ':', e2);
|
||||
opnd2test(expp, '?');
|
||||
#ifdef LINT
|
||||
if (is_cp_cst(*expp))
|
||||
hwarning("condition in ?: is constant");
|
||||
#endif LINT
|
||||
ch7bin(expp, '?', e1);
|
||||
}
|
||||
]?
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
/*
|
||||
*The following functions are hacked to null-functions (i.e. they
|
||||
* do nothing). This needs another solution in the future.
|
||||
*/
|
||||
#include "lint.h"
|
||||
|
||||
#ifdef LINT
|
||||
#ifdef LINT
|
||||
|
||||
#include "arith.h"
|
||||
#include "label.h"
|
||||
|
@ -65,4 +71,4 @@ CC_psdnam(ps_xxx,s) char *s; {}
|
|||
CC_pspnam(ps_xxx,s) char *s; {}
|
||||
/* ARGSUSED */
|
||||
CC_scon(v,s) char *s; {}
|
||||
#endif LINT
|
||||
#endif LINT
|
||||
|
|
|
@ -29,7 +29,9 @@
|
|||
extern char options[128];
|
||||
extern char *symbol2str();
|
||||
|
||||
struct expr_state *lint_expr();
|
||||
static struct expr_state *lint_expr();
|
||||
static struct expr_state *lint_value();
|
||||
static struct expr_state *lint_oper();
|
||||
|
||||
lint_init()
|
||||
{
|
||||
|
@ -44,6 +46,8 @@ lint_init()
|
|||
|
||||
pre_lint_expr(expr, val, used)
|
||||
struct expr *expr;
|
||||
int val; /* LVAL or RVAL */
|
||||
int used;
|
||||
{
|
||||
/* Introduced to dispose the returned expression states */
|
||||
|
||||
|
@ -65,9 +69,11 @@ free_expr_states(esp)
|
|||
}
|
||||
}
|
||||
|
||||
struct expr_state *
|
||||
static struct expr_state *
|
||||
lint_expr(expr, val, used)
|
||||
register struct expr *expr;
|
||||
int val;
|
||||
int used;
|
||||
{
|
||||
/* Main function to process an expression tree.
|
||||
* It returns a structure containing information about which variables
|
||||
|
@ -77,217 +83,232 @@ lint_expr(expr, val, used)
|
|||
* If the value of an operation without side-effects is not used,
|
||||
* a warning is given.
|
||||
*/
|
||||
struct expr_state *esp1 = 0, *esp2 = 0;
|
||||
|
||||
if (used == IGNORED) {
|
||||
expr_ignored(expr);
|
||||
}
|
||||
|
||||
switch (expr->ex_class) {
|
||||
case Value:
|
||||
switch (expr->VL_CLASS) {
|
||||
case Const:
|
||||
case Label:
|
||||
return(0);
|
||||
|
||||
case Name:
|
||||
{
|
||||
register struct idf *idf = expr->VL_IDF;
|
||||
|
||||
if (!idf || !idf->id_def)
|
||||
return(0);
|
||||
|
||||
if ( val == LVAL
|
||||
|| ( val == RVAL
|
||||
&& expr->ex_type->tp_fund == POINTER
|
||||
&& !expr->ex_lvalue
|
||||
)
|
||||
) {
|
||||
change_state(idf, SET);
|
||||
idf->id_def->df_file =
|
||||
Salloc(dot.tk_file,
|
||||
strlen(dot.tk_file) + 1);
|
||||
idf->id_def->df_line = dot.tk_line;
|
||||
}
|
||||
if (val == RVAL) {
|
||||
change_state(idf, USED);
|
||||
add_expr_state(expr->EX_VALUE, USED, &esp1);
|
||||
}
|
||||
return(esp1);
|
||||
}
|
||||
|
||||
default:
|
||||
crash("(lint_expr) bad value class\n");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
return lint_value(expr, val);
|
||||
|
||||
case Oper:
|
||||
return lint_oper(expr, val, used);
|
||||
|
||||
default: /* String Float Type */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static struct expr_state *
|
||||
lint_value(expr, val)
|
||||
register struct expr *expr;
|
||||
{
|
||||
switch (expr->VL_CLASS) {
|
||||
case Const:
|
||||
case Label:
|
||||
return 0;
|
||||
|
||||
case Name:
|
||||
{
|
||||
register int oper = expr->OP_OPER;
|
||||
register struct expr *left = expr->OP_LEFT;
|
||||
register struct expr *right = expr->OP_RIGHT;
|
||||
register struct idf *idf = expr->VL_IDF;
|
||||
struct expr_state *esp1 = 0;
|
||||
|
||||
switch (oper) {
|
||||
case '=':
|
||||
case PLUSAB:
|
||||
case MINAB:
|
||||
case TIMESAB:
|
||||
case DIVAB:
|
||||
case MODAB:
|
||||
case LEFTAB:
|
||||
case RIGHTAB:
|
||||
case ANDAB:
|
||||
case XORAB:
|
||||
case ORAB:
|
||||
lint_conversion(oper, right->ex_type, left->ex_type);
|
||||
/* for cases like i += l; */
|
||||
esp1 = lint_expr(right, RVAL, USED);
|
||||
if (oper != '=') {
|
||||
/* i += 1; is interpreted as i = i + 1; */
|
||||
esp2 = lint_expr(left, RVAL, USED);
|
||||
check_and_merge(&esp1, esp2, oper);
|
||||
}
|
||||
esp2 = lint_expr(left, LVAL, USED);
|
||||
/* for cases like i = i + 1; and i not set, this
|
||||
** order is essential
|
||||
*/
|
||||
check_and_merge(&esp1, esp2, oper);
|
||||
if ( left->ex_class == Value
|
||||
&& left->VL_CLASS == Name
|
||||
) {
|
||||
add_expr_state(left->EX_VALUE, SET, &esp1);
|
||||
}
|
||||
return(esp1);
|
||||
if (!idf || !idf->id_def)
|
||||
return 0;
|
||||
|
||||
case POSTINCR:
|
||||
case POSTDECR:
|
||||
case PLUSPLUS:
|
||||
case MINMIN:
|
||||
/* i++; is parsed as i = i + 1;
|
||||
* This isn't quite correct :
|
||||
* The first statement doesn't USE i,
|
||||
* the second does.
|
||||
*/
|
||||
esp1 = lint_expr(left, RVAL, USED);
|
||||
esp2 = lint_expr(left, LVAL, USED);
|
||||
check_and_merge(&esp1, esp2, oper);
|
||||
if ( left->ex_class == Value
|
||||
&& left->VL_CLASS == Name
|
||||
) {
|
||||
add_expr_state(left->EX_VALUE, SET, &esp1);
|
||||
add_expr_state(left->EX_VALUE, USED, &esp1);
|
||||
}
|
||||
return(esp1);
|
||||
|
||||
case '-':
|
||||
case '*':
|
||||
if (left == 0) /* unary */
|
||||
return(lint_expr(right, RVAL, USED));
|
||||
esp1 = lint_expr(left, RVAL, USED);
|
||||
esp2 = lint_expr(right, RVAL, USED);
|
||||
check_and_merge(&esp1, esp2, oper);
|
||||
return(esp1);
|
||||
|
||||
case '(':
|
||||
if (right != 0) {
|
||||
/* function call with parameters */
|
||||
register struct expr *ex = right;
|
||||
|
||||
while ( ex->ex_class == Oper
|
||||
&& ex->OP_OPER == PARCOMMA
|
||||
) {
|
||||
esp2 = lint_expr(ex->OP_RIGHT, RVAL,
|
||||
USED);
|
||||
check_and_merge(&esp1, esp2, oper);
|
||||
ex = ex->OP_LEFT;
|
||||
}
|
||||
esp2 = lint_expr(ex, RVAL, USED);
|
||||
check_and_merge(&esp1, esp2, oper);
|
||||
}
|
||||
if ( left->ex_class == Value
|
||||
&& left->VL_CLASS == Name
|
||||
) {
|
||||
fill_outcall(expr,
|
||||
expr->ex_type->tp_fund == VOID ?
|
||||
VOIDED : used
|
||||
);
|
||||
outcall();
|
||||
left->VL_IDF->id_def->df_used = 1;
|
||||
}
|
||||
else {
|
||||
esp2 = lint_expr(left, val, USED);
|
||||
check_and_merge(&esp1, esp2, oper);
|
||||
}
|
||||
return(esp1);
|
||||
|
||||
case '.':
|
||||
return(lint_expr(left, val, USED));
|
||||
|
||||
case ARROW:
|
||||
return(lint_expr(left, RVAL, USED));
|
||||
|
||||
case '~':
|
||||
case '!':
|
||||
return(lint_expr(right, RVAL, USED));
|
||||
|
||||
case '?':
|
||||
esp1 = lint_expr(left, RVAL, USED);
|
||||
esp2 = lint_expr(right->OP_LEFT, RVAL, USED);
|
||||
check_and_merge(&esp1, esp2, 0);
|
||||
esp2 = lint_expr(right->OP_RIGHT, RVAL, USED);
|
||||
check_and_merge(&esp1, esp2, 0);
|
||||
return(esp1);
|
||||
|
||||
case INT2INT:
|
||||
case INT2FLOAT:
|
||||
case FLOAT2INT:
|
||||
case FLOAT2FLOAT:
|
||||
lint_conversion(oper, right->ex_type, left->ex_type);
|
||||
return(lint_expr(right, RVAL, USED));
|
||||
|
||||
case '<':
|
||||
case '>':
|
||||
case LESSEQ:
|
||||
case GREATEREQ:
|
||||
case EQUAL:
|
||||
case NOTEQUAL:
|
||||
lint_relop(left, right, oper);
|
||||
lint_relop(right, left,
|
||||
oper == '<' ? '>' :
|
||||
oper == '>' ? '<' :
|
||||
oper == LESSEQ ? GREATEREQ :
|
||||
oper == GREATEREQ ? LESSEQ :
|
||||
oper
|
||||
);
|
||||
/*FALLTHROUGH*/
|
||||
case '+':
|
||||
case '/':
|
||||
case '%':
|
||||
case ',':
|
||||
case LEFT:
|
||||
case RIGHT:
|
||||
case '&':
|
||||
case '|':
|
||||
case '^':
|
||||
case OR:
|
||||
case AND:
|
||||
esp1 = lint_expr(left, RVAL,
|
||||
oper == ',' ? IGNORED : USED);
|
||||
esp2 = lint_expr(right, RVAL,
|
||||
oper == ',' ? used : USED);
|
||||
if (oper == OR || oper == AND || oper == ',')
|
||||
check_and_merge(&esp1, esp2, 0);
|
||||
else
|
||||
check_and_merge(&esp1, esp2, oper);
|
||||
return(esp1);
|
||||
|
||||
default:
|
||||
return(0); /* for initcomma */
|
||||
if ( val == LVAL
|
||||
|| ( val == RVAL
|
||||
&& expr->ex_type->tp_fund == POINTER
|
||||
&& !expr->ex_lvalue
|
||||
)
|
||||
) {
|
||||
change_state(idf, SET);
|
||||
idf->id_def->df_file =
|
||||
Salloc(dot.tk_file,
|
||||
strlen(dot.tk_file) + 1);
|
||||
idf->id_def->df_line = dot.tk_line;
|
||||
}
|
||||
if (val == RVAL) {
|
||||
change_state(idf, USED);
|
||||
add_expr_state(expr->EX_VALUE, USED, &esp1);
|
||||
}
|
||||
return esp1;
|
||||
}
|
||||
|
||||
default:
|
||||
return(0);
|
||||
crash("(lint_expr) bad value class\n");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
static struct expr_state *
|
||||
lint_oper(expr, val, used)
|
||||
struct expr *expr;
|
||||
int val;
|
||||
int used;
|
||||
{
|
||||
register int oper = expr->OP_OPER;
|
||||
register struct expr *left = expr->OP_LEFT;
|
||||
register struct expr *right = expr->OP_RIGHT;
|
||||
struct expr_state *esp1 = 0;
|
||||
struct expr_state *esp2 = 0;
|
||||
|
||||
switch (oper) {
|
||||
case '=':
|
||||
case PLUSAB:
|
||||
case MINAB:
|
||||
case TIMESAB:
|
||||
case DIVAB:
|
||||
case MODAB:
|
||||
case LEFTAB:
|
||||
case RIGHTAB:
|
||||
case ANDAB:
|
||||
case XORAB:
|
||||
case ORAB:
|
||||
lint_conversion(oper, right->ex_type, left->ex_type);
|
||||
/* for cases like i += l; */
|
||||
esp1 = lint_expr(right, RVAL, USED);
|
||||
if (oper != '=') {
|
||||
/* i += 1; is interpreted as i = i + 1; */
|
||||
esp2 = lint_expr(left, RVAL, USED);
|
||||
check_and_merge(&esp1, esp2, oper);
|
||||
}
|
||||
esp2 = lint_expr(left, LVAL, USED);
|
||||
/* for cases like i = i + 1; and i not set, this
|
||||
** order is essential
|
||||
*/
|
||||
check_and_merge(&esp1, esp2, oper);
|
||||
if ( left->ex_class == Value
|
||||
&& left->VL_CLASS == Name
|
||||
) {
|
||||
add_expr_state(left->EX_VALUE, SET, &esp1);
|
||||
}
|
||||
return esp1;
|
||||
|
||||
case POSTINCR:
|
||||
case POSTDECR:
|
||||
case PLUSPLUS:
|
||||
case MINMIN:
|
||||
/* i++; is parsed as i = i + 1;
|
||||
* This isn't quite correct :
|
||||
* The first statement doesn't USE i,
|
||||
* the second does.
|
||||
*/
|
||||
esp1 = lint_expr(left, RVAL, USED);
|
||||
esp2 = lint_expr(left, LVAL, USED);
|
||||
check_and_merge(&esp1, esp2, oper);
|
||||
if ( left->ex_class == Value
|
||||
&& left->VL_CLASS == Name
|
||||
) {
|
||||
add_expr_state(left->EX_VALUE, SET, &esp1);
|
||||
add_expr_state(left->EX_VALUE, USED, &esp1);
|
||||
}
|
||||
return esp1;
|
||||
|
||||
case '-':
|
||||
case '*':
|
||||
if (left == 0) /* unary */
|
||||
return lint_expr(right, RVAL, USED);
|
||||
esp1 = lint_expr(left, RVAL, USED);
|
||||
esp2 = lint_expr(right, RVAL, USED);
|
||||
check_and_merge(&esp1, esp2, oper);
|
||||
return esp1;
|
||||
|
||||
case '(':
|
||||
if (right != 0) {
|
||||
/* function call with parameters */
|
||||
register struct expr *ex = right;
|
||||
|
||||
while ( ex->ex_class == Oper
|
||||
&& ex->OP_OPER == PARCOMMA
|
||||
) {
|
||||
esp2 = lint_expr(ex->OP_RIGHT, RVAL,
|
||||
USED);
|
||||
check_and_merge(&esp1, esp2, oper);
|
||||
ex = ex->OP_LEFT;
|
||||
}
|
||||
esp2 = lint_expr(ex, RVAL, USED);
|
||||
check_and_merge(&esp1, esp2, oper);
|
||||
}
|
||||
if ( left->ex_class == Value
|
||||
&& left->VL_CLASS == Name
|
||||
) {
|
||||
fill_outcall(expr,
|
||||
expr->ex_type->tp_fund == VOID ?
|
||||
VOIDED : used
|
||||
);
|
||||
outcall();
|
||||
left->VL_IDF->id_def->df_used = 1;
|
||||
}
|
||||
else {
|
||||
esp2 = lint_expr(left, val, USED);
|
||||
check_and_merge(&esp1, esp2, oper);
|
||||
}
|
||||
return esp1;
|
||||
|
||||
case '.':
|
||||
return lint_expr(left, val, USED);
|
||||
|
||||
case ARROW:
|
||||
return lint_expr(left, RVAL, USED);
|
||||
|
||||
case '~':
|
||||
case '!':
|
||||
return lint_expr(right, RVAL, USED);
|
||||
|
||||
case '?':
|
||||
esp1 = lint_expr(left, RVAL, USED);
|
||||
esp2 = lint_expr(right->OP_LEFT, RVAL, USED);
|
||||
check_and_merge(&esp1, esp2, 0);
|
||||
esp2 = lint_expr(right->OP_RIGHT, RVAL, USED);
|
||||
check_and_merge(&esp1, esp2, 0);
|
||||
return esp1;
|
||||
|
||||
case INT2INT:
|
||||
case INT2FLOAT:
|
||||
case FLOAT2INT:
|
||||
case FLOAT2FLOAT:
|
||||
lint_conversion(oper, right->ex_type, left->ex_type);
|
||||
return lint_expr(right, RVAL, USED);
|
||||
|
||||
case '<':
|
||||
case '>':
|
||||
case LESSEQ:
|
||||
case GREATEREQ:
|
||||
case EQUAL:
|
||||
case NOTEQUAL:
|
||||
lint_relop(left, right, oper);
|
||||
lint_relop(right, left,
|
||||
oper == '<' ? '>' :
|
||||
oper == '>' ? '<' :
|
||||
oper == LESSEQ ? GREATEREQ :
|
||||
oper == GREATEREQ ? LESSEQ :
|
||||
oper
|
||||
);
|
||||
/*FALLTHROUGH*/
|
||||
case '+':
|
||||
case '/':
|
||||
case '%':
|
||||
case ',':
|
||||
case LEFT:
|
||||
case RIGHT:
|
||||
case '&':
|
||||
case '|':
|
||||
case '^':
|
||||
case OR:
|
||||
case AND:
|
||||
esp1 = lint_expr(left, RVAL,
|
||||
oper == ',' ? IGNORED : USED);
|
||||
esp2 = lint_expr(right, RVAL,
|
||||
oper == ',' ? used : USED);
|
||||
if (oper == OR || oper == AND || oper == ',')
|
||||
check_and_merge(&esp1, esp2, 0);
|
||||
else
|
||||
check_and_merge(&esp1, esp2, oper);
|
||||
return esp1;
|
||||
|
||||
default:
|
||||
return 0; /* for initcomma */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -340,8 +361,7 @@ expr_ignored(expr)
|
|||
hwarning("identifier as statement");
|
||||
break;
|
||||
|
||||
case String:
|
||||
case Float:
|
||||
default: /* String Float */
|
||||
hwarning("constant as statement");
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -365,7 +365,7 @@ copy_st_auto_list(from_al, lvl)
|
|||
from_al = from_al->next;
|
||||
}
|
||||
|
||||
return(start);
|
||||
return start;
|
||||
}
|
||||
|
||||
free_st_auto_list(au)
|
||||
|
@ -392,7 +392,7 @@ copy_state(from_st, lvl)
|
|||
st->st_auto_list = copy_st_auto_list(from_st->st_auto_list, lvl);
|
||||
st->st_notreached = from_st->st_notreached;
|
||||
st->st_warned = from_st->st_warned;
|
||||
return(st);
|
||||
return st;
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -497,7 +497,7 @@ merge_autos(a1, a2, lvl, mode)
|
|||
crash("(merge_autos) a2 longer than a1");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
return(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
merge_states(st1, st2, lvl, mode)
|
||||
|
@ -547,14 +547,15 @@ find_wdf()
|
|||
register struct lint_stack_entry *lse = top_ls;
|
||||
|
||||
while (lse != &stack_bottom) {
|
||||
switch (lse->ls_class)
|
||||
switch (lse->ls_class) {
|
||||
case WHILE:
|
||||
case DO:
|
||||
case FOR:
|
||||
return(lse);
|
||||
return lse;
|
||||
}
|
||||
lse = lse->ls_previous;
|
||||
}
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct lint_stack_entry *
|
||||
|
@ -563,15 +564,16 @@ find_wdfc()
|
|||
register struct lint_stack_entry *lse = top_ls;
|
||||
|
||||
while (lse != &stack_bottom) {
|
||||
switch (lse->ls_class)
|
||||
switch (lse->ls_class) {
|
||||
case WHILE:
|
||||
case DO:
|
||||
case FOR:
|
||||
case CASE:
|
||||
return(lse);
|
||||
return lse;
|
||||
}
|
||||
lse = lse->ls_previous;
|
||||
}
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct lint_stack_entry *
|
||||
|
@ -580,24 +582,28 @@ find_cs()
|
|||
register struct lint_stack_entry *lse = top_ls;
|
||||
|
||||
while (lse != &stack_bottom) {
|
||||
switch (lse->ls_class)
|
||||
switch (lse->ls_class) {
|
||||
case CASE:
|
||||
case SWITCH:
|
||||
return(lse);
|
||||
return lse;
|
||||
}
|
||||
lse = lse->ls_previous;
|
||||
}
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******** A C T I O N S ********/
|
||||
|
||||
start_if_part()
|
||||
start_if_part(const)
|
||||
{
|
||||
/* Push a new stack entry on the lint_stack with class == IF
|
||||
* copy the ls_current to the top of this stack
|
||||
*/
|
||||
register struct lint_stack_entry *lse = new_lint_stack_entry();
|
||||
|
||||
if (const)
|
||||
hwarning("condition in if statement is constant");
|
||||
|
||||
lse->ls_class = IF;
|
||||
lse->ls_current = copy_state(top_ls->ls_current, level);
|
||||
lse->ls_level = level;
|
||||
|
@ -685,7 +691,7 @@ end_do_stmt(const, cond)
|
|||
{
|
||||
end_loop_stmt();
|
||||
if (const)
|
||||
hwarning("constant do condition");
|
||||
hwarning("condition in do-while statement is constant");
|
||||
if (const && cond && top_ls->ls_current->st_notreached) {
|
||||
/* no break met; this is really an endless loop */
|
||||
}
|
||||
|
@ -718,7 +724,8 @@ lint_continue_stmt()
|
|||
top_ls->ls_current->st_notreached = 1;
|
||||
}
|
||||
|
||||
start_switch_part()
|
||||
start_switch_part(expr)
|
||||
struct expr *expr;
|
||||
{
|
||||
/* ls_current of a SWITCH entry has different meaning from ls_current of
|
||||
* other entries. It keeps track of which variables are used in all
|
||||
|
@ -727,6 +734,13 @@ start_switch_part()
|
|||
*/
|
||||
register struct lint_stack_entry *lse = new_lint_stack_entry();
|
||||
|
||||
/* the following is a trick to detect a constant
|
||||
* expression in a switch
|
||||
*/
|
||||
opnd2test(&expr, SWITCH);
|
||||
if (is_cp_cst(expr))
|
||||
hwarning("value in switch statement is constant");
|
||||
|
||||
lse->ls_class = SWITCH;
|
||||
lse->ls_current = copy_state(top_ls->ls_current, level);
|
||||
lse->ls_level = level;
|
||||
|
|
|
@ -144,22 +144,22 @@ if_statement
|
|||
/* The comparison has been optimized
|
||||
to a 0 or 1.
|
||||
*/
|
||||
#ifdef LINT
|
||||
hwarning("condition in if is constant");
|
||||
#endif LINT
|
||||
if (expr->VL_VALUE == (arith)0) {
|
||||
C_bra(l_false);
|
||||
}
|
||||
/* else fall through */
|
||||
#ifdef LINT
|
||||
start_if_part(1);
|
||||
#endif LINT
|
||||
}
|
||||
else {
|
||||
code_expr(expr, RVAL, TRUE, l_true, l_false);
|
||||
C_df_ilb(l_true);
|
||||
#ifdef LINT
|
||||
start_if_part(0);
|
||||
#endif LINT
|
||||
}
|
||||
free_expression(expr);
|
||||
#ifdef LINT
|
||||
start_if_part();
|
||||
#endif LINT
|
||||
}
|
||||
')'
|
||||
statement
|
||||
|
@ -363,13 +363,7 @@ switch_statement
|
|||
{
|
||||
code_startswitch(&expr);
|
||||
#ifdef LINT
|
||||
start_switch_part();
|
||||
/* the following is a trick to detect a constant
|
||||
* expression in a switch
|
||||
*/
|
||||
opnd2test(&expr, SWITCH);
|
||||
if (is_cp_cst(expr))
|
||||
hwarning("switch value is constant");
|
||||
start_switch_part(expr);
|
||||
#endif LINT
|
||||
}
|
||||
')'
|
||||
|
|
Loading…
Reference in a new issue