diff --git a/src/cpp.c b/src/cpp.c
index a5b4b7958bf662d4610c44e6ec6dd3a4fa28dfb5..871fc3482e62c2320498291e8d8e624a9b06f12f 100644
--- a/src/cpp.c
+++ b/src/cpp.c
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: cpp.c,v 1.84 2001/05/14 03:20:39 hubbe Exp $
+ * $Id: cpp.c,v 1.85 2001/05/29 16:48:20 grubba Exp $
  */
 #include "global.h"
 #include "stralloc.h"
@@ -191,6 +191,11 @@ static void undefine(struct cpp *this,
 
   if(!d) return;
 
+  if (d->inside) {
+    cpp_error(this, "Illegal to undefine a macro during its expansion.");
+    return;
+  }
+
   this->defines=hash_unlink(this->defines, & d->link);
 
   for(e=0;e<d->num_parts;e++)
@@ -824,6 +829,18 @@ static struct pike_string *filter_bom(struct pike_string *data)
   return(data);
 }
 
+void free_one_define(struct hash_entry *h)
+{
+  int e;
+  struct define *d=BASEOF(h, define, link);
+
+  for(e=0;e<d->num_parts;e++)
+    free_string(d->parts[e].postfix);
+  if(d->first)
+    free_string(d->first);
+  free((char *)d);
+}
+
 static ptrdiff_t low_cpp(struct cpp *this, void *data, ptrdiff_t len,
 			 int shift, int flags, int auto_convert,
 			 struct pike_string *charset);
@@ -861,18 +878,6 @@ static ptrdiff_t low_cpp(struct cpp *this, void *data, ptrdiff_t len,
   return 0;
 }
 
-void free_one_define(struct hash_entry *h)
-{
-  int e;
-  struct define *d=BASEOF(h, define, link);
-
-  for(e=0;e<d->num_parts;e++)
-    free_string(d->parts[e].postfix);
-  if(d->first)
-    free_string(d->first);
-  free((char *)d);
-}
-
 /*** Magic defines ***/
 static void insert_current_line(struct cpp *this,
 				struct define *def,
diff --git a/src/preprocessor.h b/src/preprocessor.h
index 3d13b80a7ff25b2bc0ee4e5622632fbb49cb78fa..00e688d90389a1c3ecf8dea83aa48d08c1456994 100644
--- a/src/preprocessor.h
+++ b/src/preprocessor.h
@@ -1,5 +1,5 @@
 /*
- * $Id: preprocessor.h,v 1.39 2001/05/17 23:49:07 hubbe Exp $
+ * $Id: preprocessor.h,v 1.40 2001/05/29 16:48:21 grubba Exp $
  *
  * Preprocessor template.
  * Based on cpp.c 1.45
@@ -1033,9 +1033,11 @@ static ptrdiff_t lower_cpp(struct cpp *this,
 		  INT32 line=this->current_line;
 		  save=this->buf;
 		  this->buf=tmp;
+		  d->inside = 1;
 		  lower_cpp(this, a, l,
 			    flags & ~(CPP_EXPECT_ENDIF | CPP_EXPECT_ELSE),
 			    auto_convert, charset);
+		  d->inside = 0;
 		  tmp=this->buf;
 		  this->buf=save;
 		  this->current_line=line;
@@ -1879,9 +1881,16 @@ static ptrdiff_t lower_cpp(struct cpp *this,
 	       (def->parts[0].argument & DEF_ARG_MASK) > MAX_ARGS)
 	      fatal("Internal error in define\n");
 #endif	  
-	    
-	    this->defines=hash_insert(this->defines, & def->link);
-	    
+	    {
+	      struct define *d;
+	      if ((d = find_define(def->link.s)) && (d->inside)) {
+		cpp_error(this,
+			  "Illegal to redefine a macro during its expansion.");
+		free_one_define(&(def->link));
+	      } else {
+		this->defines=hash_insert(this->defines, & def->link);
+	      }
+	    }
 	  }
 	  pop_n_elems(Pike_sp-argbase);
 	  break;
diff --git a/src/testsuite.in b/src/testsuite.in
index 13f582ca790f35d4615c38f4a8279e4d4db86e41..0597e9e3021628f9cb3ed99ef8ab58189ed98e40 100644
--- a/src/testsuite.in
+++ b/src/testsuite.in
@@ -1,4 +1,4 @@
-test_true([["$Id: testsuite.in,v 1.416 2001/05/24 22:39:01 hubbe Exp $"]]);
+test_true([["$Id: testsuite.in,v 1.417 2001/05/29 16:48:21 grubba Exp $"]]);
 
 cond([[all_constants()->_verify_internals]],
 [[
@@ -5843,6 +5843,26 @@ do_test_cpp_string([["\\\\"]])
 do_test_cpp_string([["\\\\\\"]])
 do_test_cpp_string([["\""]])
 
+// #undef inside an evaluation of the macro.
+test_compile_error([[
+#define LOCALE(X,Y) (Y)
+#define DEFVAR(X, Y) ret[(X)]=my_defvar((X),(Y),vars)
+
+  DEFVAR("cm_wa",
+         Sitebuilder.SBConnect()->
+         ChooseWorkareaVariable(LOCALE(0, "Work area") + LOCALE(0, "Work area"),
+                                LOCALE(0, "the"));
+
+  DEFVAR("cr_startpage",
+         Variable.URLList(LOCALE(0, "Crawling behaviour") + LOCALE(0, "Start pages"), ""));
+
+#undef DEFVAR
+
+constant cif_defines = #"
+   <input align='&_.img-align;' type='image' name='&_.name;' value='&_.contents;' src='&var.url;' border='0' />
+</define>";
+]])
+
 // foop
 define(do_test_foop,[[
 test_eq($1 (17), !($2))