[07/20] Defer evaluating .if until within the right scope

Message ID 1395664691-60544-7-git-send-email-martin@martin.st
State Committed
Commit a83f5860179f58a74a52f3817ba4db7397073987
Headers show

Commit Message

Martin Storsjö March 24, 2014, 12:37 p.m.
This avoids prematurely evaluating .if conditions within
repetitions/macros, that previously were erroneously
evaluated too early if the enclosing environment was wrapped
in an .if.
---
 gas-preprocessor.pl | 33 +++++++++++++++++++--------------
 test.S              | 18 ++++++++++++++++++
 2 files changed, 37 insertions(+), 14 deletions(-)

Comments

Janne Grunau March 24, 2014, 3 p.m. | #1
On 2014-03-24 14:37:58 +0200, Martin Storsjö wrote:
> This avoids prematurely evaluating .if conditions within
> repetitions/macros, that previously were erroneously
> evaluated too early if the enclosing environment was wrapped
> in an .if.
> ---
>  gas-preprocessor.pl | 33 +++++++++++++++++++--------------
>  test.S              | 18 ++++++++++++++++++
>  2 files changed, 37 insertions(+), 14 deletions(-)

ok

Janne

Patch

diff --git a/gas-preprocessor.pl b/gas-preprocessor.pl
index 5917d2b..24977a7 100755
--- a/gas-preprocessor.pl
+++ b/gas-preprocessor.pl
@@ -301,21 +301,26 @@  sub parse_if_line {
 
     # evaluate .if blocks
     if (scalar(@ifstack)) {
-        if ($line =~ /\.endif/) {
-            pop(@ifstack);
-            return 1;
-        } elsif ($line =~ /\.elseif\s+(.*)/) {
-            if ($ifstack[-1] == 0) {
-                $ifstack[-1] = !!eval_expr($1);
-            } elsif ($ifstack[-1] > 0) {
-                $ifstack[-1] = -$ifstack[-1];
+        # Don't evaluate any new if statements if we're within
+        # a repetition or macro - they will be evaluated once
+        # the repetition is unrolled or the macro is expanded.
+        if (scalar(@rept_lines) == 0 and $macro_level == 0) {
+            if ($line =~ /\.endif/) {
+                pop(@ifstack);
+                return 1;
+            } elsif ($line =~ /\.elseif\s+(.*)/) {
+                if ($ifstack[-1] == 0) {
+                    $ifstack[-1] = !!eval_expr($1);
+                } elsif ($ifstack[-1] > 0) {
+                    $ifstack[-1] = -$ifstack[-1];
+                }
+                return 1;
+            } elsif ($line =~ /\.else/) {
+                $ifstack[-1] = !$ifstack[-1];
+                return 1;
+            } elsif (handle_if($line)) {
+                return 1;
             }
-            return 1;
-        } elsif ($line =~ /\.else/) {
-            $ifstack[-1] = !$ifstack[-1];
-            return 1;
-        } elsif (handle_if($line)) {
-            return 1;
         }
 
         # discard lines in false .if blocks
diff --git a/test.S b/test.S
index a05e743..f8372d5 100644
--- a/test.S
+++ b/test.S
@@ -30,3 +30,21 @@  m 0
 .irpc i, 01
     m \i
 .endr
+
+.macro outer
+    .macro inner
+        .if VAR1 > 10
+            mov r4, #42
+        .endif
+    .endm
+
+    .set VAR1, 5
+    inner
+    .set VAR1, 15
+    inner
+    .purgem inner
+.endm
+
+.if 2 > 1
+    outer
+.endif