summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Sema/Overload.h3
-rw-r--r--clang/lib/Sema/SemaInit.cpp4
-rw-r--r--clang/lib/Sema/SemaOverload.cpp11
-rw-r--r--clang/test/SemaCXX/undefined-internal.cpp17
4 files changed, 31 insertions, 4 deletions
diff --git a/clang/include/clang/Sema/Overload.h b/clang/include/clang/Sema/Overload.h
index 3ce3513c21a..56dec5bba36 100644
--- a/clang/include/clang/Sema/Overload.h
+++ b/clang/include/clang/Sema/Overload.h
@@ -653,7 +653,8 @@ namespace clang {
/// Find the best viable function on this overload set, if it exists.
OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc,
OverloadCandidateSet::iterator& Best,
- bool UserDefinedConversion = false);
+ bool UserDefinedConversion = false,
+ bool IsExtraneousCopy = false);
void NoteCandidates(Sema &S,
OverloadCandidateDisplayKind OCD,
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 6a1bc97de79..d43ce5bb49c 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -3478,7 +3478,9 @@ static ExprResult CopyObject(Sema &S,
}
OverloadCandidateSet::iterator Best;
- switch (CandidateSet.BestViableFunction(S, Loc, Best)) {
+ switch (CandidateSet.BestViableFunction(S, Loc, Best,
+ /*UserDefinedConversion=*/ false,
+ IsExtraneousCopy)) {
case OR_Success:
break;
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 60873cd969d..c59bfec8116 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -6248,7 +6248,8 @@ isBetterOverloadCandidate(Sema &S,
OverloadingResult
OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,
iterator &Best,
- bool UserDefinedConversion) {
+ bool UserDefinedConversion,
+ bool IsExtraneousCopy) {
// Find the best viable function.
Best = end();
for (iterator Cand = begin(); Cand != end(); ++Cand) {
@@ -6286,7 +6287,13 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,
// covers calls to named functions (5.2.2), operator overloading
// (clause 13), user-defined conversions (12.3.2), allocation function for
// placement new (5.3.4), as well as non-default initialization (8.5).
- if (Best->Function)
+ //
+ // As a special exception, we don't mark functions selected for extraneous
+ // copy constructor calls as used; the nature of extraneous copy constructor
+ // calls is that they are never in fact called.
+ // FIXME: This doesn't seem like the right approach. Should we be doing
+ // overload resolution at all for extraneous copies?
+ if (Best->Function && !IsExtraneousCopy)
S.MarkDeclarationReferenced(Loc, Best->Function);
return OR_Success;
diff --git a/clang/test/SemaCXX/undefined-internal.cpp b/clang/test/SemaCXX/undefined-internal.cpp
index a7e92499657..e926f18d5ff 100644
--- a/clang/test/SemaCXX/undefined-internal.cpp
+++ b/clang/test/SemaCXX/undefined-internal.cpp
@@ -105,3 +105,20 @@ namespace test6 {
a.value = A<Internal>::two;
}
}
+
+// We support (as an extension) private, undefined copy constructors when
+// a temporary is bound to a reference even in C++98. Similarly, we shouldn't
+// warn about this copy constructor being used without a definition.
+namespace PR9323 {
+ namespace {
+ struct Uncopyable {
+ Uncopyable() {}
+ private:
+ Uncopyable(const Uncopyable&); // expected-note {{declared private here}}
+ };
+ }
+ void f(const Uncopyable&) {}
+ void test() {
+ f(Uncopyable()); // expected-warning {{C++98 requires an accessible copy constructor}}
+ };
+}
OpenPOWER on IntegriCloud