> But this doesn't fix
> 
>     case TRUTH_NOT_EXPR:
>     case BIT_NOT_EXPR:
>       op = DW_OP_not;
>       goto do_unop;

Revised patch attached, using Jakub's suggestion.  The original (buggy) DWARF 
procedure for the Ada testcase I previously posted is:

        .uleb128 0x8    # (DIE (0x5b) DW_TAG_dwarf_procedure)
        .uleb128 0xc    # DW_AT_location
        .byte   0x12    # DW_OP_dup
        .byte   0x20    # DW_OP_not
        .byte   0x28    # DW_OP_bra
        .value  0x4
        .byte   0x34    # DW_OP_lit4
        .byte   0x2f    # DW_OP_skip
        .value  0x1
        .byte   0x30    # DW_OP_lit0
        .byte   0x16    # DW_OP_swap
        .byte   0x13    # DW_OP_drop

With Jakub's fix:

        .uleb128 0x8    # (DIE (0x5b) DW_TAG_dwarf_procedure)
        .uleb128 0xd    # DW_AT_location
        .byte   0x12    # DW_OP_dup
        .byte   0x30    # DW_OP_lit0
        .byte   0x29    # DW_OP_eq
        .byte   0x28    # DW_OP_bra
        .value  0x4
        .byte   0x34    # DW_OP_lit4
        .byte   0x2f    # DW_OP_skip
        .value  0x1
        .byte   0x30    # DW_OP_lit0
        .byte   0x16    # DW_OP_swap
        .byte   0x13    # DW_OP_drop

With mine:

        .uleb128 0x8    # (DIE (0x5b) DW_TAG_dwarf_procedure)
        .uleb128 0xb    # DW_AT_location
        .byte   0x12    # DW_OP_dup
        .byte   0x28    # DW_OP_bra
        .value  0x4
        .byte   0x30    # DW_OP_lit0
        .byte   0x2f    # DW_OP_skip
        .value  0x1
        .byte   0x34    # DW_OP_lit4
        .byte   0x16    # DW_OP_swap
        .byte   0x13    # DW_OP_drop


        * dwarf2out.c (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.

-- 
Eric Botcazou
diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 5681b01749a..c333c595026 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -19449,6 +19449,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;
@@ -19497,6 +19505,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)

Reply via email to