This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ front end: NON_DEPENDENT_EXPR and lvalue_p_1


A question for the C++ maintainers considering the lvalue-ness of
NON_DEPENDENT_EXPR expressions...

As part of tightening up our checking of non-dependent expressions
within templates (and necessary step for C++0x, and a good idea in
C++98 anyway), I bumped into this bit of code in lvalue_p_1:

   case NON_DEPENDENT_EXPR:
     /* We must consider NON_DEPENDENT_EXPRs to be lvalues so that
	 things like "&E" where "E" is an expression with a
	 non-dependent type work. It is safe to be lenient because an
	 error will be issued when the template is instantiated if "E"
	 is not an lvalue.  */
     return clk_ordinary;

In C++98, it's okay to assume that any non-dependent expression is an
lvalue, because lvalues can be used anywhere where rvalues can be
used. As the comment says, the worst thing that happens is that we
issue a diagnostic late (at instantiation time), which we're allowed
to do.

C++0x changes things. First of all, we need to be able to fully
type-check non-dependent expressions within templates to make concepts
work properly, so it is no longer safe to be lenient here. A more
immediate concern is rvalue references: since you can now overload on
lvalues vs. rvalues, treating all NON_DEPENDENT_EXPRs as lvalues means
that we could end up picking the wrong overload when type-checking a
template. I don't have a test case on hand, but I'm pretty certain I
could create an error-on-valid-code inside a template. (I have one
such test case, but it currently relies on concepts).

Now, one cannot determine the lvalueness of a NON_DEPENDENT_EXPR from
its operand, because the operand is the tree that the parser has
produced, not the tree that has resulted from semantic analysis. And,
of course, the type of the NON_DEPENDENT_EXPR is only a type... it
doesn't contain lvalue or rvalue information.

So, I think the right answer is to add a field to NON_DEPENDENT_EXPR
that essentially caches the result of lvalue_p_1 for the expression it
represents. We'll need to know what the result of lvalue_p_1 is for
both treat_class_rvalues_as_lvalues true and false. The logic for this
can probably be built right into build_min_non_dep.

Does this seem like the right way to go?

- Doug


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]