Author: rsmith Date: Tue Dec 5 15:54:25 2017 New Revision: 319858 URL: http://llvm.org/viewvc/llvm-project?rev=319858&view=rev Log: P0722R2: The first parameter in an implicit call to a destroying operator delete should be a cv-unqualified pointer to the deleted object.
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp cfe/trunk/test/SemaCXX/cxx2a-destroying-delete.cpp Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=319858&r1=319857&r2=319858&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Dec 5 15:54:25 2017 @@ -3293,6 +3293,15 @@ Sema::ActOnCXXDelete(SourceLocation Star // is trivial and left to AST consumers to handle. QualType ParamType = OperatorDelete->getParamDecl(0)->getType(); if (!IsVirtualDelete && !ParamType->getPointeeType()->isVoidType()) { + Qualifiers Qs = Pointee.getQualifiers(); + if (Qs.hasCVRQualifiers()) { + // Qualifiers are irrelevant to this conversion; we're only looking + // for access and ambiguity. + Qs.removeCVRQualifiers(); + QualType Unqual = Context.getPointerType( + Context.getQualifiedType(Pointee.getUnqualifiedType(), Qs)); + Ex = ImpCastExprToType(Ex.get(), Unqual, CK_NoOp); + } Ex = PerformImplicitConversion(Ex.get(), ParamType, AA_Passing); if (Ex.isInvalid()) return ExprError(); Modified: cfe/trunk/test/SemaCXX/cxx2a-destroying-delete.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx2a-destroying-delete.cpp?rev=319858&r1=319857&r2=319858&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/cxx2a-destroying-delete.cpp (original) +++ cfe/trunk/test/SemaCXX/cxx2a-destroying-delete.cpp Tue Dec 5 15:54:25 2017 @@ -101,3 +101,22 @@ namespace delete_selection { }; void delete_I(I *i) { delete i; } // expected-error {{deleted}} } + +namespace first_param_conversion { + struct A { + void operator delete(A *, std::destroying_delete_t); + }; + void f(const volatile A *a) { + delete a; // ok + } + + struct B { + void operator delete(B *, std::destroying_delete_t); + }; + struct C : B {}; + struct D : B {}; + struct E : C, D {}; + void g(E *e) { + delete e; // expected-error {{ambiguous conversion from derived class 'first_param_conversion::E' to base class 'first_param_conversion::B':}} + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits