File: Issue951.java

package info (click to toggle)
checker-framework-java 3.2.0%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 22,840 kB
  • sloc: java: 145,910; xml: 839; sh: 518; makefile: 401; perl: 26
file content (132 lines) | stat: -rw-r--r-- 3,827 bytes parent folder | download | duplicates (3)
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Test case for issue #951:
// https://github.com/typetools/checker-framework/issues/951

import org.checkerframework.dataflow.qual.Deterministic;
import org.checkerframework.dataflow.qual.Pure;
import org.checkerframework.dataflow.qual.SideEffectFree;

public class Issue951 {

    @Pure
    public static int min(int[] a) {
        if (a.length == 0) {
            throw new MyExceptionSefConstructor("Empty array passed to min(int[])");
        }
        int result = a[0];
        for (int i = 1; i < a.length; i++) {
            result = min(result, a[i]);
        }
        return result;
    }

    @Pure
    public static int arbitraryExceptionArg1() {
        // :: error: (purity.not.deterministic.not.sideeffectfree.call.method)
        // :: error: (purity.not.sideeffectfree.call.constructor)
        throw new MyException("" + arbitraryMethod());
    }

    @Pure
    public static int arbitraryExceptionArg2() {
        // :: error: (purity.not.deterministic.not.sideeffectfree.call.method)
        throw new MyExceptionSefConstructor("" + arbitraryMethod());
    }

    @Pure
    public static int sefExceptionArg1() {
        // The method is safe, so this is a false positive warning;
        // in the future the Purity Checker may not issue this warning.
        // :: error: (purity.not.deterministic.call.method)
        // :: error: (purity.not.sideeffectfree.call.constructor)
        throw new MyException("" + sefMethod());
    }

    @Pure
    public static int sefExceptionArg2() {
        // The method is safe, so this is a false positive warning;
        // in the future the Purity Checker may not issue this warning.
        // :: error: (purity.not.deterministic.call.method)
        throw new MyExceptionSefConstructor("" + sefMethod());
    }

    @Pure
    public static int detExceptionArg1() {
        // :: error: (purity.not.sideeffectfree.call.method)
        // :: error: (purity.not.sideeffectfree.call.constructor)
        throw new MyException("" + detMethod());
    }

    @Pure
    public static int detExceptionArg2() {
        // :: error: (purity.not.sideeffectfree.call.method)
        throw new MyExceptionSefConstructor("" + detMethod());
    }

    @Pure
    public static int pureExceptionArg1(int a, int b) {
        // :: error: (purity.not.sideeffectfree.call.constructor)
        throw new MyException("" + min(a, b));
    }

    @Pure
    public static int pureExceptionArg2(int a, int b) {
        throw new MyExceptionSefConstructor("" + min(a, b));
    }

    @Pure
    int throwNewWithinTry() {
        for (int i = 0; i < 10; i++) {
            try {
                for (int j = 0; j < 10; j++) {
                    throw new MyExceptionSefConstructor("foo");
                }
                // :: error: (purity.not.deterministic.catch)
            } catch (MyExceptionSefConstructor e) {
                return -1;
            }
        }
        return 22;
    }

    // Helper methods

    // Not deterministic or side-effect-free
    static int arbitraryMethod() {
        return 22;
    }

    // Not deterministic
    @SideEffectFree
    static int sefMethod() {
        return 22;
    }

    @Deterministic
    // Not side-effect-free
    static int detMethod() {
        return 22;
    }

    @Pure
    static int min(int a, int b) {
        if (a < b) {
            return a;
        } else {
            return b;
        }
    }

    // Constructors

    static class MyException extends Error {
        // Not side-effect-free
        MyException(String message) {}
    }

    static class MyExceptionSefConstructor extends Error {
        // Side-effect-free
        @SuppressWarnings("purity.not.sideeffectfree.call") // until java.util.Error is annotated
        @SideEffectFree
        MyExceptionSefConstructor(String message) {}
    }
}