LValueExprEvaluator::VisitArraySubscriptExpr assertion

In LibreOffice we have a Clang plugin calling Expr::EvaluateAsBooleanCondition, and at least with a recent trunk Clang build with assertions enabled that triggers the assert in

static bool EvaluatePointer(const Expr* E, LValue& Result, EvalInfo &Info) {
  assert(E->isRValue() && E->getType()->hasPointerRepresentation());
  return PointerExprEvaluator(Info, Result).Visit(E);
}

(in lib/AST/ExprConstant.cpp) on expressions like

   m_Strings[nEntry]

where m_Strings is of std::vector type.

What happens is that Expr::EvaluateAsBooleanCondition goes into LValueExprEvaluator::VisitArraySubscriptExpr, which calls EvaluatePointer, which asserts because m_Strings doesn't have array or pointer type.

It's not clear to me where the error lies; should LValueExprEvaluator::VisitArraySubscriptExpr even be reached for uses of user-defined operator[] overloads?

For now, I'm working around the assertion with

In LibreOffice we have a Clang plugin calling Expr::EvaluateAsBooleanCondition,
and at least with a recent trunk Clang build with assertions enabled that
triggers the assert in

static bool EvaluatePointer(const Expr* E, LValue& Result, EvalInfo

&Info) {
  assert(E->isRValue() && E->getType()->hasPointerRepresentation());
  return PointerExprEvaluator(Info, Result).Visit(E);
}

(in lib/AST/ExprConstant.cpp) on expressions like

  m_Strings[nEntry]

where m_Strings is of std::vector type.

What happens is that Expr::EvaluateAsBooleanCondition goes into
LValueExprEvaluator::VisitArraySubscriptExpr, which calls
EvaluatePointer, which asserts because m_Strings doesn't have array or
pointer type.

It's not clear to me where the error lies; should LValueExprEvaluator::VisitArraySubscriptExpr
even be reached for uses of user-defined operator[] overloads?

No. Are you calling EvaluateAsBooleanCondition on a value-dependent
expression, perhaps? We should probably add an assert for that.

    In LibreOffice we have a Clang plugin calling
    Expr::__EvaluateAsBooleanCondition, and at least with a recent trunk
    Clang build with assertions enabled that triggers the assert in

        static bool EvaluatePointer(const Expr* E, LValue& Result,
        EvalInfo &Info) {
           assert(E->isRValue() &&
        E->getType()->__hasPointerRepresentation());
           return PointerExprEvaluator(Info, Result).Visit(E);
        }

    (in lib/AST/ExprConstant.cpp) on expressions like

       m_Strings[nEntry]

    where m_Strings is of std::vector type.

    What happens is that Expr::__EvaluateAsBooleanCondition goes into
    LValueExprEvaluator::__VisitArraySubscriptExpr, which calls
    EvaluatePointer, which asserts because m_Strings doesn't have array
    or pointer type.

    It's not clear to me where the error lies; should
    LValueExprEvaluator::__VisitArraySubscriptExpr even be reached for
    uses of user-defined operator[] overloads?

No. Are you calling EvaluateAsBooleanCondition on a value-dependent
expression, perhaps? We should probably add an assert for that.

Turned out to be called on an Expr for which isTypeDependent() is true (and the problem went away after changing the plugin to no longer call EvaluateAsBooleanCondition on any type-dependent expressions).

However, I must admit that even after consulting [temp.dep.expr] it is still unclear to me why Clang considers the expression s[0] in

struct S { void operator [](int); };
template<typename> struct T {
    S s;
    void f() { s[0]; }
};

as type-dependent.