r183874 - Don't suggest putting 'operator new' or 'operator delete' in a namespace to fix a two-phase lookup issue. That's not permitted.

Richard Smith richard-llvm at metafoo.co.uk
Wed Jun 12 15:56:54 PDT 2013


Author: rsmith
Date: Wed Jun 12 17:56:54 2013
New Revision: 183874

URL: http://llvm.org/viewvc/llvm-project?rev=183874&view=rev
Log:
Don't suggest putting 'operator new' or 'operator delete' in a namespace to fix a two-phase lookup issue. That's not permitted.

Modified:
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/SemaTemplate/dependent-names.cpp

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=183874&r1=183873&r2=183874&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Wed Jun 12 17:56:54 2013
@@ -9766,6 +9766,19 @@ void Sema::AddOverloadedCallCandidates(U
                                          CandidateSet, PartialOverloading);
 }
 
+/// Determine whether a declaration with the specified name could be moved into
+/// a different namespace.
+static bool canBeDeclaredInNamespace(const DeclarationName &Name) {
+  switch (Name.getCXXOverloadedOperator()) {
+  case OO_New: case OO_Array_New:
+  case OO_Delete: case OO_Array_Delete:
+    return false;
+
+  default:
+    return true;
+  }
+}
+
 /// Attempt to recover from an ill-formed use of a non-dependent name in a
 /// template, where the non-dependent name was declared after the template
 /// was defined. This is common in code written for a compilers which do not
@@ -9818,22 +9831,24 @@ DiagnoseTwoPhaseLookup(Sema &SemaRef, So
                                                  AssociatedNamespaces,
                                                  AssociatedClasses);
       Sema::AssociatedNamespaceSet SuggestedNamespaces;
-      DeclContext *Std = SemaRef.getStdNamespace();
-      for (Sema::AssociatedNamespaceSet::iterator
-             it = AssociatedNamespaces.begin(),
-             end = AssociatedNamespaces.end(); it != end; ++it) {
-        // Never suggest declaring a function within namespace 'std'.
-        if (Std && Std->Encloses(*it))
-          continue;
-        
-        // Never suggest declaring a function within a namespace with a reserved
-        // name, like __gnu_cxx.
-        NamespaceDecl *NS = dyn_cast<NamespaceDecl>(*it);
-        if (NS &&
-            NS->getQualifiedNameAsString().find("__") != std::string::npos)
-          continue;
+      if (canBeDeclaredInNamespace(R.getLookupName())) {
+        DeclContext *Std = SemaRef.getStdNamespace();
+        for (Sema::AssociatedNamespaceSet::iterator
+               it = AssociatedNamespaces.begin(),
+               end = AssociatedNamespaces.end(); it != end; ++it) {
+          // Never suggest declaring a function within namespace 'std'.
+          if (Std && Std->Encloses(*it))
+            continue;
+
+          // Never suggest declaring a function within a namespace with a
+          // reserved name, like __gnu_cxx.
+          NamespaceDecl *NS = dyn_cast<NamespaceDecl>(*it);
+          if (NS &&
+              NS->getQualifiedNameAsString().find("__") != std::string::npos)
+            continue;
 
-        SuggestedNamespaces.insert(*it);
+          SuggestedNamespaces.insert(*it);
+        }
       }
 
       SemaRef.Diag(R.getNameLoc(), diag::err_not_found_by_two_phase_lookup)

Modified: cfe/trunk/test/SemaTemplate/dependent-names.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/dependent-names.cpp?rev=183874&r1=183873&r2=183874&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/dependent-names.cpp (original)
+++ cfe/trunk/test/SemaTemplate/dependent-names.cpp Wed Jun 12 17:56:54 2013
@@ -387,3 +387,15 @@ namespace PR14695_A { void PR14695_f(PR1
 template<typename T> void PR14695_g(T t) { PR14695_f(t); } // expected-error {{call to function 'PR14695_f' that is neither visible in the template definition nor found by argument-dependent lookup}}
 using namespace PR14695_A;
 template void PR14695_g(PR14695_X); // expected-note{{requested here}}
+
+namespace OperatorNew {
+  template<typename T> void f(T t) {
+    operator new(100, t); // expected-error{{call to function 'operator new' that is neither visible in the template definition nor found by argument-dependent lookup}}
+    // FIXME: This should give the same error.
+    new (t) int;
+  }
+  struct X {};
+};
+using size_t = decltype(sizeof(0));
+void *operator new(size_t, OperatorNew::X); // expected-note-re {{should be declared prior to the call site$}}
+template void OperatorNew::f(OperatorNew::X); // expected-note {{instantiation of}}





More information about the cfe-commits mailing list