Skip to content

SFINAEing p.x on a pointer wrongly tries to complete the pointee's type #52970

@Quuxplusone

Description

@Quuxplusone

This program hard-errors trying to complete Holder<Incomplete>; but it shouldn't.

struct Incomplete;
template<class T> struct Holder { T t; int x; };
template<class T> auto f(T t) -> decltype(t.x);
void f(...);
void test() {
    ::f((Holder<Incomplete>*)nullptr);
}

It appears to me that the problem is here, in LookupMemberExpr:

  // Recover from dot accesses to pointers, e.g.:
  //   type *foo;
  //   foo.bar
  [...]
    if (!IsArrow && Ptr->getPointeeType()->isRecordType() &&
        MemberName.getNameKind() != DeclarationName::CXXDestructorName) {
      S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
          << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
          << FixItHint::CreateReplacement(OpLoc, "->");

      // Recurse as an -> access.
      IsArrow = true;
      return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
                              ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
    }
  }

That second recursive call to LookupMemberExpr triggers completion of the pointed-to type, which is not OK if we're in a SFINAE context.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions