diff --git a/src/builtin_functions.c b/src/builtin_functions.c
index 00b66922a68374f49c025c559cf987f233275e83..b7d893ee28d488ef853f42b1dd538902581d4886 100644
--- a/src/builtin_functions.c
+++ b/src/builtin_functions.c
@@ -706,6 +706,7 @@ PMOD_EXPORT void f_lower_case(INT32 args)
 
   ret = end_shared_string(ret);
   ret->flags |= STRING_IS_LOWERCASE;
+  ret->flags |= orig->flags & STRING_CLEAR_ON_EXIT;
   pop_n_elems(args);
   push_string(ret);
 }
@@ -813,6 +814,7 @@ PMOD_EXPORT void f_upper_case(INT32 args)
   pop_n_elems(args);
   ret = end_shared_string(ret);
   ret->flags |= STRING_IS_UPPERCASE;
+  ret->flags |= orig->flags & STRING_CLEAR_ON_EXIT;
   push_string(ret);
 }
 
@@ -1779,6 +1781,7 @@ PMOD_EXPORT void f_string_to_unicode(INT32 args)
 #endif
   }
   pop_n_elems(args);
+  out->flags |= in->flags & STRING_CLEAR_ON_EXIT;
   push_string(out);
 }
 
@@ -1938,6 +1941,7 @@ PMOD_EXPORT void f_unicode_to_string(INT32 args)
   }
   out = end_shared_string(out);
   pop_n_elems(args);
+  out->flags |= in->flags & STRING_CLEAR_ON_EXIT;
   push_string(out);
 }
 
@@ -2082,6 +2086,7 @@ PMOD_EXPORT void f_string_to_utf8(INT32 args)
 #endif /* PIKE_DEBUG */
   out = end_shared_string(out);
   pop_n_elems(args);
+  out->flags |= in->flags & STRING_CLEAR_ON_EXIT;
   push_string(out);
 }
 
@@ -2435,6 +2440,7 @@ PMOD_EXPORT void f_utf8_to_string(INT32 args)
   check_string (out);
 #endif
   pop_n_elems(args);
+  out->flags |= in->flags & STRING_CLEAR_ON_EXIT;
   push_string(out);
 }
 
diff --git a/src/operators.c b/src/operators.c
index 2dcbc8019b64562d422ce15c0d25569fae3911ba..43808e9858078c2c03134ce8b3d929d2cfa85c85 100644
--- a/src/operators.c
+++ b/src/operators.c
@@ -2741,28 +2741,31 @@ PMOD_EXPORT void o_and(void)
 #define STRING_BITOP(OP,STROP)						  \
   case T_STRING:							  \
   {									  \
-    struct pike_string *s;						  \
+    struct pike_string *s, *a, *b;					  \
     ptrdiff_t len, i;							  \
-									  \
-    len = sp[-2].u.string->len;						  \
-    if (len != sp[-1].u.string->len)					  \
+    a = sp[-2].u.string;                                                  \
+    b = sp[-1].u.string;                                                  \
+    len = a->len;						          \
+    if (len != b->len)					                  \
       PIKE_ERROR("`" #OP, "Bitwise "STROP				  \
 		 " on strings of different lengths.\n", sp, 2);		  \
-    if(!sp[-2].u.string->size_shift && !sp[-1].u.string->size_shift)	  \
+    if(!a->size_shift && !b->size_shift)	                          \
     {									  \
       s = begin_shared_string(len);					  \
       for (i=0; i<len; i++)						  \
-	s->str[i] = sp[-2].u.string->str[i] OP sp[-1].u.string->str[i];	  \
+	s->str[i] = a->str[i] OP b->str[i];	                          \
     }else{								  \
       s = begin_wide_shared_string(len,					  \
-				   MAXIMUM(sp[-2].u.string->size_shift,	  \
-					   sp[-1].u.string->size_shift)); \
+				   MAXIMUM(a->size_shift,	          \
+					   b->size_shift));               \
       for (i=0; i<len; i++)						  \
-	low_set_index(s,i,index_shared_string(sp[-2].u.string,i) OP 	  \
-		      index_shared_string(sp[-1].u.string,i));		  \
+	low_set_index(s,i,index_shared_string(a,i) OP 	                  \
+		      index_shared_string(b,i));		          \
     }									  \
