Author: rsmith
Date: Wed Apr 16 20:12:17 2014
New Revision: 206435
URL: http://llvm.org/viewvc/llvm-project?rev=206435&view=rev
Log:
PR19452: Implement more of [over.match.oper]p3's restrictions on which
non-member overloaded operators can be found when no operand is of class type.
We used to fail to implement this rule if there was an operand of dependent
type.
Modified:
cfe/trunk/include/clang/AST/ExprCXX.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaLookup.cpp
cfe/trunk/lib/Sema/TreeTransform.h
cfe/trunk/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3.cpp
Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=206435&r1=206434&r2=206435&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Wed Apr 16 20:12:17 2014
@@ -2431,6 +2431,9 @@ public:
decls_iterator decls_end() const {
return UnresolvedSetIterator(Results + NumResults);
}
+ llvm::iterator_range<decls_iterator> decls() const {
+ return llvm::iterator_range<decls_iterator>(decls_begin(), decls_end());
+ }
/// \brief Gets the number of declarations in the unresolved set.
unsigned getNumDecls() const { return NumResults; }
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=206435&r1=206434&r2=206435&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Apr 16 20:12:17 2014
@@ -2564,6 +2564,9 @@ public:
void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
QualType T1, QualType T2,
UnresolvedSetImpl &Functions);
+ void addOverloadedOperatorToUnresolvedSet(UnresolvedSetImpl &Functions,
+ DeclAccessPair Operator,
+ QualType T1, QualType T2);
LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
SourceLocation GnuLabelLoc =
SourceLocation());
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=206435&r1=206434&r2=206435&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Wed Apr 16 20:12:17 2014
@@ -2390,20 +2390,24 @@ void Sema::LookupOverloadedOperatorName(
if (Operators.empty())
return;
- for (LookupResult::iterator Op = Operators.begin(), OpEnd = Operators.end();
- Op != OpEnd; ++Op) {
- NamedDecl *Found = (*Op)->getUnderlyingDecl();
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Found)) {
- if (IsAcceptableNonMemberOperatorCandidate(FD, T1, T2, Context))
- Functions.addDecl(*Op, Op.getAccess()); // FIXME: canonical FD
- } else if (FunctionTemplateDecl *FunTmpl
- = dyn_cast<FunctionTemplateDecl>(Found)) {
- // FIXME: friend operators?
- // FIXME: do we need to check IsAcceptableNonMemberOperatorCandidate,
- // later?
- if (!FunTmpl->getDeclContext()->isRecord())
- Functions.addDecl(*Op, Op.getAccess());
- }
+ for (auto I = Operators.begin(), E = Operators.end(); I != E; ++I)
+ addOverloadedOperatorToUnresolvedSet(Functions, I.getPair(), T1, T2);
+}
+
+void Sema::addOverloadedOperatorToUnresolvedSet(UnresolvedSetImpl &Functions,
+ DeclAccessPair Op,
+ QualType T1, QualType T2) {
+ NamedDecl *Found = Op->getUnderlyingDecl();
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Found)) {
+ if (IsAcceptableNonMemberOperatorCandidate(FD, T1, T2, Context))
+ Functions.addDecl(Op, Op.getAccess()); // FIXME: canonical FD
+ } else if (FunctionTemplateDecl *FunTmpl
+ = dyn_cast<FunctionTemplateDecl>(Found)) {
+ // FIXME: friend operators?
+ // FIXME: do we need to check IsAcceptableNonMemberOperatorCandidate,
+ // later?
+ if (!FunTmpl->getDeclContext()->isRecord())
+ Functions.addDecl(Op, Op.getAccess());
}
}
Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=206435&r1=206434&r2=206435&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Wed Apr 16 20:12:17 2014
@@ -9760,9 +9760,10 @@ TreeTransform<Derived>::RebuildCXXOperat
if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
assert(ULE->requiresADL());
- // FIXME: Do we have to check
- // IsAcceptableNonMemberOperatorCandidate for each of these?
- Functions.append(ULE->decls_begin(), ULE->decls_end());
+ for (auto I = ULE->decls_begin(), E = ULE->decls_end(); I != E; ++I)
+ SemaRef.addOverloadedOperatorToUnresolvedSet(
+ Functions, I.getPair(), First->getType(),
+ Second ? Second->getType() : QualType());
} else {
// If we've resolved this to a particular non-member function, just call
// that function. If we resolved it to a member function,
Modified:
cfe/trunk/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3.cpp
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3.cpp?rev=206435&r1=206434&r2=206435&view=diff
==============================================================================
--- cfe/trunk/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3.cpp
(original)
+++ cfe/trunk/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3.cpp
Wed Apr 16 20:12:17 2014
@@ -1,5 +1,29 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
-// expected-no-diagnostics
+
+namespace bullet2 {
+
+// For non-member candidates, if no operand has a class type, only those
+// non-member functions that have a matching enumeration parameter are
+// candidates.
+
+struct B { template<typename T> B(T); };
+int operator~(B); // expected-note {{declared prior to the call site}}
+template<typename T> int operator%(B, T);
+enum class E { e };
+
+// FIXME: This is the wrong diagnostic.
+template<typename T> int f(T t) { return ~t; } // expected-error {{call to}}
+template<typename T, typename U> int f(T t, U u) { return t % u; }
+
+int b1 = ~E::e; // expected-error {{invalid argument type}}
+int b2 = f(E::e); // expected-note {{in instantiation of}}
+int b3 = f(0, E::e);
+// FIXME: This should be rejected.
+int b4 = f(E::e, 0);
+
+}
+
+namespace bullet3 {
// This is specifically testing the bullet:
// "do not have the same parameter-type-list as any non-template
@@ -26,4 +50,6 @@ extern bool test2;
extern decltype(a <= a) test2;
extern A test3;
-extern decltype(a <= b) test3;
\ No newline at end of file
+extern decltype(a <= b) test3;
+
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits