]> granicus.if.org Git - clang/commitdiff
Don't suggest putting 'operator new' or 'operator delete' in a namespace to fix a...
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 12 Jun 2013 22:56:54 +0000 (22:56 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 12 Jun 2013 22:56:54 +0000 (22:56 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183874 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaOverload.cpp
test/SemaTemplate/dependent-names.cpp

index 9e3ca9dd4060d67a31133c37f30eb5bc3ac5712f..b9983ef0559c28c3cf427dd442dbdc25cf6eaa54 100644 (file)
@@ -9766,6 +9766,19 @@ void Sema::AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE,
                                          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, SourceLocation FnLoc,
                                                  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;
 
-        SuggestedNamespaces.insert(*it);
+          // 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);
+        }
       }
 
       SemaRef.Diag(R.getNameLoc(), diag::err_not_found_by_two_phase_lookup)
index 769584d93caeeb40ab29db1368b5a5560ec32808..4d4aafa918cb4ad8ddc1d0c15db259f4a17654ed 100644 (file)
@@ -387,3 +387,15 @@ namespace PR14695_A { void PR14695_f(PR14695_X); } // expected-note {{'PR14695_f
 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}}