diff --git a/.gitattributes b/.gitattributes
index 716ccf2664..2743f93c28 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -5757,6 +5757,7 @@ tests/test/tintfdef.pp svneol=native#text/plain
 tests/test/tintuint.pp svneol=native#text/plain
 tests/test/tlibrary1.pp svneol=native#text/plain
 tests/test/tlibrary2.pp svneol=native#text/plain
+tests/test/tmacbool.pp svneol=native#text/plain
 tests/test/tmacfunret.pp svneol=native#text/plain
 tests/test/tmaclocalprocparam.pp svneol=native#text/plain
 tests/test/tmacnonlocalexit.pp svneol=native#text/plain
@@ -5767,6 +5768,7 @@ tests/test/tmacpas3.pp svneol=native#text/plain
 tests/test/tmacpas4.pp svneol=native#text/plain
 tests/test/tmacprocvar.pp svneol=native#text/plain
 tests/test/tmath1.pp svneol=native#text/plain
+tests/test/tmcbool2.pp svneol=native#text/plain
 tests/test/tmmx1.pp svneol=native#text/plain
 tests/test/tmove.pp svneol=native#text/plain
 tests/test/tmt1.pp svneol=native#text/plain
diff --git a/compiler/nadd.pas b/compiler/nadd.pas
index 4f9f19ed8b..e3e0ac6e85 100644
--- a/compiler/nadd.pas
+++ b/compiler/nadd.pas
@@ -812,8 +812,25 @@ implementation
                  exit;
                end;
 
+              { set for & and | operations in macpas mode: they only work on }
+              { booleans, and always short circuit evaluation                }
+              if (nf_short_bool in flags) then
+                begin
+                  if not is_boolean(ld) then
+                    begin
+                      inserttypeconv(left,booltype);
+                      ld := left.resulttype.def;
+                    end;
+                  if not is_boolean(rd) then
+                    begin
+                      inserttypeconv(right,booltype);
+                      rd := right.resulttype.def;
+                    end;
+                end;
+
              { 2 booleans? Make them equal to the largest boolean }
-             if is_boolean(ld) and is_boolean(rd) then
+             if (is_boolean(ld) and is_boolean(rd)) or
+                (nf_short_bool in flags) then
               begin
                 if torddef(left.resulttype.def).size>torddef(right.resulttype.def).size then
                  begin
@@ -840,7 +857,8 @@ implementation
                   unequaln,
                   equaln:
                     begin
-                      if not(cs_full_boolean_eval in aktlocalswitches) then
+                      if not(cs_full_boolean_eval in aktlocalswitches) or
+                         (nf_short_bool in flags) then
                        begin
                          { Remove any compares with constants }
                          if (left.nodetype=ordconstn) then
@@ -2079,7 +2097,8 @@ implementation
            { 2 booleans ? }
              if is_boolean(ld) and is_boolean(rd) then
               begin
-                if not(cs_full_boolean_eval in aktlocalswitches) and
+                if (not(cs_full_boolean_eval in aktlocalswitches) or
+                    (nf_short_bool in flags)) and
                    (nodetype in [andn,orn]) then
                  begin
                    expectloc:=LOC_JUMP;
diff --git a/compiler/ncgadd.pas b/compiler/ncgadd.pas
index 8611b7d934..e17947df83 100644
--- a/compiler/ncgadd.pas
+++ b/compiler/ncgadd.pas
@@ -379,7 +379,8 @@ interface
         { And,Or will only evaluate from left to right only the
           needed nodes unless full boolean evaluation is enabled }
         if (nodetype in [orn,andn]) and
-           not(cs_full_boolean_eval in aktlocalswitches) then
+           (not(cs_full_boolean_eval in aktlocalswitches) or
+            (nf_short_bool in flags)) then
           begin
             location_reset(location,LOC_JUMP,OS_NO);
             case nodetype of
diff --git a/compiler/node.pas b/compiler/node.pas
index 85999c08d3..174963a6fd 100644
--- a/compiler/node.pas
+++ b/compiler/node.pas
@@ -220,6 +220,7 @@ interface
          { taddnode }
          nf_is_currency,
          nf_has_pointerdiv,
