Author: rsmith Date: Tue Sep 27 21:20:06 2016 New Revision: 282564 URL: http://llvm.org/viewvc/llvm-project?rev=282564&view=rev Log: Revert r282556. This change made several bots unhappy.
Modified: cfe/trunk/include/clang/AST/ExprCXX.h cfe/trunk/lib/CodeGen/CGCall.cpp cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CGExprCXX.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp cfe/trunk/test/CodeGenCXX/cxx1z-eval-order.cpp cfe/trunk/test/CodeGenObjCXX/property-object-reference-2.mm cfe/trunk/www/cxx_status.html Modified: cfe/trunk/include/clang/AST/ExprCXX.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=282564&r1=282563&r2=282564&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/ExprCXX.h (original) +++ cfe/trunk/include/clang/AST/ExprCXX.h Tue Sep 27 21:20:06 2016 @@ -76,16 +76,6 @@ public: /// expression refers to. OverloadedOperatorKind getOperator() const { return Operator; } - static bool isAssignmentOp(OverloadedOperatorKind Opc) { - return Opc == OO_Equal || Opc == OO_StarEqual || - Opc == OO_SlashEqual || Opc == OO_PercentEqual || - Opc == OO_PlusEqual || Opc == OO_MinusEqual || - Opc == OO_LessLessEqual || Opc == OO_GreaterGreaterEqual || - Opc == OO_AmpEqual || Opc == OO_CaretEqual || - Opc == OO_PipeEqual; - } - bool isAssignmentOp() const { return isAssignmentOp(getOperator()); } - /// \brief Returns the location of the operator symbol in the expression. /// /// When \c getOperator()==OO_Call, this is the location of the right Modified: cfe/trunk/lib/CodeGen/CGCall.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=282564&r1=282563&r2=282564&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGCall.cpp (original) +++ cfe/trunk/lib/CodeGen/CGCall.cpp Tue Sep 27 21:20:06 2016 @@ -3172,8 +3172,7 @@ void CodeGenFunction::EmitNonNullArgChec void CodeGenFunction::EmitCallArgs( CallArgList &Args, ArrayRef<QualType> ArgTypes, llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange, - const FunctionDecl *CalleeDecl, unsigned ParamsToSkip, - bool ForceRightToLeftEvaluation) { + const FunctionDecl *CalleeDecl, unsigned ParamsToSkip) { assert((int)ArgTypes.size() == (ArgRange.end() - ArgRange.begin())); auto MaybeEmitImplicitObjectSize = [&](unsigned I, const Expr *Arg) { @@ -3192,8 +3191,7 @@ void CodeGenFunction::EmitCallArgs( // We *have* to evaluate arguments from right to left in the MS C++ ABI, // because arguments are destroyed left to right in the callee. - if (CGM.getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee() || - ForceRightToLeftEvaluation) { + if (CGM.getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) { // Insert a stack save if we're going to need any inalloca args. bool HasInAllocaArgs = false; for (ArrayRef<QualType>::iterator I = ArgTypes.begin(), E = ArgTypes.end(); Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=282564&r1=282563&r2=282564&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Sep 27 21:20:06 2016 @@ -4121,17 +4121,8 @@ RValue CodeGenFunction::EmitCall(QualTyp if (Chain) Args.add(RValue::get(Builder.CreateBitCast(Chain, CGM.VoidPtrTy)), CGM.getContext().VoidPtrTy); - - // C++17 requires that we evaluate arguments to a call using assignment syntax - // right-to-left. It also requires that we evaluate arguments to operators - // <<, >>, and ->* left-to-right, but that is not possible under the MS ABI, - // so there is no corresponding "force left-to-right" case. - bool ForceRightToLeft = false; - if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) - ForceRightToLeft = OCE->isAssignmentOp(); - EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), E->arguments(), - E->getDirectCallee(), /*ParamsToSkip*/ 0, ForceRightToLeft); + E->getDirectCallee(), /*ParamsToSkip*/ 0); const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeFreeFunctionCall( Args, FnType, /*isChainCall=*/Chain); Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=282564&r1=282563&r2=282564&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Tue Sep 27 21:20:06 2016 @@ -28,7 +28,7 @@ static RequiredArgs commonEmitCXXMemberOrOperatorCall(CodeGenFunction &CGF, const CXXMethodDecl *MD, llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *CE, - CallArgList &Args, CallArgList *RtlArgs) { + CallArgList &Args) { assert(CE == nullptr || isa<CXXMemberCallExpr>(CE) || isa<CXXOperatorCallExpr>(CE)); assert(MD->isInstance() && @@ -61,12 +61,7 @@ commonEmitCXXMemberOrOperatorCall(CodeGe RequiredArgs required = RequiredArgs::forPrototypePlus(FPT, Args.size(), MD); // And the rest of the call args. - if (RtlArgs) { - // Special case: if the caller emitted the arguments right-to-left already - // (prior to emitting the *this argument), we're done. This happens for - // assignment operators. - Args.addFrom(*RtlArgs); - } else if (CE) { + if (CE) { // Special case: skip first argument of CXXOperatorCall (it is "this"). unsigned ArgsToSkip = isa<CXXOperatorCallExpr>(CE) ? 1 : 0; CGF.EmitCallArgs(Args, FPT, drop_begin(CE->arguments(), ArgsToSkip), @@ -82,11 +77,11 @@ commonEmitCXXMemberOrOperatorCall(CodeGe RValue CodeGenFunction::EmitCXXMemberOrOperatorCall( const CXXMethodDecl *MD, llvm::Value *Callee, ReturnValueSlot ReturnValue, llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy, - const CallExpr *CE, CallArgList *RtlArgs) { + const CallExpr *CE) { const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); CallArgList Args; RequiredArgs required = commonEmitCXXMemberOrOperatorCall( - *this, MD, This, ImplicitParam, ImplicitParamTy, CE, Args, RtlArgs); + *this, MD, This, ImplicitParam, ImplicitParamTy, CE, Args); return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required), Callee, ReturnValue, Args, MD); } @@ -97,7 +92,7 @@ RValue CodeGenFunction::EmitCXXDestructo StructorType Type) { CallArgList Args; commonEmitCXXMemberOrOperatorCall(*this, DD, This, ImplicitParam, - ImplicitParamTy, CE, Args, nullptr); + ImplicitParamTy, CE, Args); return EmitCall(CGM.getTypes().arrangeCXXStructorDeclaration(DD, Type), Callee, ReturnValueSlot(), Args, DD); } @@ -175,19 +170,6 @@ RValue CodeGenFunction::EmitCXXMemberOrO } } - // C++17 demands that we evaluate the RHS of a (possibly-compound) assignment - // operator before the LHS. - CallArgList RtlArgStorage; - CallArgList *RtlArgs = nullptr; - if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(CE)) { - if (OCE->isAssignmentOp()) { - RtlArgs = &RtlArgStorage; - EmitCallArgs(*RtlArgs, MD->getType()->castAs<FunctionProtoType>(), - drop_begin(CE->arguments(), 1), CE->getDirectCallee(), - /*ParamsToSkip*/0, /*ForceRightToLeftEvaluation*/true); - } - } - Address This = Address::invalid(); if (IsArrow) This = EmitPointerWithAlignment(Base); @@ -205,12 +187,10 @@ RValue CodeGenFunction::EmitCXXMemberOrO if (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()) { // We don't like to generate the trivial copy/move assignment operator // when it isn't necessary; just produce the proper effect here. - LValue RHS = isa<CXXOperatorCallExpr>(CE) - ? MakeNaturalAlignAddrLValue( - (*RtlArgs)[0].RV.getScalarVal(), - (*(CE->arg_begin() + 1))->getType()) - : EmitLValue(*CE->arg_begin()); - EmitAggregateAssign(This, RHS.getAddress(), CE->getType()); + // Special case: skip first argument of CXXOperatorCall (it is "this"). + unsigned ArgsToSkip = isa<CXXOperatorCallExpr>(CE) ? 1 : 0; + Address RHS = EmitLValue(*(CE->arg_begin() + ArgsToSkip)).getAddress(); + EmitAggregateAssign(This, RHS, CE->getType()); return RValue::get(This.getPointer()); } @@ -269,8 +249,7 @@ RValue CodeGenFunction::EmitCXXMemberOrO Callee = CGM.GetAddrOfFunction(GlobalDecl(DDtor, Dtor_Complete), Ty); } EmitCXXMemberOrOperatorCall(MD, Callee, ReturnValue, This.getPointer(), - /*ImplicitParam=*/nullptr, QualType(), CE, - nullptr); + /*ImplicitParam=*/nullptr, QualType(), CE); } return RValue::get(nullptr); } @@ -303,8 +282,7 @@ RValue CodeGenFunction::EmitCXXMemberOrO } return EmitCXXMemberOrOperatorCall(MD, Callee, ReturnValue, This.getPointer(), - /*ImplicitParam=*/nullptr, QualType(), CE, - RtlArgs); + /*ImplicitParam=*/nullptr, QualType(), CE); } RValue Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=282564&r1=282563&r2=282564&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original) +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Sep 27 21:20:06 2016 @@ -2867,8 +2867,7 @@ public: EmitCXXMemberOrOperatorCall(const CXXMethodDecl *MD, llvm::Value *Callee, ReturnValueSlot ReturnValue, llvm::Value *This, llvm::Value *ImplicitParam, - QualType ImplicitParamTy, const CallExpr *E, - CallArgList *RtlArgs); + QualType ImplicitParamTy, const CallExpr *E); RValue EmitCXXDestructorCall(const CXXDestructorDecl *DD, llvm::Value *Callee, llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *E, @@ -3323,8 +3322,7 @@ public: void EmitCallArgs(CallArgList &Args, const T *CallArgTypeInfo, llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange, const FunctionDecl *CalleeDecl = nullptr, - unsigned ParamsToSkip = 0, - bool ForceRightToLeftEvaluation = false) { + unsigned ParamsToSkip = 0) { SmallVector<QualType, 16> ArgTypes; CallExpr::const_arg_iterator Arg = ArgRange.begin(); @@ -3364,15 +3362,13 @@ public: for (auto *A : llvm::make_range(Arg, ArgRange.end())) ArgTypes.push_back(getVarArgType(A)); - EmitCallArgs(Args, ArgTypes, ArgRange, CalleeDecl, ParamsToSkip, - ForceRightToLeftEvaluation); + EmitCallArgs(Args, ArgTypes, ArgRange, CalleeDecl, ParamsToSkip); } void EmitCallArgs(CallArgList &Args, ArrayRef<QualType> ArgTypes, llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange, const FunctionDecl *CalleeDecl = nullptr, - unsigned ParamsToSkip = 0, - bool ForceRightToLeftEvaluation = false); + unsigned ParamsToSkip = 0); /// EmitPointerWithAlignment - Given an expression with a pointer /// type, emit the value and compute our best estimate of the Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=282564&r1=282563&r2=282564&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original) +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Tue Sep 27 21:20:06 2016 @@ -1456,8 +1456,7 @@ void ItaniumCXXABI::EmitDestructorCall(C Callee = CGM.getAddrOfCXXStructor(DD, getFromDtorType(Type)); CGF.EmitCXXMemberOrOperatorCall(DD, Callee, ReturnValueSlot(), - This.getPointer(), VTT, VTTTy, - nullptr, nullptr); + This.getPointer(), VTT, VTTTy, nullptr); } void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT, @@ -1637,7 +1636,7 @@ llvm::Value *ItaniumCXXABI::EmitVirtualD CGF.EmitCXXMemberOrOperatorCall(Dtor, Callee, ReturnValueSlot(), This.getPointer(), /*ImplicitParam=*/nullptr, - QualType(), CE, nullptr); + QualType(), CE); return nullptr; } Modified: cfe/trunk/test/CodeGenCXX/cxx1z-eval-order.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx1z-eval-order.cpp?rev=282564&r1=282563&r2=282564&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/cxx1z-eval-order.cpp (original) +++ cfe/trunk/test/CodeGenCXX/cxx1z-eval-order.cpp Tue Sep 27 21:20:06 2016 @@ -18,8 +18,7 @@ struct B { struct C { operator int *(); A *operator->(); - void operator->*(A); - friend void operator->*(C, B); + void operator->*(B); friend void operator<<(C, B); friend void operator>>(C, B); @@ -138,17 +137,7 @@ int dotstar_lhs_before_rhs() { int b = make_a_ptr()->*make_mem_ptr_a(); // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( - // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( - make_c()->*make_a(); - - // FIXME: The corresponding case for Windows ABIs is unimplementable if the - // operand has a non-trivially-destructible type, because the order of - // construction of function arguments is defined by the ABI there (it's the - // reverse of the order in which the parameters are destroyed in the callee). - // But we could follow the C++17 rule in the case where the operand type is - // trivially-destructible. - // CHECK-ITANIUM: call {{.*}}@{{.*}}make_c{{.*}}( - // CHECK-ITANIUM: call {{.*}}@{{.*}}make_b{{.*}}( + // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( make_c()->*make_b(); // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( @@ -165,60 +154,61 @@ int dotstar_lhs_before_rhs() { // CHECK: } } - -// CHECK-LABEL: define {{.*}}@{{.*}}assign_rhs_before_lhs{{.*}}( +#if 0 +// CHECKDISABLED-LABEL: define {{.*}}@{{.*}}assign_lhs_before_rhs{{.*}}( void assign_rhs_before_lhs() { extern int &lhs_ref(), rhs(); - // CHECK: call {{.*}}@{{.*}}rhs{{.*}}( - // CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}rhs{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}lhs_ref{{.*}}( lhs_ref() = rhs(); - // CHECK: call {{.*}}@{{.*}}rhs{{.*}}( - // CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}rhs{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}lhs_ref{{.*}}( lhs_ref() += rhs(); - // CHECK: call {{.*}}@{{.*}}rhs{{.*}}( - // CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}rhs{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}lhs_ref{{.*}}( lhs_ref() %= rhs(); - // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( - // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}make_b{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}make_c{{.*}}( make_c() = make_b(); - // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( - // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}make_b{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}make_c{{.*}}( make_c() += make_b(); -// CHECK: } +// CHECKDISABLED: } } - -// CHECK-LABEL: define {{.*}}@{{.*}}shift_lhs_before_rhs{{.*}}( +#endif +#if 0 +// CHECKDISABLED-LABEL: define {{.*}}@{{.*}}shift_lhs_before_rhs{{.*}}( void shift_lhs_before_rhs() { extern int lhs(), rhs(); - // CHECK: call {{.*}}@{{.*}}lhs{{.*}}( - // CHECK: call {{.*}}@{{.*}}rhs{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}lhs{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}rhs{{.*}}( (void)(lhs() << rhs()); - // CHECK: call {{.*}}@{{.*}}lhs{{.*}}( - // CHECK: call {{.*}}@{{.*}}rhs{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}lhs{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}rhs{{.*}}( (void)(lhs() >> rhs()); - // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( - // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}make_a{{.*}}( make_c() << make_a(); - // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( - // CHECK: call {{.*}}@{{.*}}make_a{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}make_a{{.*}}( make_c() >> make_a(); - // CHECK: call {{.*}}@{{.*}}make_c{{.*}}( - // CHECK: call {{.*}}@{{.*}}make_b{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}make_b{{.*}}( make_c() << make_b(); - // FIXME: This is unimplementable for Windows ABIs, see above. - // CHECK-ITANIUM: call {{.*}}@{{.*}}make_c{{.*}}( - // CHECK-ITANIUM: call {{.*}}@{{.*}}make_b{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}make_c{{.*}}( + // CHECKDISABLED: call {{.*}}@{{.*}}make_b{{.*}}( make_c() >> make_b(); -// CHECK: } +// CHECKDISABLED: } } +#endif Modified: cfe/trunk/test/CodeGenObjCXX/property-object-reference-2.mm URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/property-object-reference-2.mm?rev=282564&r1=282563&r2=282564&view=diff ============================================================================== --- cfe/trunk/test/CodeGenObjCXX/property-object-reference-2.mm (original) +++ cfe/trunk/test/CodeGenObjCXX/property-object-reference-2.mm Tue Sep 27 21:20:06 2016 @@ -44,8 +44,8 @@ struct TCPPObject // CHECK: ret void // CHECK-LABEL: define internal void @__assign_helper_atomic_property_(%struct.TCPPObject*, %struct.TCPPObject*) # -// CHECK: [[THREE:%.*]] = load %struct.TCPPObject*, %struct.TCPPObject** [[ADDR1:%.*]], align 8 // CHECK: [[TWO:%.*]] = load %struct.TCPPObject*, %struct.TCPPObject** [[ADDR:%.*]], align 8 +// CHECK: [[THREE:%.*]] = load %struct.TCPPObject*, %struct.TCPPObject** [[ADDR1:%.*]], align 8 // CHECK: [[CALL:%.*]] = call dereferenceable({{[0-9]+}}) %struct.TCPPObject* @_ZN10TCPPObjectaSERKS_(%struct.TCPPObject* [[TWO]], %struct.TCPPObject* dereferenceable({{[0-9]+}}) [[THREE]]) // CHECK: ret void Modified: cfe/trunk/www/cxx_status.html URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=282564&r1=282563&r2=282564&view=diff ============================================================================== --- cfe/trunk/www/cxx_status.html (original) +++ cfe/trunk/www/cxx_status.html Tue Sep 27 21:20:06 2016 @@ -701,7 +701,7 @@ as the draft C++1z standard evolves.</p> <tr> <td rowspan=2>Stricter expression evaluation order</td> <td><a href="http://wg21.link/p0145r3";>P0145R3</a></td> - <td class="svn" align="center" rowspan=2>SVN <a href="#p0145">(10)</a></td> + <td class="none" align="center" rowspan=2>No</td> </tr> <tr> <td><a href="http://wg21.link/p0400r0";>P0400R0</a></td> @@ -741,14 +741,6 @@ In Clang 3.7, a warning is emitted for a </span><br> <span id="p0136">(9): This is the resolution to a Defect Report, so is applied to all language versions supporting inheriting constructors. -</span><br> -<span id="p0145">(10): Under the MS ABI, this feature is not fully implementable, -because the calling convention requires that function parameters are destroyed -from left to right in the callee. In order to guarantee that destruction order -is reverse construction order, the operands of overloaded -<tt>operator<<</tt>, <tt>operator>></tt>, and <tt>operator->*</tt> -functions are evaluated right-to-left under the MS ABI when called using operator -syntax, not left-to-right as P0145R3 requires. </span> </p> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits