Browse Source

* handle unary minus in the preprocessor, resolves #40782

florian 1 year ago
parent
commit
a9c88ace25
2 changed files with 44 additions and 1 deletions
  1. 28 1
      compiler/scanner.pas
  2. 16 0
      tests/test/tpreproc1.pp

+ 28 - 1
compiler/scanner.pas

@@ -1359,7 +1359,20 @@ type
             end;
         end;
         _EQ,_NE,_LT,_GT,_GTE,_LTE,_PLUS,_MINUS,_STAR,_SLASH,_OP_DIV,_OP_MOD,_OP_SHL,_OP_SHR:
-        if check_compatible then
+        if (op=_MINUS) and not(assigned(v)) then
+          begin
+            if is_ordinal(def) then
+              result:=texprvalue.create_ord(-value.valueord)
+            else if is_fpu(def) then
+              result:=texprvalue.create_real(-pbestreal(value.valueptr)^)
+            else
+              begin
+                { actually we should never get here but this avoids a warning }
+                Message(parser_e_illegal_expression);
+                result:=texprvalue.create_error;
+              end;
+          end
+        else if check_compatible then
           begin
             if (is_ordinal(def) and is_ordinal(v.def)) then
               begin
@@ -2395,6 +2408,20 @@ type
                  end;
                preproc_consume(_REALNUMBER);
              end
+           else if current_scanner.preproc_token = _MINUS then
+             begin
+               preproc_consume(_MINUS);
+               exprvalue:=preproc_factor(eval);
+               if eval then
+                 result:=exprvalue.evaluate(nil,_MINUS)
+               else if exprvalue.isInt then
+                 result:=texprvalue.create_int(-exprvalue.asInt)
+               else if is_fpu(exprvalue.def) then
+                 result:=texprvalue.create_real(-pbestreal(exprvalue.value.valueptr)^)
+               else
+                 Message(scan_e_error_in_preproc_expr);
+               exprvalue.free;
+             end
            else
              Message(scan_e_error_in_preproc_expr);
            if not assigned(result) then

+ 16 - 0
tests/test/tpreproc1.pp

@@ -0,0 +1,16 @@
+const
+	C = -2;
+	M2 = -2;
+begin
+	// Works.
+	{$if C <> M2} {$error C <> M2} {$endif}
+
+	// Error: Evaluating a conditional compiling expression
+	// Error: Incompatible types: got "<erroneous type>" expected "Int64"
+	// Error: Incompatible types: got "ShortInt" expected "<erroneous type>"
+	// Error: Compile time expression: Wanted Boolean but got <erroneous type> at IF or ELSEIF
+	{$if C <> -2} {$error C <> -2} {$endif}
+	{$if C <> - 2} {$error C <> - 2} {$endif}
+	{$if C <> -2.0} {$error C <> -2.0} {$endif}
+	{$if C <> - 2.0} {$error C <> - 2.0} {$endif}
+end.