+         nf_short_bool,
 
          { tassignmentnode }
          nf_concat_string,
diff --git a/compiler/pexpr.pas b/compiler/pexpr.pas
index 00002107ff..ae207560e6 100644
--- a/compiler/pexpr.pas
+++ b/compiler/pexpr.pas
@@ -2567,10 +2567,18 @@ implementation
                  p1:=cisnode.create(p1,p2);
                _OP_OR,
                _PIPE {macpas only} :
-                 p1:=caddnode.create(orn,p1,p2);
+                 begin
+                   p1:=caddnode.create(orn,p1,p2);
+                   if (oldt = _PIPE) then
+                     include(p1.flags,nf_short_bool);
+                 end;
                _OP_AND,
                _AMPERSAND {macpas only} :
-                 p1:=caddnode.create(andn,p1,p2);
+                 begin
+                   p1:=caddnode.create(andn,p1,p2);
+                   if (oldt = _AMPERSAND) then
+                     include(p1.flags,nf_short_bool);
+                 end;
                _OP_DIV :
                  p1:=cmoddivnode.create(divn,p1,p2);
                _OP_NOT :
diff --git a/compiler/powerpc/nppcadd.pas b/compiler/powerpc/nppcadd.pas
index 554a798c8f..015728735c 100644
--- a/compiler/powerpc/nppcadd.pas
+++ b/compiler/powerpc/nppcadd.pas
@@ -261,7 +261,8 @@ interface
         else
            cgsize:=OS_32;
 
-        if (cs_full_boolean_eval in aktlocalswitches) or
+        if ((cs_full_boolean_eval in aktlocalswitches) and
+            not(nf_short_bool in flags)) or
            (nodetype in [unequaln,ltn,lten,gtn,gten,equaln,xorn]) then
           begin
             if left.nodetype in [ordconstn,realconstn] then
diff --git a/compiler/powerpc64/nppcadd.pas b/compiler/powerpc64/nppcadd.pas
index a260fbb33e..896fc9819a 100644
--- a/compiler/powerpc64/nppcadd.pas
+++ b/compiler/powerpc64/nppcadd.pas
@@ -254,7 +254,8 @@ begin
   else
     cgsize := OS_32;
 
-  if (cs_full_boolean_eval in aktlocalswitches) or
+  if ((cs_full_boolean_eval in aktlocalswitches) and
+      not(nf_short_bool in flags)) or
     (nodetype in [unequaln, ltn, lten, gtn, gten, equaln, xorn]) then
   begin
     if left.nodetype in [ordconstn, realconstn] then
diff --git a/compiler/ppu.pas b/compiler/ppu.pas
index 762ef688e9..f646b2e898 100644
--- a/compiler/ppu.pas
+++ b/compiler/ppu.pas
@@ -43,7 +43,7 @@ type
 {$endif Test_Double_checksum}
 
 const
-  CurrentPPUVersion=57;
+  CurrentPPUVersion=58;
 
 { buffer sizes }
   maxentrysize = 1024;
