ast_unary::make: safer double-negation optimization check
authorWolfgang Bumiller <wry.git@bumiller.com>
Sun, 1 Feb 2015 11:13:05 +0000 (12:13 +0100)
committerWolfgang Bumiller <wry.git@bumiller.com>
Sun, 1 Feb 2015 11:13:05 +0000 (12:13 +0100)
ast.cpp

diff --git a/ast.cpp b/ast.cpp
index 96d9e2f..3a26dd9 100644 (file)
--- a/ast.cpp
+++ b/ast.cpp
@@ -365,16 +365,20 @@ ast_binstore::~ast_binstore()
 
 ast_unary* ast_unary::make(lex_ctx_t ctx, int op, ast_expression *expr)
 {
-    if (ast_istype(expr, ast_unary) && OPTS_OPTIMIZATION(OPTIM_PEEPHOLE)) {
-        ast_unary *prev = (ast_unary*)((ast_unary*)expr)->m_operand;
-
-        /* Handle for double negation */
-        if (((ast_unary*)expr)->m_op == op)
-            prev = (ast_unary*)((ast_unary*)expr)->m_operand;
-
-        if (ast_istype(prev, ast_unary)) {
-            ++opts_optimizationcount[OPTIM_PEEPHOLE];
-            return prev;
+    // handle double negation, double bitwise or logical not
+    if (op == opid2('!','P') ||
+        op == opid2('~','P') ||
+        op == opid2('-','P'))
+    {
+        if (ast_istype(expr, ast_unary) && OPTS_OPTIMIZATION(OPTIM_PEEPHOLE)) {
+            ast_unary *unary = reinterpret_cast<ast_unary*>(expr);
+            if (unary->m_op == op) {
+                auto out = reinterpret_cast<ast_unary*>(unary->m_operand);
+                unary->m_operand = nullptr;
+                delete unary;
+                ++opts_optimizationcount[OPTIM_PEEPHOLE];
+                return out;
+            }
         }
     }