[cfe-commits] [PATCH] Remove PotentiallyPotentiallyEvaluated

Eli Friedman eli.friedman at gmail.com
Wed Jan 18 19:42:50 PST 2012


On Wed, Jan 18, 2012 at 6:58 PM, John McCall <rjmccall at apple.com> wrote:
> On Jan 18, 2012, at 5:28 PM, Eli Friedman wrote:
>> On Wed, Jan 18, 2012 at 5:22 PM, John McCall <rjmccall at apple.com> wrote:
>>> On Jan 18, 2012, at 4:53 PM, Eli Friedman wrote:
>>>> This patch passes all the regression tests except for one,
>>>> CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp, which I haven't
>>>> figured out how to fix. (The issue is that given a DeclRefExpr
>>>> pointing at a FieldDecl, there isn't any easy way to distinguish
>>>> whether it is part of member pointer formation.)
>>>
>>> A DeclRefExpr pointing at a FieldDecl should always be a part
>>> of member pointer formation.  Any other use would be a MemberExpr.
>>
>> Code:
>> struct A { int a; };
>> int y = sizeof A::a;
>
> Aha!  That this is well-formed is news to me.  Very interesting.
>
> Can you expand on the issue?  It sounds like these are generally
> valid in UE contexts now;  I would assume that there's just some
> random code that's not aware of that.
>
> John.
>
> P.S.  Doug and I talked about this rule and thought it might be
> unsound, but it appears that it's actually just another important
> client of your re-analysis.  The idea is that this code is ill-formed:
>
>  struct V { virtual void foo(); };
>  V &foo(int);
>  struct A { int x; };
>  void test() { (void) typeid(foo(A::x)); }

Yes, that's what CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp looks like.

> But it's not possible to notice that it's ill-formed except by walking back
> over the operand to typeid and retroactively complaining about the use
> of A::x in a PE context.

Well, you can sort of assume that it's unevaluated and buffer an error
for if the context ends up potentially-evaluated.  I actually
committed some code that tries to do that, but I don't think it
actually works correctly in dependent contexts.

Anyway, you can distinguish this case from member pointer formation
easily if you have the entire expression tree available; the issue is
that the whole tree isn't really available when we're transforming a
DeclRefExpr inside TreeTransform.

> Memo to Doug:  our example doesn't quite work.  The rule is that it's
> a member expression if 'this' is available and it's either PE *or* the
> context is a (non-strict) subclass of the declaring class of the field.
> In any context where it would be potentially valid as a member
> expression, it is one.  The problem is in other contexts, like the test
> above, where there's an "ambiguity" between being ill-formed
> and being an abstract member reference.  Clearly this should be
> resolved in favor of being an abstract member reference, with
> this extra check being required after deciding that something is
> really PE.  Up to you whether this rises to the level of a drafting error.

The standard is completely clear; granted, it's a bit stupid that
sizeof(A::x) is legal in some, but not all contexts.

-Eli




More information about the cfe-commits mailing list