On 03/30/2016 01:25 PM, Jason Merrill wrote:
On 03/30/2016 12:32 PM, Martin Sebor wrote:
On 03/30/2016 09:30 AM, Jason Merrill wrote:
On 03/29/2016 11:57 PM, Martin Sebor wrote:
Are we confident that arr[0] won't make it here as
POINTER_PLUS_EXPR or
some such?
I'm as confident as I can be given that this is my first time
working in this area. Which piece of code or what assumption
in particular are you concerned about?
I want to be sure that we don't fold these conditions to false.
constexpr int *ip = 0;
constexpr struct A { int ar[3]; } *ap = 0;
static_assert(&ip[0] == 0);
static_assert(&(ap->ar[0]) == 0);
I see. Thanks for clarifying. The asserts pass. The expressions
are folded earlier on (in fact, as we discussed, the second one
too early and is accepted even though it's undefined and should be
rejected in a constexpr context) and never reach fold_comparison.
Good, then let's add at least the first to one of the tests.
+ /* Avoid folding references to struct members at offset 0 to
+ prevent tests like '&ptr->firstmember == 0' from getting
+ eliminated. When ptr is null, although the -> expression
+ is strictly speaking invalid, GCC retains it as a matter
+ of QoI. See PR c/44555. */
+ && (TREE_CODE (op0) != ADDR_EXPR
+ || TREE_CODE (TREE_OPERAND (op0, 0)) != COMPONENT_REF
+ || compare_tree_int (DECL_FIELD_OFFSET ((TREE_OPERAND
+ (TREE_OPERAND (op0, 0), 1))), 0))
Can we look at offset/bitpos here rather than examine the tree structure
of op0? get_inner_reference already examined it for us.
Also, it looks like you aren't handling the case with the operands
switched, i.e. 0 == p and such.
Presumably all this stuff runs prior to the call to shorten_compare and
friends which would canonicalize 0 == p into p == 0?
And yes, I still want to separate the canonicalization, warning and
optimization that's done by shorten_compare and friends. It just fell
out of gcc-6 due to lack of time.
jeff
Jason