diff --git a/tests/test/tmacbool.pp b/tests/test/tmacbool.pp
new file mode 100644
index 0000000000..ba773aed6c
--- /dev/null
+++ b/tests/test/tmacbool.pp
@@ -0,0 +1,189 @@
+program macbool;
+
+{$mode macpas}
+
+{ checks boolean evaluation in macpas mode }
+
+var
+  ftruecalled, ffalsecalled: boolean;
+
+function ftrue: boolean;
+begin
+  ftruecalled := true;
+  ftrue := true;
+end;
+
+function ffalse: boolean;
+begin
+  ffalsecalled := true;
+  ffalse := false;
+end;
+
+
+begin
+  { OR and |, short circuit }
+{$b-}
+  ffalsecalled := false;
+  ftruecalled := false;
+  if (ftrue or ffalse) then
+    begin
+      if not(ftruecalled) then
+        halt(1);
+      if ffalsecalled then
+        halt(2);
+    end
+  else
+    halt(128);
+
+  ffalsecalled := false;
+  ftruecalled := false;
+  if not(ffalse or ftrue) then
+    halt(3);
+  if not(ffalsecalled) then
+    halt(4);
+  if not(ftruecalled) then
+    halt(5);
+
+  ffalsecalled := false;
+  ftruecalled := false;
+  if (ftrue | ffalse) then
+    begin
+      if not(ftruecalled) then
+        halt(6);
+      if ffalsecalled then
+        halt(7);
+    end
+  else
+    halt(129);
+
+  ffalsecalled := false;
+  ftruecalled := false;
+  if not(ffalse | ftrue) then
+    halt(8);
+  if not(ffalsecalled) then
+    halt(9);
+  if not(ftruecalled) then
+    halt(10);
+
+
+  { OR and |, full evaluation }
+{$b+}
+  ffalsecalled := false;
+  ftruecalled := false;
+  if (ftrue or ffalse) then
+    begin
+      if not(ftruecalled) then
+        halt(11);
+      if not(ffalsecalled) then
+        halt(12);
+    end
+  else
+    halt(130);
+
+  ffalsecalled := false;
+  ftruecalled := false;
+  if not(ffalse or ftrue) then
+    halt(13);
+  if not(ffalsecalled) then
+    halt(14);
+  if not(ftruecalled) then
+    halt(15);
+
+  ffalsecalled := false;
+  ftruecalled := false;
+  if (ftrue | ffalse) then
+    begin
+      if not(ftruecalled) then
+        halt(16);
+      if ffalsecalled then
+        halt(17);
+    end
+  else
+    halt(131);
+
+  ffalsecalled := false;
+  ftruecalled := false;
+  if not(ffalse | ftrue) then
+    halt(18);
+  if not(ffalsecalled) then
+    halt(19);
+  if not(ftruecalled) then
+    halt(20);
+
+  { AND and &, short circuit }
+{$b-}
+  ffalsecalled := false;
+  ftruecalled := false;
+  if (ftrue and ffalse) then
+    halt(21);
+   if not(ftruecalled) then
+     halt(211);
+   if not(ffalsecalled) then
+     halt(22);
+
+  ffalsecalled := false;
+  ftruecalled := false;
+  if (ffalse and ftrue) then
+    halt(23);
+  if not(ffalsecalled) then
+    halt(24);
+  if (ftruecalled) then
+    halt(25);
+
+  ffalsecalled := false;
+  ftruecalled := false;
+  if (ftrue & ffalse) then
+    halt(206);
+  if not(ftruecalled) then
+    halt(26);
+  if not(ffalsecalled) then
+    halt(27);
+
+  ffalsecalled := false;
+  ftruecalled := false;
+  if (ffalse & ftrue) then
+    halt(28);
+  if not(ffalsecalled) then
+    halt(29);
+  if (ftruecalled) then
+    halt(30);
+
+
+  { AND and &, full evaluation }
+{$b+}
+  ffalsecalled := false;
+  ftruecalled := false;
+  if (ftrue and ffalse) then
+    halt(31);
+   if not(ftruecalled) then
+     halt(111);
+   if not(ffalsecalled) then
+     halt(32);
+
+  ffalsecalled := false;
+  ftruecalled := false;
+  if (ffalse and ftrue) then
+    halt(33);
+  if not(ffalsecalled) then
+    halt(34);
+  if not(ftruecalled) then
+    halt(35);
+
+  ffalsecalled := false;
+  ftruecalled := false;
+  if (ftrue & ffalse) then
+    halt(133);
+  if not(ftruecalled) then
+    halt(36);
+  if not(ffalsecalled) then
+    halt(37);
+
+  ffalsecalled := false;
+  ftruecalled := false;
+  if (ffalse & ftrue) then
+    halt(38);
+  if not(ffalsecalled) then
+    halt(39);
+  if (ftruecalled) then
+    halt(40);
+end.
diff --git a/tests/test/tmcbool2.pp b/tests/test/tmcbool2.pp
new file mode 100644
index 0000000000..e93f9b38dd
--- /dev/null
+++ b/tests/test/tmcbool2.pp
@@ -0,0 +1,10 @@
+{ %fail}
+program mcbool2;
+
+{$mode macpas}
+
+var
+  a, b: longint;
+begin
+  a := a & b;
+end.