<URL: http://bugs.freeciv.org/Ticket/Display.html?id=39562 >

 In current trunk bad choice structures cause illegal memory access
(old iterators were more robust, but at the same time they hide bugs).
 This patch makes easier to hunt those choice problems down.


 - ML

diff -Nurd -X.diff_ignore freeciv/ai/aicity.c freeciv/ai/aicity.c
--- freeciv/ai/aicity.c	2007-08-13 20:51:05.000000000 +0300
+++ freeciv/ai/aicity.c	2007-08-14 11:41:06.000000000 +0300
@@ -1380,7 +1380,7 @@
   }
 
   if (pcity->ai.choice.want != 0) { 
-    ASSERT_REAL_CHOICE_TYPE(pcity->ai.choice.type);
+    ASSERT_CHOICE(pcity->ai.choice);
 
     CITY_LOG(LOG_DEBUG, pcity, "wants %s with desire %d.",
 	     is_unit_choice_type(pcity->ai.choice.type)
@@ -1532,7 +1532,7 @@
     /* Not dealing with this city a second time */
     pcity->ai.choice.want = 0;
 
-    ASSERT_REAL_CHOICE_TYPE(bestchoice.type);
+    ASSERT_CHOICE(bestchoice);
 
     /* Try upgrade units at danger location (high want is usually danger) */
     if (pcity->ai.urgency > 1) {
@@ -1692,6 +1692,7 @@
         game.info.turn + myrand(RECALC_SPEED) + RECALC_SPEED;
     }
     TIMING_LOG(AIT_CITY_SETTLERS, TIMER_STOP);
+    ASSERT_CHOICE(pcity->ai.choice);
   } city_list_iterate_end;
 
   city_list_iterate(pplayer->cities, pcity) {
diff -Nurd -X.diff_ignore freeciv/common/city.h freeciv/common/city.h
--- freeciv/common/city.h	2007-08-13 20:51:03.000000000 +0300
+++ freeciv/common/city.h	2007-08-14 11:38:37.000000000 +0300
@@ -157,18 +157,19 @@
   CT_LAST
 };
 
-/* FIXME:
-
-   This should detect also cases where type is just initialized with
-   CT_NONE (probably in order to silence compiler warnings), but no real value
-   is given. You have to change value of CT_BUILDING into 1 before you
-   can add this check. It's left this way for now, is case hardcoded
-   value 0 is still used somewhere instead of CT_BUILDING.
-
-   -- Caz
-*/
-#define ASSERT_REAL_CHOICE_TYPE(type)                                    \
-        assert(type >= 0 && type < CT_LAST /* && type != CT_NONE */ );
+#define ASSERT_CHOICE(c)                                                 \
+  do {                                                                   \
+    if ((c).want > 0) {                                                  \
+      assert((c).type >= 0 && (c).type < CT_LAST && (c).type != CT_NONE);\
+      if ((c).type == CT_BUILDING) {                                     \
+        int _iindex = improvement_index((c).value.building);             \
+        assert(_iindex >= 0 && _iindex < B_LAST);                        \
+      } else {                                                           \
+        int _uindex = utype_index((c).value.utype);                      \
+        assert(_uindex >= 0 && _uindex < U_LAST);                        \
+      }                                                                  \
+    }                                                                    \
+  } while(0);
 
 struct ai_choice {
   enum choice_type type;
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to