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> 2016-07-05 Markus Trippelsdorf <markus@trippelsdorf.de>
PR c++/71214 PR c++/71214
......
...@@ -910,11 +910,11 @@ c_common_post_options (const char **pfilename) ...@@ -910,11 +910,11 @@ c_common_post_options (const char **pfilename)
else if (warn_narrowing == -1) else if (warn_narrowing == -1)
warn_narrowing = 0; warn_narrowing = 0;
/* C++17 requires that function arguments be evaluated left-to-right even on /* C++17 has stricter evaluation order requirements; let's use some of them
PUSH_ARGS_REVERSED targets. */ for earlier C++ as well, so chaining works as expected. */
if (c_dialect_cxx () if (c_dialect_cxx ()
&& flag_args_in_order == -1) && flag_strong_eval_order == -1)
flag_args_in_order = 2 /*(cxx_dialect >= cxx1z) ? 2 : 0*/; flag_strong_eval_order = (cxx_dialect >= cxx1z ? 2 : 1);
/* Global sized deallocation is new in C++14. */ /* Global sized deallocation is new in C++14. */
if (flag_sized_deallocation == -1) if (flag_sized_deallocation == -1)
......
...@@ -1043,14 +1043,6 @@ falt-external-templates ...@@ -1043,14 +1043,6 @@ falt-external-templates
C++ ObjC++ Ignore Warn(switch %qs is no longer supported) C++ ObjC++ Ignore Warn(switch %qs is no longer supported)
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 fasm
C ObjC C++ ObjC++ Var(flag_no_asm, 0) C ObjC C++ ObjC++ Var(flag_no_asm, 0)
Recognize the \"asm\" keyword. Recognize the \"asm\" keyword.
...@@ -1518,6 +1510,28 @@ Assume that values of enumeration type are always within the minimum range of th ...@@ -1518,6 +1510,28 @@ Assume that values of enumeration type are always within the minimum range of th
fstrict-prototype fstrict-prototype
C++ ObjC++ Ignore Warn(switch %qs is no longer supported) 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= ftabstop=
C ObjC C++ ObjC++ Joined RejectNegative UInteger C ObjC C++ ObjC++ Joined RejectNegative UInteger
-ftabstop=<number> Distance between tab stops for column reporting. -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> 2016-07-07 Jakub Jelinek <jakub@redhat.com>
Kai Tietz <ktietz70@googlemail.com> Kai Tietz <ktietz70@googlemail.com>
......
...@@ -5378,14 +5378,15 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args, ...@@ -5378,14 +5378,15 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
static int static int
op_is_ordered (tree_code code) op_is_ordered (tree_code code)
{ {
if (!flag_args_in_order)
return 0;
switch (code) switch (code)
{ {
// 5. b @= a // 5. b @= a
case MODIFY_EXPR: 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 // 1. a.b
// Not overloadable (yet). // Not overloadable (yet).
...@@ -5393,13 +5394,11 @@ op_is_ordered (tree_code code) ...@@ -5393,13 +5394,11 @@ op_is_ordered (tree_code code)
// Only one argument. // Only one argument.
// 3. a->*b // 3. a->*b
case MEMBER_REF: case MEMBER_REF:
// 6. a[b]
case ARRAY_REF:
// 7. a << b // 7. a << b
case LSHIFT_EXPR: case LSHIFT_EXPR:
// 8. a >> b // 8. a >> b
case RSHIFT_EXPR: case RSHIFT_EXPR:
return 1; return (flag_strong_eval_order ? 1 : 0);
default: default:
return 0; return 0;
...@@ -7830,9 +7829,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) ...@@ -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); tree call = build_cxx_call (fn, nargs, argarray, complain|decltype_flag);
if (call != error_mark_node if (call != error_mark_node
&& !magic && cand->flags & LOOKUP_LIST_INIT_CTOR)
&& (flag_args_in_order > 1
|| (cand->flags & LOOKUP_LIST_INIT_CTOR)))
{ {
tree c = extract_call_expr (call); tree c = extract_call_expr (call);
/* build_new_op_1 will clear this when appropriate. */ /* 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) ...@@ -780,11 +780,10 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
ret = GS_ERROR; ret = GS_ERROR;
} }
} }
else if (flag_args_in_order == 1 else if (flag_strong_eval_order
&& !CALL_EXPR_OPERATOR_SYNTAX (*expr_p)) && !CALL_EXPR_OPERATOR_SYNTAX (*expr_p))
{ {
/* If flag_args_in_order == 1, we don't force an order on all /* If flag_strong_eval_order, evaluate the object argument first. */
function arguments, but do evaluate the object argument first. */
tree fntype = TREE_TYPE (CALL_EXPR_FN (*expr_p)); tree fntype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
if (POINTER_TYPE_P (fntype)) if (POINTER_TYPE_P (fntype))
fntype = TREE_TYPE (fntype); fntype = TREE_TYPE (fntype);
......
...@@ -2237,14 +2237,6 @@ option is used for the warning. ...@@ -2237,14 +2237,6 @@ option is used for the warning.
Turn off all access checking. This switch is mainly useful for working Turn off all access checking. This switch is mainly useful for working
around bugs in the access control code. 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 @item -fcheck-new
@opindex fcheck-new @opindex fcheck-new
Check that the pointer returned by @code{operator new} is non-null 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 ...@@ -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 enumerators). This assumption may not be valid if the program uses a
cast to convert an arbitrary integer value to the enumerated type. 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} @item -ftemplate-backtrace-limit=@var{n}
@opindex ftemplate-backtrace-limit @opindex ftemplate-backtrace-limit
Set the maximum number of template instantiation notes for a single 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++ // P0145R2: Refining Expression Order for C++
// { dg-do run } // { dg-do run }
// { dg-options "-std=c++1z -fargs-in-order=1" } // { dg-options "-std=c++1z" }
extern "C" int printf (const char *, ...); extern "C" int printf (const char *, ...);
void sink(...) { } 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