diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/Sema/Overload.h | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 11 | ||||
-rw-r--r-- | clang/test/SemaCXX/undefined-internal.cpp | 17 |
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}} + }; +} |