/*
-** LCLint - annotation-assisted static program checker
-** Copyright (C) 1994-2001 University of Virginia,
+** Splint - annotation-assisted static program checker
+** Copyright (C) 1994-2002 University of Virginia,
** Massachusetts Institute of Technology
**
** This program is free software; you can redistribute it and/or modify it
**
** For information on lclint: lclint-request@cs.virginia.edu
** To report a bug: lclint-bug@cs.virginia.edu
-** For more information: http://lclint.cs.virginia.edu
+** For more information: http://www.splint.org
*/
/*
** mtContextNode.c
# include "lclintMacros.nf"
# include "basic.h"
-# include "mtgrammar.h"
static bool mtContextNode_matchesType (mtContextNode, ctype) /*@*/ ;
switch (ck)
{
case MTC_ANY: return cstring_makeLiteralTemp ("any");
- case MTC_PARAM: return cstring_makeLiteralTemp ("param");
+ case MTC_PARAM: return cstring_makeLiteralTemp ("parameter");
case MTC_RESULT: return cstring_makeLiteralTemp ("result");
case MTC_REFERENCE: return cstring_makeLiteralTemp ("reference");
case MTC_CLAUSE: return cstring_makeLiteralTemp ("clause");
+ case MTC_LITERAL: return cstring_makeLiteralTemp ("literal");
+ case MTC_NULL: return cstring_makeLiteralTemp ("null");
}
- BADBRANCH;
+ BADBRANCHRET (cstring_undefined);
}
static mtContextNode mtContextNode_create (mtContextKind context, ctype ct)
return mtContextNode_create (MTC_CLAUSE, ct);
}
+extern mtContextNode mtContextNode_createLiteral (ctype ct)
+{
+ return mtContextNode_create (MTC_LITERAL, ct);
+}
+
+extern mtContextNode mtContextNode_createNull (ctype ct)
+{
+ return mtContextNode_create (MTC_NULL, ct);
+}
+
extern void mtContextNode_free (/*@only@*/ mtContextNode node)
{
sfree (node);
}
break;
case MTC_PARAM:
- if (!uentry_isParam (ue))
+ if (!uentry_isAnyParam (ue))
{
+ DPRINTF (("not param: %s", uentry_unparseFull (ue)));
return FALSE;
}
break;
+ case MTC_LITERAL:
+ case MTC_NULL:
+ return FALSE;
case MTC_REFERENCE:
break;
case MTC_CLAUSE:
return FALSE;
}
break;
+ case MTC_LITERAL:
+ DPRINTF (("Literal: %s", sRef_unparse (sr)));
+ if (!sRef_isConst (sr))
+ {
+ return FALSE;
+ }
+ break;
+ case MTC_NULL:
case MTC_REFERENCE:
break;
case MTC_CLAUSE:
}
else
{
+ /* evans 2001-08-21 - don't match if only one type is unknown */
+ if (ctype_isUnknown (ct) && !ctype_isUnknown (context->type))
+ {
+ return FALSE;
+ }
+
DPRINTF (("Type okay: %s / %s",
ctype_unparse (context->type),
ctype_unparse (ct)));
return (n->context == MTC_RESULT);
}
+bool mtContextNode_isLiteral (mtContextNode n)
+{
+ llassert (mtContextNode_isDefined (n));
+ return (n->context == MTC_LITERAL);
+}
+
+bool mtContextNode_isNull (mtContextNode n)
+{
+ llassert (mtContextNode_isDefined (n));
+ return (n->context == MTC_NULL);
+}
+
+void mtContextNode_showRefError (mtContextNode context, sRef sr)
+{
+ ctype ct;
+
+ llassert (mtContextNode_isDefined (context));
+ llassert (!mtContextNode_matchesRef (context, sr));
+
+ DPRINTF (("Matches context: %s / %s",
+ mtContextNode_unparse (context), sRef_unparse (sr)));
+
+ switch (context->context)
+ {
+ case MTC_ANY: break; /* everything matches */
+ case MTC_RESULT:
+ if (!sRef_isResult (sr))
+ {
+ llgenindentmsgnoloc
+ (message ("Context is result, doesn't match %q", sRef_unparse (sr)));
+ return;
+ }
+ break;
+ case MTC_PARAM:
+ if (!sRef_isResult (sr))
+ {
+ llgenindentmsgnoloc
+ (message ("Context is parameter, doesn't match %q", sRef_unparse (sr)));
+ return;
+ }
+ break;
+ case MTC_LITERAL:
+ DPRINTF (("Literal: %s", sRef_unparse (sr)));
+ if (!sRef_isConst (sr))
+ {
+ llgenindentmsgnoloc
+ (message ("Context is literal, doesn't match %q", sRef_unparse (sr)));
+ return;
+ }
+ break;
+ case MTC_NULL:
+ case MTC_REFERENCE:
+ break;
+ case MTC_CLAUSE:
+ BADBRANCH;
+ }
+
+ ct = sRef_getType (sr);
+
+ if (!mtContextNode_matchesType (context, ct))
+ {
+ llgenindentmsgnoloc
+ (message ("Context type is %s, doesn't match type %s",
+ ctype_unparse (context->type),
+ ctype_unparse (ct)));
+ }
+ else
+ {
+ BADBRANCH;
+ }
+}