+    s = end_shared_string(s);                                             \
+    s->flags |= (a->flags | b->flags) & STRING_CLEAR_ON_EXIT;             \
     pop_n_elems(2);							  \
-    push_string(end_shared_string(s));					  \
+    push_string(s);                                                       \
     return;								  \
   }
 
diff --git a/src/stralloc.c b/src/stralloc.c
index 5d97026659c5195b8499a0a212428080c1768cc0..91da8781859427c8bb0e81a103787fff7ad0a14e 100644
--- a/src/stralloc.c
+++ b/src/stralloc.c
@@ -1778,7 +1778,8 @@ struct pike_string *realloc_unlinked_string(struct pike_string *a,
   if(!r)
   {
     r=begin_wide_shared_string(size, a->size_shift);
-    r->flags |= a->flags & ~15;
+    /* we keep both content information and the clear flags */
+    r->flags |= a->flags & (STRING_CONTENT_MASK|STRING_CLEAR_ON_EXIT);
     r->min = a->min;
     r->max = a->max;
     if (a->len <= size) {
@@ -1806,7 +1807,8 @@ static struct pike_string *realloc_shared_string(struct pike_string *a,
   }else{
     r=begin_wide_shared_string(size,a->size_shift);
     MEMCPY(r->str, a->str, a->len<<a->size_shift);
-    r->flags |= a->flags & ~15;
+    /* we keep both content information and the clear flags */
+    r->flags |= a->flags & (STRING_CONTENT_MASK|STRING_CLEAR_ON_EXIT);
     r->min = a->min;
     r->max = a->max;
     free_string(a);
@@ -1821,7 +1823,7 @@ struct pike_string *new_realloc_shared_string(struct pike_string *a, INT32 size,
 
   r=begin_wide_shared_string(size,shift);
   pike_string_cpy(MKPCHARP_STR(r),a);
-  r->flags |= (a->flags & ~15);
+  r->flags |= (a->flags & (STRING_CONTENT_MASK|STRING_CLEAR_ON_EXIT));
   r->min = a->min;
   r->max = a->max;
   free_string(a);
@@ -1994,7 +1996,7 @@ PMOD_EXPORT void set_flags_for_add( struct pike_string *ret,
                                     struct pike_string *b)
 {
   if( !b->len ) {
-    ret->flags |= aflags & ~15;
+    ret->flags |= aflags & (STRING_CONTENT_MASK|STRING_CLEAR_ON_EXIT);
     ret->min = amin;
     ret->max = amax;
     return;
@@ -2010,6 +2012,7 @@ PMOD_EXPORT void set_flags_for_add( struct pike_string *ret,
 
   ret->flags &= ~(STRING_IS_LOWERCASE | STRING_IS_UPPERCASE);
   ret->flags |= (aflags & b->flags & (STRING_IS_LOWERCASE | STRING_IS_UPPERCASE));
+  ret->flags |= (aflags | b->flags) & STRING_CLEAR_ON_EXIT;
 }
 
 PMOD_EXPORT void update_flags_for_add( struct pike_string *a, struct pike_string *b)
@@ -2027,6 +2030,7 @@ PMOD_EXPORT void update_flags_for_add( struct pike_string *a, struct pike_string
   }
 
   a->flags &= ~(STRING_IS_LOWERCASE | STRING_IS_UPPERCASE) | b->flags;
+  a->flags |= b->flags & STRING_CLEAR_ON_EXIT;
 }
 
 /*** Add strings ***/
diff --git a/src/stralloc.h b/src/stralloc.h
index 951d3f6c6dd61418f80dd30dc0308812e65cede1..2f90e6629fe1605a2804a06fe70d3bf0a1a596e4 100644
--- a/src/stralloc.h
+++ b/src/stralloc.h
@@ -62,6 +62,8 @@ struct string_builder
 #define STRING_IS_LOWERCASE    32
 #define STRING_IS_UPPERCASE    64
 
+#define STRING_CONTENT_MASK (STRING_CONTENT_CHECKED|STRING_IS_LOWERCASE|STRING_IS_UPPERCASE)
+
 #define CLEAR_STRING_CHECKED(X) do{(X)->flags &= 15;}while(0)
 
 /* Flags used by string_builder_append_integer() */