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
|
#!./perl -w
# Uncomment this for testing, but don't leave it in for "production", as
# we've not yet verified that use works.
# use strict;
print "1..19\n";
my $test = 0;
# Historically constant folding was performed by evaluating the ops, and if
# they threw an exception compilation failed. This was seen as buggy, because
# even illegal constants in unreachable code would cause failure. So now
# illegal expressions are reported at runtime, if the expression is reached,
# making constant folding consistent with many other languages, and purely an
# optimisation rather than a behaviour change.
sub failed {
my ($got, $expected, $name) = @_;
print "not ok $test - $name\n";
my @caller = caller(1);
print "# Failed test at $caller[1] line $caller[2]\n";
if (defined $got) {
print "# Got '$got'\n";
} else {
print "# Got undef\n";
}
print "# Expected $expected\n";
return;
}
sub like {
my ($got, $pattern, $name) = @_;
$test = $test + 1;
if (defined $got && $got =~ $pattern) {
print "ok $test - $name\n";
# Principle of least surprise - maintain the expected interface, even
# though we aren't using it here (yet).
return 1;
}
failed($got, $pattern, $name);
}
sub is {
my ($got, $expect, $name) = @_;
$test = $test + 1;
if (defined $got && $got eq $expect) {
print "ok $test - $name\n";
return 1;
}
failed($got, "'$expect'", $name);
}
sub ok {
my ($got, $name) = @_;
$test = $test + 1;
if ($got) {
print "ok $test - $name\n";
return 1;
}
failed($got, "a true value", $name);
}
my $a;
$a = eval '$b = 0/0 if 0; 3';
is ($a, 3, 'constants in conditionals don\'t affect constant folding');
is ($@, '', 'no error');
my $b = 0;
$a = eval 'if ($b) {return sqrt -3} 3';
is ($a, 3, 'variables in conditionals don\'t affect constant folding');
is ($@, '', 'no error');
$a = eval q{
$b = eval q{if ($b) {return log 0} 4};
is ($b, 4, 'inner eval folds constant');
is ($@, '', 'no error');
5;
};
is ($a, 5, 'outer eval folds constant');
is ($@, '', 'no error');
# warn and die hooks should be disabled during constant folding
{
my $c = 0;
local $SIG{__WARN__} = sub { $c++ };
local $SIG{__DIE__} = sub { $c+= 2 };
eval q{
is($c, 0, "premature warn/die: $c");
my $x = "a"+5;
is($c, 1, "missing warn hook");
is($x, 5, "a+5");
$c = 0;
$x = 1/0;
};
like ($@, qr/division/, "eval caught division");
is($c, 2, "missing die hook");
}
# [perl #20444] Constant folding should not change the meaning of match
# operators.
{
local *_;
$_="foo"; my $jing = 1;
ok scalar $jing =~ (1 ? /foo/ : /bar/),
'lone m// is not bound via =~ after ? : folding';
ok scalar $jing =~ (0 || /foo/),
'lone m// is not bound via =~ after || folding';
ok scalar $jing =~ (1 ? s/foo/foo/ : /bar/),
'lone s/// is not bound via =~ after ? : folding';
ok scalar $jing =~ (0 || s/foo/foo/),
'lone s/// is not bound via =~ after || folding';
$jing = 3;
ok scalar $jing =~ (1 ? y/fo// : /bar/),
'lone y/// is not bound via =~ after ? : folding';
ok scalar $jing =~ (0 || y/fo//),
'lone y/// is not bound via =~ after || folding';
}
|