From d0cf395a999499cfdc785cdb920bfdf401a628aa Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 8 Jul 2016 16:25:31 -0400 Subject: [PATCH] P0145: Refining Expression Order for C++ (-fstrong-eval-order). gcc/c-family/ * c.opts (-fargs-in-order): Rename to -fstrong-eval-order. * c-opts.c: Adjust. gcc/cp/ * call.c (op_is_ordered, build_over_call): Adjust for -fargs-in-order renaming to -fstrong-eval-order. * cp-gimplify.c (cp_gimplify_expr): Likewise. From-SVN: r238176 --- gcc/c-family/ChangeLog | 6 +++++ gcc/c-family/c-opts.c | 8 +++---- gcc/c-family/c.opt | 30 +++++++++++++++++------- gcc/cp/ChangeLog | 7 ++++++ gcc/cp/call.c | 17 ++++++-------- gcc/cp/cp-gimplify.c | 5 ++-- gcc/doc/invoke.texi | 17 +++++++------- gcc/testsuite/g++.dg/cpp1z/eval-order1.C | 21 ----------------- gcc/testsuite/g++.dg/cpp1z/eval-order3.C | 2 +- 9 files changed, 58 insertions(+), 55 deletions(-) delete mode 100644 gcc/testsuite/g++.dg/cpp1z/eval-order1.C diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index f30c9f321a4..9c002f61fc6 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2016-07-08 Jason Merrill + + P0145: Refining Expression Order for C++. + * c.opts (-fargs-in-order): Rename to -fstrong-eval-order. + * c-opts.c: Adjust. + 2016-07-05 Markus Trippelsdorf PR c++/71214 diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index ff6339c44b6..d945825cc64 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -910,11 +910,11 @@ c_common_post_options (const char **pfilename) else if (warn_narrowing == -1) warn_narrowing = 0; - /* C++17 requires that function arguments be evaluated left-to-right even on - PUSH_ARGS_REVERSED targets. */ + /* C++17 has stricter evaluation order requirements; let's use some of them + for earlier C++ as well, so chaining works as expected. */ if (c_dialect_cxx () - && flag_args_in_order == -1) - flag_args_in_order = 2 /*(cxx_dialect >= cxx1z) ? 2 : 0*/; + && flag_strong_eval_order == -1) + flag_strong_eval_order = (cxx_dialect >= cxx1z ? 2 : 1); /* Global sized deallocation is new in C++14. */ if (flag_sized_deallocation == -1) diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 83fd84ccc0f..8c701523c38 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -1043,14 +1043,6 @@ falt-external-templates C++ ObjC++ Ignore Warn(switch %qs is no longer supported) No longer supported. -fargs-in-order -C++ ObjC++ Alias(fargs-in-order=, 2, 0) -Always evaluate function arguments in left-to-right order. - -fargs-in-order= -C++ ObjC++ Var(flag_args_in_order) Joined UInteger Init(-1) -Always evaluate function arguments in left-to-right order. - fasm C ObjC C++ ObjC++ Var(flag_no_asm, 0) Recognize the \"asm\" keyword. @@ -1518,6 +1510,28 @@ Assume that values of enumeration type are always within the minimum range of th fstrict-prototype C++ ObjC++ Ignore Warn(switch %qs is no longer supported) +fstrong-eval-order +C++ ObjC++ Common Alias(fstrong-eval-order=, all, none) +Follow the C++17 evaluation order requirements for assignment expressions, +shift, member function calls, etc. + +fstrong-eval-order= +C++ ObjC++ Common Var(flag_strong_eval_order) Joined Enum(strong_eval_order) Init(-1) +Follow the C++17 evaluation order requirements for assignment expressions, +shift, member function calls, etc. + +Enum +Name(strong_eval_order) Type(int) + +EnumValue +Enum(strong_eval_order) String(none) Value(0) + +EnumValue +Enum(strong_eval_order) String(some) Value(1) + +EnumValue +Enum(strong_eval_order) String(all) Value(2) + ftabstop= C ObjC C++ ObjC++ Joined RejectNegative UInteger -ftabstop= Distance between tab stops for column reporting. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 12f15db59dd..13f80f9103f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2016-07-08 Jason Merrill + + P0145R2: Refining Expression Order for C++. + * call.c (op_is_ordered, build_over_call): Adjust for + -fargs-in-order renaming to -fstrong-eval-order. + * cp-gimplify.c (cp_gimplify_expr): Likewise. + 2016-07-07 Jakub Jelinek Kai Tietz diff --git a/gcc/cp/call.c b/gcc/cp/call.c index d77092b1ef5..8b93c61a6db 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -5378,14 +5378,15 @@ add_candidates (tree fns, tree first_arg, const vec *args, static int op_is_ordered (tree_code code) { - if (!flag_args_in_order) - return 0; - switch (code) { // 5. b @= a case MODIFY_EXPR: - return -1; + return (flag_strong_eval_order > 1 ? -1 : 0); + + // 6. a[b] + case ARRAY_REF: + return (flag_strong_eval_order > 1 ? 1 : 0); // 1. a.b // Not overloadable (yet). @@ -5393,13 +5394,11 @@ op_is_ordered (tree_code code) // Only one argument. // 3. a->*b case MEMBER_REF: - // 6. a[b] - case ARRAY_REF: // 7. a << b case LSHIFT_EXPR: // 8. a >> b case RSHIFT_EXPR: - return 1; + return (flag_strong_eval_order ? 1 : 0); default: return 0; @@ -7830,9 +7829,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) tree call = build_cxx_call (fn, nargs, argarray, complain|decltype_flag); if (call != error_mark_node - && !magic - && (flag_args_in_order > 1 - || (cand->flags & LOOKUP_LIST_INIT_CTOR))) + && cand->flags & LOOKUP_LIST_INIT_CTOR) { tree c = extract_call_expr (call); /* build_new_op_1 will clear this when appropriate. */ diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 1d81fb1e3d2..c04368fc189 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -780,11 +780,10 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) ret = GS_ERROR; } } - else if (flag_args_in_order == 1 + else if (flag_strong_eval_order && !CALL_EXPR_OPERATOR_SYNTAX (*expr_p)) { - /* If flag_args_in_order == 1, we don't force an order on all - function arguments, but do evaluate the object argument first. */ + /* If flag_strong_eval_order, evaluate the object argument first. */ tree fntype = TREE_TYPE (CALL_EXPR_FN (*expr_p)); if (POINTER_TYPE_P (fntype)) fntype = TREE_TYPE (fntype); diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index e185178bf55..b7e9d2d1109 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -2237,14 +2237,6 @@ option is used for the warning. Turn off all access checking. This switch is mainly useful for working around bugs in the access control code. -@item -fargs-in-order -@opindex fargs-in-order -Evaluate function arguments and operands of some binary expressions in -left-to-right order, and evaluate the right side of an assignment -before the left side, as proposed in P0145R2. Enabled by default with -@option{-std=c++1z}. @option{-fargs-in-order=1} implements all of the -ordering requirements except function arguments. - @item -fcheck-new @opindex fcheck-new Check that the pointer returned by @code{operator new} is non-null @@ -2483,6 +2475,15 @@ represented in the minimum number of bits needed to represent all the enumerators). This assumption may not be valid if the program uses a cast to convert an arbitrary integer value to the enumerated type. +@item -fstrong-eval-order +@opindex fstrong-eval-order +Evaluate member access, array subscripting, and shift expressions in +left-to-right order, and evaluate assignment in right-to-left order, +as adopted for C++17. Enabled by default with @option{-std=c++1z}. +@option{-fstrong-eval-order=some} enables just the ordering of member +access and shift expressions, and is the default without +@option{-std=c++1z}. + @item -ftemplate-backtrace-limit=@var{n} @opindex ftemplate-backtrace-limit Set the maximum number of template instantiation notes for a single diff --git a/gcc/testsuite/g++.dg/cpp1z/eval-order1.C b/gcc/testsuite/g++.dg/cpp1z/eval-order1.C deleted file mode 100644 index 278990d6f8e..00000000000 --- a/gcc/testsuite/g++.dg/cpp1z/eval-order1.C +++ /dev/null @@ -1,21 +0,0 @@ -// P0145R2: Refining Expression Order for C++ -// { dg-do run } -// { dg-options "-std=c++1z" } - -extern "C" int printf (const char *, ...); -void sink(...) { } - -int last = 0; -int f(int i) -{ - if (i < last) - __builtin_abort (); - last = i; - return i; -} - -int main() -{ - sink(f(1), f(2)); - sink(f(3), f(4), f(5)); -} diff --git a/gcc/testsuite/g++.dg/cpp1z/eval-order3.C b/gcc/testsuite/g++.dg/cpp1z/eval-order3.C index 15df9038107..d382d073aa6 100644 --- a/gcc/testsuite/g++.dg/cpp1z/eval-order3.C +++ b/gcc/testsuite/g++.dg/cpp1z/eval-order3.C @@ -1,6 +1,6 @@ // P0145R2: Refining Expression Order for C++ // { dg-do run } -// { dg-options "-std=c++1z -fargs-in-order=1" } +// { dg-options "-std=c++1z" } extern "C" int printf (const char *, ...); void sink(...) { } -- 2.30.2