Commit d0cf395a by Jason Merrill Committed by Jason Merrill

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
parent 8a1b7b7f
2016-07-08 Jason Merrill <jason@redhat.com>
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 <markus@trippelsdorf.de>
PR c++/71214
......
......@@ -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)
......
......@@ -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=<number> Distance between tab stops for column reporting.
......
2016-07-08 Jason Merrill <jason@redhat.com>
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 <jakub@redhat.com>
Kai Tietz <ktietz70@googlemail.com>
......
......@@ -5378,14 +5378,15 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *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. */
......
......@@ -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);
......
......@@ -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
......
// 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));
}
// 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(...) { }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment