diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ee2f4a9509d688d2d8c65812fb942051cb396451..98370d65eeebf9afcd93725bb615598c1c5aa5da 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2016-01-08 Jakub Jelinek <jakub@redhat.com> + PR tree-optimization/69162 + * gimplify.c (gimplify_va_arg_expr): Encode original type of + valist argument in another argument. + (gimplify_modify_expr): Adjust for the above change. Cleanup. + * tree-stdarg.c (expand_ifn_va_arg_1): Use new 3rd argument + to determine the va_list type, build a MEM_REF instead of + build_fold_indirect_ref. + PR tree-optimization/69172 * gimple-fold.c (gimple_fold_builtin_memory_chk): Pass type to gimple_build. diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 0887abc36ace76403394a78d2b1f41608c3f22a1..ca66402babac14acdeaf9af93848f09ce6f3ea31 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -4724,12 +4724,12 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, tree type = TREE_TYPE (call); tree ap = CALL_EXPR_ARG (call, 0); tree tag = CALL_EXPR_ARG (call, 1); + tree aptag = CALL_EXPR_ARG (call, 2); tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call), IFN_VA_ARG, type, nargs + 1, ap, tag, - vlasize); - tree *call_p = &(TREE_OPERAND (*from_p, 0)); - *call_p = newcall; + aptag, vlasize); + TREE_OPERAND (*from_p, 0) = newcall; } } @@ -11501,7 +11501,7 @@ gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, tree promoted_type, have_va_type; tree valist = TREE_OPERAND (*expr_p, 0); tree type = TREE_TYPE (*expr_p); - tree t, tag; + tree t, tag, aptag; location_t loc = EXPR_LOCATION (*expr_p); /* Verify that valist is of the proper type. */ @@ -11555,7 +11555,10 @@ gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, } tag = build_int_cst (build_pointer_type (type), 0); - *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 2, valist, tag); + aptag = build_int_cst (TREE_TYPE (valist), 0); + + *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3, + valist, tag, aptag); /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG needs to be expanded. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 672a4961b09654a2d4ee1910f6e4eacf73c92e8d..f455fa22096c44f3c14f18229e4124d7d795fb29 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2016-01-08 Jakub Jelinek <jakub@redhat.com> + PR tree-optimization/69162 + * gcc.dg/pr69162.c: New test. + PR tree-optimization/69172 * gcc.dg/pr69172.c: New test. diff --git a/gcc/testsuite/gcc.dg/pr69162.c b/gcc/testsuite/gcc.dg/pr69162.c new file mode 100644 index 0000000000000000000000000000000000000000..45644bd2fe50b6b7be1fd59393143d267fdb1766 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr69162.c @@ -0,0 +1,12 @@ +/* PR tree-optimization/69162 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#include <stdarg.h> + +int +foo (void *a) +{ + va_list *b = a; + return va_arg (*b, int); +} diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c index 9fb16e8733583b87f2bf85c1a5804567fcccb8c6..13b92f05e006f1db17c9c8427add6c99041d9511 100644 --- a/gcc/tree-stdarg.c +++ b/gcc/tree-stdarg.c @@ -1018,7 +1018,7 @@ expand_ifn_va_arg_1 (function *fun) for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i)) { gimple *stmt = gsi_stmt (i); - tree ap, expr, lhs, type; + tree ap, aptype, expr, lhs, type; gimple_seq pre = NULL, post = NULL; if (!gimple_call_ifn_va_arg_p (stmt)) @@ -1028,9 +1028,12 @@ expand_ifn_va_arg_1 (function *fun) type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 1))); ap = gimple_call_arg (stmt, 0); + aptype = TREE_TYPE (gimple_call_arg (stmt, 2)); + gcc_assert (POINTER_TYPE_P (aptype)); /* Balanced out the &ap, usually added by build_va_arg. */ - ap = build_fold_indirect_ref (ap); + ap = build2 (MEM_REF, TREE_TYPE (aptype), ap, + build_int_cst (aptype, 0)); push_gimplify_context (false); saved_location = input_location; @@ -1053,7 +1056,7 @@ expand_ifn_va_arg_1 (function *fun) if (chkp_function_instrumented_p (fun->decl)) chkp_fixup_inlined_call (lhs, expr); - if (nargs == 3) + if (nargs == 4) { /* We've transported the size of with WITH_SIZE_EXPR here as the last argument of the internal fn call. Now reinstate