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