+2003-12-19 Erik Petrich <epetrich@ivorytower.norman.ok.us>
+
+ * support/Util/SDCCerr.c,
+ * src/SDCCast.h,
+ * src/SDCCast.c (createCase, createDefault, decorateType),
+ * src/SDCClabel.c (labelUnreach),
+ * src/SDCC.y (labeled_statement, jump_statement): More improvements
+ to error messages.
+ * support/Util/SDCCerr.c (werrorfl): fixed a non-standard declaration
+ (with thanks to Stas Sergeev)
+ * device/include/time.h,
+ * device/lib/time.c (CheckTime): suppress unreachable code warning
+
2003-12-18 Erik Petrich <epetrich@ivorytower.norman.ok.us>
* src/SDCCast.c (createIvalCharPtr),
#ifndef TIME_H
#define TIME_H
-#if 1
+#ifndef __TIME_UNSIGNED
+#define __TIME_UNSIGNED 1
+#endif
+
+#if __TIME_UNSIGNED
struct tm
{
unsigned char tm_sec; /* Seconds. [0-60] */
static void CheckTime(struct tm *timeptr) {
// we could do some normalization here, e.g.
// change 40 october to 9 november
+ #if !__TIME_UNSIGNED
if (timeptr->tm_sec<0) timeptr->tm_sec=0;
- else if (timeptr->tm_sec>59) timeptr->tm_sec=59;
if (timeptr->tm_min<0) timeptr->tm_min=0;
- else if (timeptr->tm_min>59) timeptr->tm_min=59;
if (timeptr->tm_hour<0) timeptr->tm_hour=0;
- else if (timeptr->tm_hour>23) timeptr->tm_hour=23;
if (timeptr->tm_wday<0) timeptr->tm_wday=0;
- else if (timeptr->tm_wday>6) timeptr->tm_wday=6;
+ if (timeptr->tm_mon<0) timeptr->tm_mon=0;
+ #endif
+
+ if (timeptr->tm_sec>59) timeptr->tm_sec=59;
+ if (timeptr->tm_min>59) timeptr->tm_min=59;
+ if (timeptr->tm_hour>23) timeptr->tm_hour=23;
+ if (timeptr->tm_wday>6) timeptr->tm_wday=6;
if (timeptr->tm_mday<1) timeptr->tm_mday=1;
else if (timeptr->tm_mday>31) timeptr->tm_mday=31;
- if (timeptr->tm_mon<0) timeptr->tm_mon=0;
- else if (timeptr->tm_mon>11) timeptr->tm_mon=11;
+ if (timeptr->tm_mon>11) timeptr->tm_mon=11;
if (timeptr->tm_year<0) timeptr->tm_year=0;
}
labeled_statement
// : identifier ':' statement { $$ = createLabel($1,$3); }
: identifier ':' { $$ = createLabel($1,NULL); }
- | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
- | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
+ | CASE constant_expr ':' statement
+ {
+ if (STACK_EMPTY(swStk))
+ $$ = createCase(NULL,$2,$4);
+ else
+ $$ = createCase(STACK_PEEK(swStk),$2,$4);
+ }
+ | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':' statement
+ {
+ if (STACK_EMPTY(swStk))
+ $$ = createDefault(NULL,$<asts>2,$4);
+ else
+ $$ = createDefault(STACK_PEEK(swStk),$<asts>2,$4);
+ }
;
start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
}
| CONTINUE ';' {
/* make sure continue is in context */
- if (STACK_PEEK(continueStack) == NULL) {
+ if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
werror(E_BREAK_CONTEXT);
$$ = NULL;
}
}
}
| BREAK ';' {
- if (STACK_PEEK(breakStack) == NULL) {
+ if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
werror(E_BREAK_CONTEXT);
$$ = NULL;
} else {
if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
{
- werror (W_RETURN_MISMATCH);
+ werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
printFromToType (RTYPE(tree), currFunc->type->next);
goto errorTreeReturn;
}
&& tree->right &&
!IS_VOID (RTYPE (tree)))
{
- werror (E_FUNC_VOID);
+ werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
goto errorTreeReturn;
}
/* the switch value must be an integer */
if (!IS_INTEGRAL (LTYPE (tree)))
{
- werror (E_SWITCH_NON_INTEGER);
+ werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
goto errorTreeReturn;
}
LRVAL (tree) = 1;
/* then case is out of context */
if (!swStat)
{
- werror (E_CASE_CONTEXT);
+ werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
return NULL;
}
/* if not a constant then error */
if (!IS_LITERAL (caseVal->ftype))
{
- werror (E_CASE_CONSTANT);
+ werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
return NULL;
}
/* if not a integer than error */
if (!IS_INTEGRAL (caseVal->ftype))
{
- werror (E_CASE_NON_INTEGER);
+ werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
return NULL;
}
{
pval->next = caseVal->opval.val;
}
+ else if ((int) floatFromVal (val) == cVal)
+ {
+ werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
+ "case");
+ return NULL;
+ }
else
{
/* we found a value greater than */
/* createDefault - creates the parse tree for the default statement */
/*-----------------------------------------------------------------*/
ast *
-createDefault (ast * swStat, ast * stmnt)
+createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
{
char defLbl[SDCC_NAME_MAX + 1];
/* then case is out of context */
if (!swStat)
{
- werror (E_CASE_CONTEXT);
+ werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
+ return NULL;
+ }
+
+ if (swStat->values.switchVals.swDefault)
+ {
+ werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
+ "default");
return NULL;
}
ast *createBlock (symbol *, ast *);
ast *createLabel (symbol *, ast *);
ast *createCase (ast *, ast *, ast *);
-ast *createDefault (ast *, ast *);
+ast *createDefault (ast *, ast *, ast *);
ast *forLoopOptForm (ast *);
ast *argAst (ast *);
ast *resolveSymbols (ast *);
/* statement is not a label */
if (loop->op == GOTO || loop->op == RETURN)
{
+ int warn = 0;
if (loop->next &&
(loop->next->op == LABEL ||
hTabDeleteItem (&labelRef, IC_LABEL (tic)->key, tic, DELETE_ITEM, NULL);
break;
case IFX:
+ warn = 1;
if (IC_TRUE (tic))
hTabDeleteItem (&labelRef, IC_TRUE (tic)->key, tic, DELETE_ITEM, NULL);
else
hTabDeleteItem (&labelRef, IC_FALSE (tic)->key, tic, DELETE_ITEM, NULL);
break;
+ default:
+ warn = 1;
}
}
+ if (warn)
+ werrorfl (loop->next->filename, loop->next->lineno,
+ W_CODE_UNREACH);
+
/* now set up the pointers */
loop->next = loop2;
if (loop2)
{ E_ARG_COUNT, ERROR_LEVEL_ERROR,
"Function was expecting more arguments" },
{ E_FUNC_EXPECTED, ERROR_LEVEL_ERROR,
- "Function name expected '%s'.ANSI style declaration REQUIRED" },
+ "Function name expected '%s'. ANSI style declaration REQUIRED" },
{ E_PLUS_INVALID, ERROR_LEVEL_ERROR,
"invalid operand '%s'" },
{ E_PTR_PLUS_PTR, ERROR_LEVEL_ERROR,
{ E_BIT_ARRAY, ERROR_LEVEL_ERROR,
"Array or Pointer to bit|sbit|sfr not allowed.'%s'" },
{ E_DUPLICATE_TYPEDEF, ERROR_LEVEL_ERROR,
- "typedef/enum '%s' duplicate.Previous definiton Ignored" },
+ "typedef/enum '%s' duplicate. Previous definiton Ignored" },
{ E_ARG_TYPE, ERROR_LEVEL_ERROR,
"Actual Argument type different from declaration %d" },
{ E_RET_VALUE, ERROR_LEVEL_ERROR,
{ E_FUNC_DEF, ERROR_LEVEL_ERROR,
"ANSI Style declaration needed" },
{ E_DUPLICATE_LABEL, ERROR_LEVEL_ERROR,
- "Label name redefined '%s'" },
+ "Duplicate label '%s'" },
{ E_LABEL_UNDEF, ERROR_LEVEL_ERROR,
"Label undefined '%s'" },
{ E_FUNC_VOID, ERROR_LEVEL_ERROR,
{ W_RETURN_MISMATCH, ERROR_LEVEL_WARNING,
"function return value mismatch" },
{ E_CASE_CONTEXT, ERROR_LEVEL_ERROR,
- "'case/default' found without 'switch'.statement ignored" },
+ "'case/default' found without 'switch'. Statement ignored" },
{ E_CASE_CONSTANT, ERROR_LEVEL_ERROR,
- "'case' expression not constant. statement ignored" },
+ "'case' expression not constant. Statement ignored" },
{ E_BREAK_CONTEXT, ERROR_LEVEL_ERROR,
"'break/continue' statement out of context" },
{ E_SWITCH_AGGR, ERROR_LEVEL_ERROR,
{ E_INCOMPAT_TYPES, ERROR_LEVEL_ERROR,
"incompatible types" },
{ W_LOOP_ELIMINATE, ERROR_LEVEL_WARNING,
- "'while' loop with 'zero' constant.loop eliminated" },
+ "'while' loop with 'zero' constant. Loop eliminated" },
{ W_NO_SIDE_EFFECTS, ERROR_LEVEL_WARNING,
- "%s expression has NO side effects.expr eliminated" },
+ "%s expression has NO side effects. Expr eliminated" },
{ W_CONST_TOO_LARGE, ERROR_LEVEL_PEDANTIC,
"constant value '%s', out of range." },
{ W_BAD_COMPARE, ERROR_LEVEL_WARNING,
{
char *oldFilename = filename;
int oldLineno = lineno;
+ va_list marker;
filename = newFilename;
lineno = newLineno;
- va_list marker;
va_start(marker,errNum);
vwerror(errNum, marker);
va_end(marker);