]> granicus.if.org Git - clang/commitdiff
[Sema] Fix operator lookup to consider local extern declarations.
authorEric Fiselier <eric@efcs.ca>
Mon, 31 Jul 2017 00:24:28 +0000 (00:24 +0000)
committerEric Fiselier <eric@efcs.ca>
Mon, 31 Jul 2017 00:24:28 +0000 (00:24 +0000)
Summary:
Previously Clang was not considering operator declarations that occur at function scope. This is incorrect according to [over.match.oper]p3
> The set of non-member candidates is the result of the unqualified lookup of operator@ in the context of the expression according to the usual rules for name lookup in unqualified function calls.

This patch changes operator name lookup to consider block scope declarations.
This patch fixes PR27027.

Reviewers: rsmith

Reviewed By: rsmith

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D35297

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@309530 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaLookup.cpp
test/SemaCXX/overloaded-operator.cpp

index 85596ed52e9d63e333e0e83da48b29b356c3a906..4f88edcb31f5767e281703e2ce584a06ab6b526d 100644 (file)
@@ -1031,7 +1031,8 @@ struct FindLocalExternScope {
   FindLocalExternScope(LookupResult &R)
       : R(R), OldFindLocalExtern(R.getIdentifierNamespace() &
                                  Decl::IDNS_LocalExtern) {
-    R.setFindLocalExtern(R.getIdentifierNamespace() & Decl::IDNS_Ordinary);
+    R.setFindLocalExtern(R.getIdentifierNamespace() &
+                         (Decl::IDNS_Ordinary | Decl::IDNS_NonMemberOperator));
   }
   void restore() {
     R.setFindLocalExtern(OldFindLocalExtern);
index 369e9eb802a59f9b802b45300946a8a5f768e8f5..52d0bff3884c0ece3fc661c5f6ff8d66216e416f 100644 (file)
@@ -531,3 +531,22 @@ namespace NoADLForMemberOnlyOperators {
     b3 / 0; // expected-note {{in instantiation of}} expected-error {{invalid operands to}}
   }
 }
+
+
+namespace PR27027 {
+  template <class T> void operator+(T, T) = delete; // expected-note 4 {{candidate}}
+  template <class T> void operator+(T) = delete; // expected-note 4 {{candidate}}
+
+  struct A {} a_global;
+  void f() {
+    A a;
+    +a; // expected-error {{overload resolution selected deleted operator '+'}}
+    a + a; // expected-error {{overload resolution selected deleted operator '+'}}
+    bool operator+(A);
+    extern bool operator+(A, A);
+    +a; // OK
+    a + a;
+  }
+  bool test_global_1 = +a_global; // expected-error {{overload resolution selected deleted operator '+'}}
+  bool test_global_2 = a_global + a_global; // expected-error {{overload resolution selected deleted operator '+'}}
+}