File: fun_ptr.i

package info (click to toggle)
frama-c 20161101%2Bsilicon%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 42,324 kB
  • ctags: 35,695
  • sloc: ml: 200,142; ansic: 31,465; makefile: 2,334; sh: 1,643; lisp: 259; python: 85; asm: 26
file content (94 lines) | stat: -rw-r--r-- 1,410 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/* run.config*
  STDOPT:
  STDOPT: +"-machdep msvc_x86_64"
*/


int f(int x)
{
  return x+1;
}

int g(int x, int y)
{
  return x+y;
}

typedef int (*fptr1)(int);
typedef int (*fptr2)(int, int);
typedef double (*fptr3)(int);

long long t[2] = { (long long)&f, (long long)&g };

int R1, R2;
double R3;

void test1(int nd)
{
  R1 = ((fptr1)(t[nd]))(3);
}

void test2(int nd)
{
  R2 = ((fptr2)(t[nd]))(3, 4);
}

void test3(int nd)
{
  R3 = ((fptr3)(t[nd]))(5);
}

double h(short a, short b) {
  return a + b;
}

volatile int v;

void benign(int j, void *p) {
  int *q = p;
  *q = j; // q is a void*, which is actually an int, but at the call site it is a short *. We accept this for now.
  int k = j+0; 
}

void test_benign () {
  int x;
  void (*p) (long, short *) = &benign; // We accept this cast, because the arguments are "compatible enough". An (unprovable) alarm is still emitted
  (*p)(1U << 31U, &x);
}

void too_much(int i) {
  int j = i;
}

void too_much2(int i, int j, int k) {
  int l = i+j+k;
}

void test_too_much_benign () {
  int x;
  void (*p) (int, int) = &too_much;
  (*p)(1, 2); // Accepted (with an alarm)
  if (v) {
    p = &too_much2;
    (*p)(1, 2); // Failure    
  }
}

main(){
  test1(!v);
  test2(!v);
  if (v) test3(!v);
  double (*ph)() = h;
  if (v)
    ph(1., 2.);
  if (v)
    ph();
  if (v)
    ph((short)1, (short)2);

  test_benign();
  test_too_much_benign();

  return 0;
}