diff --git a/src/lexer.h b/src/lexer.h
index 917d874052b2d7ff750ccfc97a33f68f9330e37b..b3c08481a0cdefdced85da7011e3c38b015ce795 100644
--- a/src/lexer.h
+++ b/src/lexer.h
@@ -61,7 +61,7 @@
 
 #define LOOK() INDEX_CHARP(lex->pos,0,SHIFT)
 #define SKIP() (lex->pos += (1<<SHIFT))
-#define SKIPN(N) (lex->pos += ((N)<<SHIFT))
+#define SKIPN(N) (lex->pos += (N) < 0 ? -(-(N) << SHIFT) : ((N)<<SHIFT))
 #define GETC() (SKIP(),INDEX_CHARP(lex->pos-(1<<SHIFT),0,SHIFT))
 
 #define READBUF(X) do {				\
diff --git a/src/stralloc.h b/src/stralloc.h
index 951d3f6c6dd61418f80dd30dc0308812e65cede1..829c12109606ae666e9d1929f7528aa85b5191f6 100644
--- a/src/stralloc.h
+++ b/src/stralloc.h
@@ -125,13 +125,20 @@ struct pike_string *debug_findstring(const struct pike_string *foo);
    (((p_wchar2 *)(PTR))[(IND)] = DO_NOT_WARN ((p_wchar2) (VAL))))
 
 
+/* arithmetic left shift. compilers will understand this
+ * and generate one arithmetic left shift. Left shifting
+ * a negative integer is undefined and could be optimized
+ * away by compilers.
+ */
+#define SAL(a, b)	((a) < 0 ? -(-(a) << (b)) : (a) << (b))
+
 #define EXTRACT_CHARP(PTR,SHIFT) INDEX_CHARP((PTR),0,(SHIFT))
-#define CHARP_ADD(PTR,X,SHIFT) (PTR)+=(X)<<(SHIFT)
+#define CHARP_ADD(PTR,X,SHIFT) (PTR)+=SAL(X,SHIFT)
 
 #define INDEX_PCHARP(X,Y) INDEX_CHARP((X).ptr,(Y),(X).shift)
 #define SET_INDEX_PCHARP(X,Y,Z) SET_INDEX_CHARP((X).ptr,(Y),(X).shift,(Z))
 #define EXTRACT_PCHARP(X) INDEX_CHARP((X).ptr,(0),(X).shift)
-#define INC_PCHARP(X,Y) (((X).ptr)+=(Y) << (X).shift)
+#define INC_PCHARP(X,Y) (((X).ptr)+= SAL(Y, (X).shift))
 
 #define LOW_COMPARE_PCHARP(X,CMP,Y) (((char *)((X).ptr)) CMP ((char *)((Y).ptr)))
 #define LOW_SUBTRACT_PCHARP(X,Y) (LOW_COMPARE_PCHARP((X),-,(Y))>>(X).shift)
@@ -154,10 +161,10 @@ static INLINE PCHARP MKPCHARP(const void *ptr, int shift)
   return tmp;
 }
 
-#define MKPCHARP_OFF(PTR,SHIFT,OFF) MKPCHARP( ((char *)(PTR)) + ((OFF)<<(SHIFT)), (SHIFT))
+#define MKPCHARP_OFF(PTR,SHIFT,OFF) MKPCHARP( ((char *)(PTR)) + SAL(OFF, SHIFT), (SHIFT))
 #define MKPCHARP_STR(STR) MKPCHARP((STR)->str, (STR)->size_shift)
 #define MKPCHARP_STR_OFF(STR,OFF) \
- MKPCHARP((STR)->str + ((OFF)<<(STR)->size_shift), (STR)->size_shift)
+ MKPCHARP((STR)->str + SAL((OFF),(STR)->size_shift), (STR)->size_shift)
 #define ADD_PCHARP(PTR,I) MKPCHARP_OFF((PTR).ptr,(PTR).shift,(I))
 
 #define reference_shared_string(s) add_ref(s)