r337653 - PR38257: don't perform ADL when instantiating a unary & operator that turns out

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Sat Jul 21 22:21:48 PDT 2018


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, "");
+}




More information about the cfe-commits mailing list