Author: rsmith Date: Sat Jul 21 22:21:47 2018 New Revision: 337653 URL: http://llvm.org/viewvc/llvm-project?rev=337653&view=rev Log: PR38257: don't perform ADL when instantiating a unary & operator that turns out to be forming a pointer-to-member.
Added: cfe/trunk/test/SemaTemplate/argument-dependent-lookup.cpp Modified: cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/lib/Sema/TreeTransform.h Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=337653&r1=337652&r2=337653&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Sat Jul 21 22:21:47 2018 @@ -4262,6 +4262,7 @@ public: ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, Expr *Input); + bool isQualifiedMemberAccess(Expr *E); QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc); ExprResult CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo, Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=337653&r1=337652&r2=337653&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Jul 21 22:21:47 2018 @@ -12809,7 +12809,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(So /// Determine whether the given expression is a qualified member /// access expression, of a form that could be turned into a pointer to member /// with the address-of operator. -static bool isQualifiedMemberAccess(Expr *E) { +bool Sema::isQualifiedMemberAccess(Expr *E) { if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { if (!DRE->getQualifier()) return false; Modified: cfe/trunk/lib/Sema/TreeTransform.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=337653&r1=337652&r2=337653&view=diff ============================================================================== --- cfe/trunk/lib/Sema/TreeTransform.h (original) +++ cfe/trunk/lib/Sema/TreeTransform.h Sat Jul 21 22:21:47 2018 @@ -12658,9 +12658,11 @@ TreeTransform<Derived>::RebuildCXXOperat // -> is never a builtin operation. return SemaRef.BuildOverloadedArrowExpr(nullptr, First, OpLoc); } else if (Second == nullptr || isPostIncDec) { - if (!First->getType()->isOverloadableType()) { - // The argument is not of overloadable type, so try to create a - // built-in unary operation. + if (!First->getType()->isOverloadableType() || + (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) { + // The argument is not of overloadable type, or this is an expression + // of the form &Class::member, so try to create a built-in unary + // operation. UnaryOperatorKind Opc = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec); Added: cfe/trunk/test/SemaTemplate/argument-dependent-lookup.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/argument-dependent-lookup.cpp?rev=337653&view=auto ============================================================================== --- cfe/trunk/test/SemaTemplate/argument-dependent-lookup.cpp (added) +++ cfe/trunk/test/SemaTemplate/argument-dependent-lookup.cpp Sat Jul 21 22:21:47 2018 @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -verify %s +// RUN: %clang_cc1 -verify %s -DHAVE_UNQUALIFIED_LOOKUP_RESULTS +// expected-no-diagnostics + +namespace address_of { +#ifdef HAVE_UNQUALIFIED_LOOKUP_RESULTS + struct Q {}; + void operator&(Q); +#endif + + template<typename T> struct A { + static constexpr auto x = &T::value; + }; + + template<typename T> struct B { + constexpr int operator&() { return 123; } + }; + + template<typename T> struct C { + static_assert(sizeof(T) == 123, ""); + }; + + struct X1 { + static B<X1> value; + }; + struct X2 : B<X2> { + enum E { value }; + friend constexpr int operator&(E) { return 123; } + }; + + struct Y1 { + C<int> *value; + }; + struct Y2 { + C<int> value(); + }; + + // ok, uses ADL to find operator&: + static_assert(A<X1>::x == 123, ""); + static_assert(A<X2>::x == 123, ""); + + // ok, does not use ADL so does not instantiate C<T>: + static_assert(A<Y1>::x == &Y1::value, ""); + static_assert(A<Y2>::x == &Y2::value, ""); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits