Date: Tue, 7 Mar 2017 21:44:05 +0000 (UTC) From: Dimitry Andric <dim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r314883 - in stable/11/contrib/llvm/tools/clang: include/clang/Basic include/clang/Sema lib/Sema Message-ID: <201703072144.v27Li52M074368@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dim Date: Tue Mar 7 21:44:05 2017 New Revision: 314883 URL: https://svnweb.freebsd.org/changeset/base/314883 Log: Pull in r291403 from upstream clang trunk (by Richard Smith): PR30305: Implement proposed DR resolution to prevent slicing via inherited constructor. The rule we use is that a construction of a class type T from an argument of type U cannot use an inherited constructor if U is the same as T or is derived from T (or if the initialization would first convert it to such a type). This (approximately) matches the rule in use by GCC, and matches the current proposed DR resolution. Pull in r291955 from upstream clang trunk (by Richard Smith): PR31606: Generalize our tentative DR resolution for inheriting copy/move constructors to better match the pre-P0136R1 behavior. Together, these fix an issue with C++ using declarations sometimes enabling illegal implicit casts. Direct commit to stable/11, since head already has clang 4.0.0, which includes this change. Reported by: kami PR: 215969 Modified: stable/11/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td stable/11/contrib/llvm/tools/clang/include/clang/Sema/Overload.h stable/11/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp Modified: stable/11/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td ============================================================================== --- stable/11/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td Tue Mar 7 21:40:01 2017 (r314882) +++ stable/11/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td Tue Mar 7 21:44:05 2017 (r314883) @@ -3180,6 +3180,9 @@ def note_ovl_candidate : Note<"candidate def note_ovl_candidate_inherited_constructor : Note< "constructor from base class %0 inherited here">; +def note_ovl_candidate_inherited_constructor_slice : Note< + "candidate %select{constructor|template}0 ignored: " + "inherited constructor cannot be used to %select{copy|move}1 object">; def note_ovl_candidate_illegal_constructor : Note< "candidate %select{constructor|template}0 ignored: " "instantiation %select{takes|would take}0 its own class type by value">; Modified: stable/11/contrib/llvm/tools/clang/include/clang/Sema/Overload.h ============================================================================== --- stable/11/contrib/llvm/tools/clang/include/clang/Sema/Overload.h Tue Mar 7 21:40:01 2017 (r314882) +++ stable/11/contrib/llvm/tools/clang/include/clang/Sema/Overload.h Tue Mar 7 21:44:05 2017 (r314883) @@ -586,7 +586,11 @@ namespace clang { ovl_fail_enable_if, /// This candidate was not viable because its address could not be taken. - ovl_fail_addr_not_available + ovl_fail_addr_not_available, + + /// This inherited constructor is not viable because it would slice the + /// argument. + ovl_fail_inhctor_slice, }; /// OverloadCandidate - A single candidate in an overload set (C++ 13.3). Modified: stable/11/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp ============================================================================== --- stable/11/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp Tue Mar 7 21:40:01 2017 (r314882) +++ stable/11/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp Tue Mar 7 21:44:05 2017 (r314883) @@ -5783,6 +5783,28 @@ Sema::AddOverloadCandidate(FunctionDecl Candidate.FailureKind = ovl_fail_illegal_constructor; return; } + + // C++ [over.match.funcs]p8: (proposed DR resolution) + // A constructor inherited from class type C that has a first parameter + // of type "reference to P" (including such a constructor instantiated + // from a template) is excluded from the set of candidate functions when + // constructing an object of type cv D if the argument list has exactly + // one argument and D is reference-related to P and P is reference-related + // to C. + auto *Shadow = dyn_cast<ConstructorUsingShadowDecl>(FoundDecl.getDecl()); + if (Shadow && Args.size() == 1 && Constructor->getNumParams() >= 1 && + Constructor->getParamDecl(0)->getType()->isReferenceType()) { + QualType P = Constructor->getParamDecl(0)->getType()->getPointeeType(); + QualType C = Context.getRecordType(Constructor->getParent()); + QualType D = Context.getRecordType(Shadow->getParent()); + SourceLocation Loc = Args.front()->getExprLoc(); + if ((Context.hasSameUnqualifiedType(P, C) || IsDerivedFrom(Loc, P, C)) && + (Context.hasSameUnqualifiedType(D, P) || IsDerivedFrom(Loc, D, P))) { + Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_inhctor_slice; + return; + } + } } unsigned NumParams = Proto->getNumParams(); @@ -9750,6 +9772,17 @@ static void NoteFunctionCandidate(Sema & case ovl_fail_enable_if: return DiagnoseFailedEnableIfAttr(S, Cand); + case ovl_fail_inhctor_slice: + // It's generally not interesting to note copy/move constructors here. + if (cast<CXXConstructorDecl>(Fn)->isCopyOrMoveConstructor()) + return; + S.Diag(Fn->getLocation(), + diag::note_ovl_candidate_inherited_constructor_slice) + << (Fn->getPrimaryTemplate() ? 1 : 0) + << Fn->getParamDecl(0)->getType()->isRValueReferenceType(); + MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); + return; + case ovl_fail_addr_not_available: { bool Available = checkAddressOfCandidateIsAvailable(S, Cand->Function); (void)Available;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201703072144.v27Li52M074368>