blob: 1a1d947287f8fac517167bdcb6670f11a89d8bb6 [file] [log] [blame]
//TODO: Update this to not use ds-aa!
//XFAIL: *
#include <stdarg.h>
//This tests having multiple parameters
//In particular, this verifies that dsa doesn't unnecessarily
//set the mod/ref flag for functions.
//What to check:
//'val' should alias stack_val and stack_val2
//'p1' and 'p2' should alias
//'p1' and 'p2' should be modref'd by assign
//(accordingly stack_val/stack_val2 are modref'd)
//
//--build the code into a .bc
//RUN: clang -O0 %s -S -emit-llvm -o - | llvm-as > %t.bc
//--check if ds-aa breaks, breaks opts, or results in miscompiled code
//RUN: lli %t.bc > %t.refout
//RUN: dsaopt %t.bc -ds-aa -gvn -o - | lli > %t.out
//RUN: diff %t.refout %t.out
//--check properties of this particular test
//RUN: dsaopt %t.bc -ds-aa -aa-eval -o /dev/null \
// RUN: -print-all-alias-modref-info >& %t.aa
//ds-aa should tell us that assign doesn't mod/ref p1
//RUN: cat %t.aa | grep {Ptr:.*p1.*@assign} | grep NoModRef
//ds-aa should tell us that assign doesn't mod/ref p2
//RUN: cat %t.aa | grep {Ptr:.*p2.*@assign} | grep NoModRef
static int assign( int count, ... )
{
va_list ap;
va_start( ap, count );
int sum = 0;
int i = 1;
int ** old = va_arg( ap, int** );
for ( ; i < count; ++i )
{
int **val = va_arg( ap, int** );
//Unlike 'multiple_callee.c', don't mod/ref the value
//*old = *val;
old = val;
}
va_end( ap );
return sum;
}
int main()
{
int stack_val = 5;
int stack_val2 = 10;
int * p1 = &stack_val;
int * p2 = &stack_val2;
//Doesn't mod/ref either param
assign( 2, &p1, &p2 );
//p1 is still intact, pointing to stack_val
if ( p1 == &stack_val )
{
return 0;
}
return -1;
}