]> granicus.if.org Git - nethack/commitdiff
pacify static analyzer - dog.c
authorPatR <rankin@nethack.org>
Tue, 17 Jan 2023 18:42:00 +0000 (10:42 -0800)
committerPatR <rankin@nethack.org>
Tue, 17 Jan 2023 18:42:00 +0000 (10:42 -0800)
This is similar to the earlier potential fix that I didn't like,
but I think think one is better.

The analyzer claimed that 'fptr' might be Null inside the switch
case for
|struct permonst *fptr = NULL;
|if (obj->otyp == CORPSE || ...) fptr = &mons[obj->corpsenm];
|switch (obj->otyp) { case CORPSE: ... /* dereference 'fptr' */ }
even though it will always have a non-Null value for otyp==CORPSE.

Make the assignment of 'fptr' unconditional.  mons[NUMMONS] is
valid and won't match any actual monster.  In this case it will
only be used when initializing fptr, never when fptr gets used.

src/dog.c

index 9b574c1ed81b395174de00208854bfb0d0bc9b93..5c411ceec8b86fa9b8d2d01956f44a3502171332 100644 (file)
--- a/src/dog.c
+++ b/src/dog.c
@@ -898,22 +898,25 @@ discard_migrations(void)
 int
 dogfood(struct monst *mon, struct obj *obj)
 {
-    struct permonst *mptr = mon->data, *fptr = 0;
+    struct permonst *mptr = mon->data, *fptr;
     boolean carni = carnivorous(mptr), herbi = herbivorous(mptr),
             starving, mblind;
+    int fx;
 
     if (is_quest_artifact(obj) || obj_resists(obj, 0, 95))
         return obj->cursed ? TABU : APPORT;
 
     switch (obj->oclass) {
     case FOOD_CLASS:
-        if (obj->otyp == CORPSE || obj->otyp == TIN || obj->otyp == EGG)
-            fptr = &mons[obj->corpsenm];
+        fx = (obj->otyp == CORPSE || obj->otyp == TIN || obj->otyp == EGG)
+                ? obj->corpsenm
+                : NUMMONS; /* valid mons[mndx] to pacify static analyzer */
+        fptr = &mons[fx];
 
         if (obj->otyp == CORPSE && is_rider(fptr))
             return TABU;
-        if ((obj->otyp == CORPSE || obj->otyp == EGG) && touch_petrifies(fptr)
-            && !resists_ston(mon))
+        if ((obj->otyp == CORPSE || obj->otyp == EGG)
+            && touch_petrifies(fptr) && !resists_ston(mon))
             return POISON;
         if (obj->otyp == LUMP_OF_ROYAL_JELLY
             && mon->data == &mons[PM_KILLER_BEE]) {
@@ -938,12 +941,9 @@ dogfood(struct monst *mon, struct obj *obj)
         if (mptr == &mons[PM_GHOUL]) {
             if (obj->otyp == CORPSE)
                 return (peek_at_iced_corpse_age(obj) + 50L <= gm.moves
-                        && fptr != &mons[PM_LIZARD]
-                        && fptr != &mons[PM_LICHEN])
-                           ? DOGFOOD
-                           : (starving && !vegan(fptr))
-                              ? ACCFOOD
-                              : POISON;
+                        && !(fx == PM_LIZARD || fx == PM_LICHEN)) ? DOGFOOD
+                       : (starving && !vegan(fptr)) ? ACCFOOD
+                         : POISON;
             if (obj->otyp == EGG)
                 return stale_egg(obj) ? CADAVER : starving ? ACCFOOD : POISON;
             return TABU;
@@ -960,7 +960,7 @@ dogfood(struct monst *mon, struct obj *obj)
             return carni ? CADAVER : MANFOOD;
         case CORPSE:
             if ((peek_at_iced_corpse_age(obj) + 50L <= gm.moves
-                 && obj->corpsenm != PM_LIZARD && obj->corpsenm != PM_LICHEN
+                 && !(fx == PM_LIZARD || fx == PM_LICHEN)
                  && mptr->mlet != S_FUNGUS)
                 || (acidic(fptr) && !resists_acid(mon))
                 || (poisonous(fptr) && !resists_poison(mon)))
@@ -983,11 +983,9 @@ dogfood(struct monst *mon, struct obj *obj)
             /* turning into slime is preferable to starvation */
             return (starving || slimeproof(mon->data)) ? ACCFOOD : POISON;
         case CLOVE_OF_GARLIC:
-            return (is_undead(mptr) || is_vampshifter(mon))
-                      ? TABU
-                      : (herbi || starving)
-                         ? ACCFOOD
-                         : MANFOOD;
+            return (is_undead(mptr) || is_vampshifter(mon)) ? TABU
+                   : (herbi || starving) ? ACCFOOD
+                     : MANFOOD;
         case TIN:
             return metallivorous(mptr) ? ACCFOOD : MANFOOD;
         case APPLE:
@@ -995,11 +993,11 @@ dogfood(struct monst *mon, struct obj *obj)
         case CARROT:
             return (herbi || mblind) ? DOGFOOD : starving ? ACCFOOD : MANFOOD;
         case BANANA:
-            return (mptr->mlet == S_YETI && herbi)
-                      ? DOGFOOD /* for monkey and ape (tameable), sasquatch */
-                      : (herbi || starving)
-                         ? ACCFOOD
-                         : MANFOOD;
+            /* monkeys and apes (tameable) plus sasquatch prefer these,
+               yetis will only will only eat them if starving */
+            return (mptr->mlet == S_YETI && herbi) ? DOGFOOD
+                   : (herbi || starving) ? ACCFOOD
+                     : MANFOOD;
         default:
             if (starving)
                 return ACCFOOD;