{
fi = lookup_vi_for_tree (fn->decl);
rhs = get_function_part_constraint (fi, ~0);
- rhs.type = ADDRESSOF;
+ rhs.type = SCALAR;
}
else
{
rhs.var = nonlocal_id;
- rhs.type = ADDRESSOF;
+ rhs.type = SCALAR;
rhs.offset = 0;
}
FOR_EACH_VEC_ELT (lhsc, i, lhsp)
&& find_func_aliases_for_builtin_call (fn, t))
return;
+ if (gimple_call_internal_p (t, IFN_VA_ARG)
+ && gimple_call_lhs (t))
+ {
+ tree valist = gimple_call_arg (t, 0);
+ auto_vec<ce_s, 1> rhsc, lhsc;
+ get_constraint_for_rhs (valist, &rhsc);
+ do_deref (&rhsc);
+ get_constraint_for (gimple_call_lhs (t), &lhsc);
+ process_all_all_constraints (lhsc, rhsc);
+ /* va_list is used and clobbered. */
+ make_constraint_to (get_call_use_vi (t)->id, valist);
+ make_constraint_to (get_call_clobber_vi (t)->id, valist);
+ return;
+ }
+
if (gimple_call_internal_p (t, IFN_DEFERRED_INIT))
return;
--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta2-details" } */
+
+#include <stdarg.h>
+
+static int __attribute__((noinline, noclone)) q (int n, ...)
+{
+ va_list va;
+ va_start (va, n);
+ int *a = va_arg (va, int *);
+ int *b = va_arg (va, int *);
+ va_end (va);
+ return *a + *b;
+}
+
+static int __attribute__((noinline, noclone)) foo (int (*p)(int, ...))
+{
+ int i = 1, j = 3;
+ return p(2, &i, &j);
+}
+
+int main()
+{
+ if (foo (q) != 4)
+ __builtin_abort ();
+ return 0;
+}
+
+/* Verify we properly handle variadic arguments for indirect calls and
+ .VA_ARG properly accesses only the variadic part. */
+
+/* { dg-final { scan-ipa-dump "a_\[0-9\]\+ = { i j }" "pta2" } } */
+/* { dg-final { scan-ipa-dump "b_\[0-9\]\+ = { i j }" "pta2" } } */