Do not use DW_OP_not for TRUTH_NOT_EXPR in conditional expressions
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 16 May 2022 08:44:09 +0000 (10:44 +0200)
committerEric Botcazou <ebotcazou@adacore.com>
Mon, 16 May 2022 09:04:51 +0000 (11:04 +0200)
DW_OP_not is a bitwise, not a logical NOT, so it computes the wrong result
in a DWARF conditional expression.

gcc/
* dwarf2out.cc (loc_list_from_tree_1) <TRUTH_NOT_EXPR>: Do a logical
instead of a bitwise negation.
<COND_EXPR>: Swap the operands if the condition is TRUTH_NOT_EXPR.

gcc/dwarf2out.cc

index 4ef644c..fccf59e 100644 (file)
@@ -19448,6 +19448,14 @@ loc_list_from_tree_1 (tree loc, int want_address,
       break;
 
     case TRUTH_NOT_EXPR:
+      list_ret = loc_list_from_tree_1 (TREE_OPERAND (loc, 0), 0, context);
+      if (list_ret == 0)
+       return 0;
+
+      add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_lit0, 0, 0));
+      add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_eq, 0, 0));
+      break;
+
     case BIT_NOT_EXPR:
       op = DW_OP_not;
       goto do_unop;
@@ -19496,6 +19504,15 @@ loc_list_from_tree_1 (tree loc, int want_address,
          list_ret
            = loc_list_from_tree_1 (TREE_OPERAND (TREE_OPERAND (loc, 0), 0),
                                    0, context);
+       /* Likewise, swap the operands for a logically negated condition.  */
+       else if (TREE_CODE (TREE_OPERAND (loc, 0)) == TRUTH_NOT_EXPR)
+         {
+           lhs = loc_descriptor_from_tree (TREE_OPERAND (loc, 2), 0, context);
+           rhs = loc_list_from_tree_1 (TREE_OPERAND (loc, 1), 0, context);
+           list_ret
+             = loc_list_from_tree_1 (TREE_OPERAND (TREE_OPERAND (loc, 0), 0),
+                                     0, context);
+         }
        else
          list_ret = loc_list_from_tree_1 (TREE_OPERAND (loc, 0), 0, context);
        if (list_ret == 0 || lhs == 0 || rhs == 0)