This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Call STORE on lexical $tied = vec/chr
[perl5.git] / t / op / lex_assign.t
1 #!./perl
2
3 # Test that $lexical = <some op> optimises the assignment away correctly
4 # and causes no ill side-effects.
5
6 BEGIN {
7     chdir 't' if -d 't';
8     @INC = '../lib';
9     require './test.pl';
10 }
11
12 $| = 1;
13 umask 0;
14 $xref = \ "";
15 $runme = $^X;
16 @a = (1..5);
17 %h = (1..6);
18 $aref = \@a;
19 $href = \%h;
20 open OP, qq{$runme -le "print 'aaa Ok ok' for 1..100"|};
21 $chopit = 'aaaaaa';
22 @chopar = (113 .. 119);
23 $posstr = '123456';
24 $cstr = 'aBcD.eF';
25 pos $posstr = 3;
26 $nn = $n = 2;
27 sub subb {"in s"}
28
29 @INPUT = <DATA>;
30 @simple_input = grep /^\s*\w+\s*\$\w+\s*[#\n]/, @INPUT;
31
32 sub wrn {"@_"}
33
34 # Check correct optimization of ucfirst etc
35 my $a = "AB";
36 my $b = "\u\L$a";
37 is( $b, 'Ab', 'Check correct optimization of ucfirst, etc');
38
39 # Check correct destruction of objects:
40 my $dc = 0;
41 sub A::DESTROY {$dc += 1}
42 $a=8;
43 my $b;
44 { my $c = 6; $b = bless \$c, "A"}
45
46 is($dc, 0, 'No destruction yet');
47
48 $b = $a+5;
49
50 is($dc, 1, 'object descruction via reassignment to variable');
51
52 my $xxx = 'b';
53 $xxx = 'c' . ($xxx || 'e');
54 is( $xxx, 'cb', 'variables can be read before being overwritten');
55
56 # Chains of assignments
57
58 my ($l1, $l2, $l3, $l4);
59 my $zzzz = 12;
60 $zzz1 = $l1 = $l2 = $zzz2 = $l3 = $l4 = 1 + $zzzz;
61
62 is($zzz1, 13, 'chain assignment, part1');
63 is($zzz2, 13, 'chain assignment, part2');
64 is($l1,   13, 'chain assignment, part3');
65 is($l2,   13, 'chain assignment, part4');
66 is($l3,   13, 'chain assignment, part5');
67 is($l4,   13, 'chain assignment, part6');
68
69 for (@INPUT) {
70   ($op, undef, $comment) = /^([^\#]+)(\#\s+(.*))?/;
71   $comment = $op unless defined $comment;
72   chomp;
73   $op = "$op==$op" unless $op =~ /==/;
74   ($op, $expectop) = $op =~ /(.*)==(.*)/;
75   
76   $skip = ($op =~ /^'\?\?\?'/ or $comment =~ /skip\(.*\Q$^O\E.*\)/i);
77   $integer = ($comment =~ /^i_/) ? "use integer" : '' ;
78   if ($skip) {
79     SKIP: {
80         skip $comment, 1;
81     }
82     next;
83   }
84   
85   eval <<EOE;
86   local \$SIG{__WARN__} = \\&wrn;
87   my \$a = 'fake';
88   $integer;
89   \$a = $op;
90   \$b = $expectop;
91   is (\$a, \$b, \$comment);
92 EOE
93   if ($@) {
94     $warning = $@;
95     chomp $warning;
96     if ($@ !~ /is unimplemented/) {
97       fail($_ . ' ' . $warning);
98     }
99   }
100 }
101
102 {                               # Check calling STORE
103   note('Tied variables, calling STORE');
104   my $sc = 0;
105   sub B::TIESCALAR {bless [11], 'B'}
106   sub B::FETCH { -(shift->[0]) }
107   sub B::STORE { $sc++; my $o = shift; $o->[0] = 17 + shift }
108
109   my $m;
110   tie $m, 'B';
111   $m = 100;
112
113   is( $sc, 1, 'STORE called when assigning scalar to tied variable' );
114
115   my $t = 11;
116   $m = $t + 89;
117   
118   is( $sc, 2, 'and again' );
119   is( $m,  -117, 'checking the tied variable result' );
120
121   $m += $t;
122
123   is( $sc, 3, 'called on self-increment' );
124   is( $m,  89, 'checking the tied variable result' );
125
126   for (@INPUT) {
127     ($op, undef, $comment) = /^([^\#]+)(\#\s+(.*))?/;
128     $comment = $op unless defined $comment;
129     next if ($op =~ /^'\?\?\?'/ or $comment =~ /skip\(.*\Q$^O\E.*\)/i);
130     $op =~ s/==.*//;
131     
132     $sc = 0;
133     eval "\$m = $op";
134     is $sc, 1, "STORE count for $comment";
135   }
136 }
137
138 for (@simple_input) {
139   ($op, undef, $comment) = /^([^\#]+)(\#\s+(.*))?/;
140   $comment = $op unless defined $comment;
141   chomp;
142   ($operator, $variable) = /^\s*(\w+)\s*\$(\w+)/ or warn "misprocessed '$_'\n";
143   eval <<EOE;
144   local \$SIG{__WARN__} = \\&wrn;
145   my \$$variable = "Ac# Ca\\nxxx";
146   \$$variable = $operator \$$variable;
147   \$toself = \$$variable;
148   \$direct = $operator "Ac# Ca\\nxxx";
149   is(\$toself, \$direct);
150 EOE
151   if ($@) {
152     $warning = $@;
153     chomp $warning;
154     if ($@ =~ /is unimplemented/) {
155       SKIP: {
156         skip $warning, 1;
157         pass($comment);
158       }
159     } elsif ($@ =~ /Can't (modify|take log of 0)/) {
160       SKIP: {
161         skip $warning . ' ' . $comment . ' syntax not good for selfassign', 1;
162         pass();
163       }
164     } else {
165       ##Something bad happened
166       fail($_ . ' ' . $warning);
167     }
168   }
169 }
170
171 # XXX This test does not really belong here, as it has nothing to do with
172 #     OPpTARGET_MY optimisation.  But where should it go?
173 eval {
174     sub PVBM () { 'foo' }
175     index 'foo', PVBM;
176     my $x = PVBM;
177
178     my $str = 'foo';
179     my $pvlv = \substr $str, 0, 1;
180     $x = $pvlv;
181
182     1;
183 };
184 is($@, '', 'ex-PVBM assert'.$@);
185
186 done_testing();
187
188 __END__
189 ref $xref                       # ref
190 ref $cstr                       # ref nonref
191 `$runme -e "print qq[1\\n]"`                            # backtick skip(MSWin32)
192 `$undefed`                      # backtick undef skip(MSWin32)
193 <*>                             # glob
194 <OP>                            # readline
195 'faked'                         # rcatline
196 (@z = (1 .. 3))                 # aassign
197 chop $chopit                    # chop
198 (chop (@x=@chopar))             # schop
199 chomp $chopit                   # chomp
200 (chop (@x=@chopar))             # schomp
201 pos $posstr                     # pos
202 pos $chopit                     # pos returns undef
203 $nn++==2                        # postinc
204 $nn++==3                        # i_postinc
205 $nn--==4                        # postdec
206 $nn--==3                        # i_postdec
207 $n ** $n                        # pow
208 $n * $n                         # multiply
209 $n * $n                         # i_multiply
210 $n / $n                         # divide
211 $n / $n                         # i_divide
212 $n % $n                         # modulo
213 $n % $n                         # i_modulo
214 $n x $n                         # repeat
215 $n + $n                         # add
216 $n + $n                         # i_add
217 $n - $n                         # subtract
218 $n - $n                         # i_subtract
219 $n . $n                         # concat
220 $n . $a=='2fake'                # concat with self
221 "3$a"=='3fake'                  # concat with self in stringify
222 "$n"                            # stringify
223 $n << $n                        # left_shift
224 $n >> $n                        # right_shift
225 $n <=> $n                       # ncmp
226 $n <=> $n                       # i_ncmp
227 $n cmp $n                       # scmp
228 $n & $n                         # bit_and
229 $n ^ $n                         # bit_xor
230 $n | $n                         # bit_or
231 -$n                             # negate
232 -$n                             # i_negate
233 -$a=="-fake"                    # i_negate with string
234 ~$n                             # complement
235 atan2 $n,$n                     # atan2
236 sin $n                          # sin
237 cos $n                          # cos
238 '???'                           # rand
239 exp $n                          # exp
240 log $n                          # log
241 sqrt $n                         # sqrt
242 int $n                          # int
243 hex $n                          # hex
244 oct $n                          # oct
245 abs $n                          # abs
246 length $posstr                  # length
247 substr $posstr, 2, 2            # substr
248 vec("abc",2,8)                  # vec
249 index $posstr, 2                # index
250 rindex $posstr, 2               # rindex
251 sprintf "%i%i", $n, $n          # sprintf
252 ord $n                          # ord
253 chr $n                          # chr
254 chr ${\256}                     # chr $wide
255 crypt $n, $n                    # crypt
256 ucfirst ($cstr . "a")           # ucfirst padtmp
257 ucfirst $cstr                   # ucfirst
258 lcfirst $cstr                   # lcfirst
259 uc $cstr                        # uc
260 lc $cstr                        # lc
261 quotemeta $cstr                 # quotemeta
262 @$aref                          # rv2av
263 @$undefed                       # rv2av undef
264 (each %h) % 2 == 1              # each
265 values %h                       # values
266 keys %h                         # keys
267 %$href                          # rv2hv
268 pack "C2", $n,$n                # pack
269 split /a/, "abad"               # split
270 join "a"; @a                    # join
271 push @a,3==6                    # push
272 unshift @aaa                    # unshift
273 reverse @a                      # reverse
274 reverse $cstr                   # reverse - scal
275 grep $_, 1,0,2,0,3              # grepwhile
276 map "x$_", 1,0,2,0,3            # mapwhile
277 subb()                          # entersub
278 caller                          # caller
279 warn "ignore this\n"            # warn
280 'faked'                         # die
281 open BLAH, "<non-existent"      # open
282 fileno STDERR                   # fileno
283 umask 0                         # umask
284 select STDOUT                   # sselect
285 select undef,undef,undef,0      # select
286 getc OP                         # getc
287 '???'                           # read
288 '???'                           # sysread
289 '???'                           # syswrite
290 '???'                           # send
291 '???'                           # recv
292 '???'                           # tell
293 '???'                           # fcntl
294 '???'                           # ioctl
295 '???'                           # flock
296 '???'                           # accept
297 '???'                           # shutdown
298 '???'                           # ftsize
299 '???'                           # ftmtime
300 '???'                           # ftatime
301 '???'                           # ftctime
302 chdir 'non-existent'            # chdir
303 '???'                           # chown
304 '???'                           # chroot
305 unlink 'non-existent'           # unlink
306 chmod 'non-existent'            # chmod
307 utime 'non-existent'            # utime
308 rename 'non-existent', 'non-existent1'  # rename
309 link 'non-existent', 'non-existent1' # link
310 '???'                           # symlink
311 readlink 'non-existent', 'non-existent1' # readlink
312 '???'                           # mkdir
313 '???'                           # rmdir
314 '???'                           # telldir
315 '???'                           # fork
316 '???'                           # wait
317 '???'                           # waitpid
318 system "$runme -e 0"            # system skip(VMS)
319 '???'                           # exec
320 '???'                           # kill
321 getppid                         # getppid
322 getpgrp                         # getpgrp
323 '???'                           # setpgrp
324 getpriority $$, $$              # getpriority
325 '???'                           # setpriority
326 time                            # time
327 localtime $^T                   # localtime
328 gmtime $^T                      # gmtime
329 '???'                           # sleep: can randomly fail
330 '???'                           # alarm
331 '???'                           # shmget
332 '???'                           # shmctl
333 '???'                           # shmread
334 '???'                           # shmwrite
335 '???'                           # msgget
336 '???'                           # msgctl
337 '???'                           # msgsnd
338 '???'                           # msgrcv
339 '???'                           # semget
340 '???'                           # semctl
341 '???'                           # semop
342 '???'                           # getlogin
343 '???'                           # syscall