diff --git a/gcc/ada/utils2.c b/gcc/ada/utils2.c index 8ad4c68c867..4a4bd7d896c 100644 --- a/gcc/ada/utils2.c +++ b/gcc/ada/utils2.c @@ -158,6 +158,7 @@ known_alignment (tree exp) switch (TREE_CODE (exp)) { case CONVERT_EXPR: + case VIEW_CONVERT_EXPR: case NOP_EXPR: case NON_LVALUE_EXPR: /* Conversions between pointers and integers don't change the alignment @@ -165,6 +166,11 @@ known_alignment (tree exp) this_alignment = known_alignment (TREE_OPERAND (exp, 0)); break; + case COMPOUND_EXPR: + /* The value of a COMPOUND_EXPR is that of it's second operand. */ + this_alignment = known_alignment (TREE_OPERAND (exp, 1)); + break; + case PLUS_EXPR: case MINUS_EXPR: /* If two address are added, the alignment of the result is the @@ -174,6 +180,13 @@ known_alignment (tree exp) this_alignment = MIN (lhs, rhs); break; + case COND_EXPR: + /* If there is a choice between two values, use the smallest one. */ + lhs = known_alignment (TREE_OPERAND (exp, 1)); + rhs = known_alignment (TREE_OPERAND (exp, 2)); + this_alignment = MIN (lhs, rhs); + break; + case INTEGER_CST: /* The first part of this represents the lowest bit in the constant, but is it in bytes, not bits. */ @@ -195,6 +208,14 @@ known_alignment (tree exp) this_alignment = MIN (BIGGEST_ALIGNMENT, lhs * rhs); break; + case BIT_AND_EXPR: + /* A bit-and expression is as aligned as the maximum alignment of the + operands. We typically get here for a complex lhs and a constant + negative power of two on the rhs to force an explicit alignment, so + don't bother looking at the lhs. */ + this_alignment = known_alignment (TREE_OPERAND (exp, 1)); + break; + case ADDR_EXPR: this_alignment = expr_align (TREE_OPERAND (exp, 0)); break;