Skip to content

Commit 528a97f

Browse files
committed
[Clang][Sema] Fix arrow operator for expressions with non-pointer type that is the current instantiation
1 parent 9de1221 commit 528a97f

File tree

2 files changed

+72
-3
lines changed

2 files changed

+72
-3
lines changed

clang/lib/Sema/SemaExprMember.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -991,7 +991,9 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
991991
bool SuppressQualifierCheck,
992992
ActOnMemberAccessExtraArgs *ExtraArgs) {
993993
assert(!SS.isInvalid() && "nested-name-specifier cannot be invalid");
994-
if (R.wasNotFoundInCurrentInstantiation())
994+
if (R.wasNotFoundInCurrentInstantiation() ||
995+
(IsArrow && !BaseExprType->isPointerType() &&
996+
BaseExprType->isDependentType()))
995997
return ActOnDependentMemberExpr(BaseExpr, BaseExprType, IsArrow, OpLoc, SS,
996998
TemplateKWLoc, FirstQualifierInScope,
997999
R.getLookupNameInfo(), TemplateArgs);

clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ namespace N2 {
439439
a->B::C::x;
440440
}
441441
};
442-
}
442+
} // namespace N2
443443

444444
namespace N3 {
445445
struct A { };
@@ -453,4 +453,71 @@ namespace N3 {
453453
this->A::operator=(*this);
454454
}
455455
};
456-
}
456+
} // namespace N3
457+
458+
namespace N4 {
459+
template<typename T>
460+
struct A {
461+
void not_instantiated(A a, A<T> b, T c) {
462+
a->x;
463+
b->x;
464+
c->x;
465+
}
466+
467+
void instantiated(A a, A<T> b, T c) {
468+
a->x; // expected-error {{member reference type 'A<int>' is not a pointer; did you mean to use '.'?}}
469+
// expected-error@-1 {{no member named 'x' in 'N4::A<int>'}}
470+
b->x; // expected-error {{member reference type 'A<int>' is not a pointer; did you mean to use '.'?}}
471+
// expected-error@-1 {{no member named 'x' in 'N4::A<int>'}}
472+
c->x; // expected-error {{member reference type 'int' is not a pointer}}
473+
}
474+
};
475+
476+
template void A<int>::instantiated(A<int>, A<int>, int); // expected-note {{in instantiation of}}
477+
478+
struct B {
479+
int x;
480+
481+
void f();
482+
};
483+
484+
template<typename T>
485+
struct C {
486+
B *operator->();
487+
488+
void not_instantiated(C a, C<T> b, T c) {
489+
a->x;
490+
b->x;
491+
c->x;
492+
}
493+
494+
void instantiated(C a, C<T> b, T c) {
495+
a->x;
496+
b->x;
497+
c->x; // expected-error {{member reference type 'int' is not a pointer}}
498+
}
499+
};
500+
501+
template void C<int>::instantiated(C, C, int); // expected-note {{in instantiation of}}
502+
503+
template<typename T>
504+
struct D {
505+
T *operator->();
506+
507+
void not_instantiated(D a) {
508+
a->x;
509+
a->y;
510+
a->f();
511+
a->g();
512+
}
513+
514+
void instantiated(D a) {
515+
a->x;
516+
a->y; // expected-error {{no member named 'y' in 'N4::B'}}
517+
a->f();
518+
a->g(); // expected-error {{no member named 'g' in 'N4::B'}}
519+
}
520+
};
521+
522+
template void D<B>::instantiated(D); // expected-note {{in instantiation of}}
523+
} // namespace N4

0 commit comments

Comments
 (0)