Skip to content

Commit eee1384

Browse files
H. Peter Anvin (Intel)Copilot
andcommitted
testgen: add %ifdef ERROR error-case coverage, fix branch-operand bugs
Add error-case ("negative test") coverage per the user's preferred convention: rather than a separate source file, error-triggering instruction lines are appended to the existing per-mnemonic .asm file under a %ifdef ERROR guard, and the harness assembles the same file twice -- once without -DERROR (existing positive-path coverage, unaffected) and once with -DERROR (expected to fail, per nasm-t.py's "error": "expected" json convention, matching the pre-existing travis/ret/ret.json pattern). The error material comes for free from lines the generator already knows are bit-width-incompatible: - Lines needing 64-bit encodings (reg64/imm64 operands, hireg r8-r15, apxreg r16-r31, etc. -- %needs64_token / build_variant_line) are, by construction, exactly the lines already excluded from the 16/32-bit "narrow" body. They're appended to the narrow file under %ifdef ERROR and probed at --bits 16/32 with -DERROR; only widths where the block actually fails become json entries. - Symmetrically, CALL/JMP near-indirect targets via rm16/rm32 (only rm64 is valid in 64-bit mode -- confirmed empirically, matches the NOLONG flag on those insns.xda templates) are appended to the full (64-bit) body under %ifdef ERROR and probed at --bits 64 with -DERROR. Each candidate block is probed before being turned into a json entry, so a line that unexpectedly *does* assemble at some width (this generator doesn't model every mode restriction) doesn't turn into a bogus "expected error" test; a mnemonic whose *only* surviving coverage would be error entries is also rejected (see below), since "this never assembles" isn't meaningful regression coverage on its own. While wiring this up, discovered and fixed two related bugs in the existing branch-mnemonic handling (gen_operand()'s is_branch substitution): 1. is_branch replaced *every* operand of a branch mnemonic with the ".L1" local-label text, not just genuine relative/near/short/abs branch-displacement operands. This produced nonsensical lines like "loop .L1, .L1" (LOOP's address-size-override form takes a fixed "cx"/"ecx"/"rcx" second operand, not a branch target) and "call .L1" for JMP/CALL's indirect (rm16/32/64) and far-pointer (imm16:imm16) forms instead of an actual register/memory operand. These bogus lines silently poisoned assembly for the whole mnemonic, and LOOP/LOOPE/LOOPNE/LOOPNZ/LOOPZ/JCXZ were silently dropped entirely as a result (present in the "16 dropped" list). Restricting the substitution to base tokens matching /^imm(?:8|16|32|64)$/ fixes both LOOP's operand and JMP/CALL's indirect/far forms, and recovers all six previously-dropped mnemonics with correct coverage. 2. Once (1) exposed genuine rm16/rm32 operand generation for CALL/JMP, a new bit-width interaction appeared: rm16/rm32 near-indirect targets are only valid in 16/32-bit mode (unlike ordinary reg16/32 operands elsewhere, which work at any bit width), so a line built from one now broke 64-bit assembly for the whole mnemonic the same way a needs64 line breaks 16/32-bit assembly. Added branch_narrow_only() and a parallel avoid64 line flag (mirroring needs64) to exclude these lines from the 64-bit "full" body -- this is also what feeds the new symmetric 64-bit error-case coverage described above. Also added a safety-net to the existing "couldn't assemble in any mode, drop the directory" check: a directory is now only kept if it has at least one *non*-error json entry, preventing a future bug symmetric to (1) from silently producing a directory whose only content is error-case entries. Verified via full scratch regeneration (2612 mnemonics generated / 10 dropped, up from 2606/16 thanks to the LOOP-family/JCXZ fix) + nasm-t.py run (10918/10918 PASS, 0 FAIL) + per-mnemonic non-error .json entry-count diff against the prior committed tree (identical except the 6 newly-recovered mnemonics, confirming no regressions). 1976/2612 mnemonics gained at least one error-case entry (3951 error json entries total). Regenerated travis/insns/ and validated via 'make -j32 travis' (all PASS, ~27s). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 6de2898 commit eee1384

7,981 files changed

Lines changed: 89508 additions & 54 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

tools/testgen/gen-insn-tests.pl

Lines changed: 160 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,17 @@ sub base_token {
404404
sub gen_operand {
405405
my ($rng, $tok, $mnem, $is_branch, $variant) = @_;
406406
my $base = base_token($tok);
407-
if ($is_branch) {
407+
# Only genuine relative/near/short/abs branch-displacement operands
408+
# (plain imm8/16/32/64, before the trailing "|near"/"|short"/"|abs"
409+
# qualifier that base_token() already stripped) get replaced with a
410+
# local label -- NOT every operand of a "branch mnemonic". Some
411+
# branch mnemonics also have indirect (rm16/32/64), far-pointer
412+
# (colon-compound "imm16:imm16"), or fixed-register (reg_cx, for
413+
# LOOP's address-size-override form) operand forms, none of which
414+
# are relative-displacement targets, and would otherwise get
415+
# nonsensically replaced with the branch label too (producing
416+
# invalid syntax like "loop .L1, .L1" instead of "loop .L1, cx").
417+
if ($is_branch && $base =~ /^imm(?:8|16|32|64)$/) {
408418
return '.L1';
409419
}
410420
if (exists $fixed{$base}) {
@@ -417,6 +427,21 @@ sub gen_operand {
417427
return undef;
418428
}
419429

430+
# CALL/JMP near-indirect targets (the only branch-mnemonic templates
431+
# with rm*-typed operands) restrict the operand-size override: rm64 is
432+
# the only form valid in 64-bit mode -- rm16/rm32 forms genuinely only
433+
# assemble in 16/32-bit mode (confirmed empirically: "call cx"/
434+
# "call ecx" both fail under --bits 64, matching the NOLONG flag on
435+
# those insns.xda templates). This is unrelated to %needs64_token
436+
# (which flags the opposite direction -- 64-bit-*only* operands), so a
437+
# separate helper marks lines built from these tokens as excluded from
438+
# the 64-bit "full" body, mirroring how needs64 lines are excluded from
439+
# the 16/32-bit "narrow" body.
440+
sub branch_narrow_only {
441+
my ($is_branch, $base) = @_;
442+
return ($is_branch && $base =~ /^rm(?:16|32)$/) ? 1 : 0;
443+
}
444+
420445
# Base tokens whose register pool has hireg (r8-r15 range) / apxreg
421446
# (r16-r31 range) tiers available -- i.e. templates containing at
422447
# least one of these are candidates for the extra register-number-
@@ -632,6 +657,7 @@ sub build_dispboundary_line {
632657
my @operands;
633658
my $used_mem = 0;
634659
my $needs64 = 0;
660+
my $avoid64 = 0;
635661
for my $tok (@$ops) {
636662
my $base = base_token($tok);
637663
if (!$used_mem && exists $mem_sizebits{$base}) {
@@ -640,15 +666,17 @@ sub build_dispboundary_line {
640666
$txt = "$memsize{$sizebits} $txt" if $sizebits && $memsize{$sizebits};
641667
push @operands, $txt;
642668
$used_mem = 1;
669+
$avoid64 = 1 if branch_narrow_only($is_branch, $base);
643670
next;
644671
}
645672
my $val = gen_operand($rng, $tok, $mnem, $is_branch);
646673
return undef unless defined $val;
647674
$needs64 = 1 if $needs64_token{$base};
675+
$avoid64 = 1 if branch_narrow_only($is_branch, $base);
648676
push @operands, $val;
649677
}
650678
return undef unless $used_mem;
651-
return { text => lc($mnem) . ' ' . join(', ', @operands), needs64 => $needs64 };
679+
return { text => lc($mnem) . ' ' . join(', ', @operands), needs64 => $needs64, avoid64 => $avoid64 };
652680
}
653681

654682
# Implicitly-sized memory operand coverage.
@@ -677,20 +705,23 @@ sub build_implicitsize_line {
677705
my @operands;
678706
my $used_mem = 0;
679707
my $needs64 = 0;
708+
my $avoid64 = 0;
680709
for my $tok (@$ops) {
681710
my $base = base_token($tok);
682711
if (!$used_mem && ($mem_sizebits{$base} // 0)) {
683712
push @operands, mem_operand($rng, 0);
684713
$used_mem = 1;
714+
$avoid64 = 1 if branch_narrow_only($is_branch, $base);
685715
next;
686716
}
687717
my $val = gen_operand($rng, $tok, $mnem, $is_branch);
688718
return undef unless defined $val;
689719
$needs64 = 1 if $needs64_token{$base};
720+
$avoid64 = 1 if branch_narrow_only($is_branch, $base);
690721
push @operands, $val;
691722
}
692723
return undef unless $used_mem;
693-
return { text => lc($mnem) . ' ' . join(', ', @operands), needs64 => $needs64 };
724+
return { text => lc($mnem) . ' ' . join(', ', @operands), needs64 => $needs64, avoid64 => $avoid64 };
694725
}
695726

696727
sub make_rng {
@@ -768,16 +799,20 @@ sub render_body {
768799
my @operands;
769800
my $ok = 1;
770801
my $needs64 = 0;
802+
my $avoid64 = 0;
771803
for my $tok (@{ $t->{ops} }) {
772804
my $val = gen_operand($rng, $tok, $mnem, $is_branch);
773805
if (!defined $val) { $ok = 0; last; }
774-
$needs64 = 1 if $needs64_token{ base_token($tok) };
806+
my $base = base_token($tok);
807+
$needs64 = 1 if $needs64_token{$base};
808+
$avoid64 = 1 if branch_narrow_only($is_branch, $base);
775809
push @operands, $val;
776810
}
777811
next unless $ok;
778812
push @lines, {
779813
text => lc($mnem) . (@operands ? ' ' . join(', ', @operands) : ''),
780814
needs64 => $needs64,
815+
avoid64 => $avoid64,
781816
};
782817

783818
# Optional-operand ('*'/'?') coverage: also emit the
@@ -791,9 +826,11 @@ sub render_body {
791826
push @lines, {
792827
text => lc($mnem) . (@reduced ? ' ' . join(', ', @reduced) : ''),
793828
needs64 => $needs64,
829+
avoid64 => $avoid64,
794830
};
795831
}
796832

833+
797834
# Register-number coverage: once per template (not once per
798835
# --variants instance), also try building an all-hireg
799836
# (r8-r15/xmm8-15/...) and an all-apxreg (r16-r31/xmm16-31)
@@ -848,7 +885,17 @@ sub render_body {
848885
for my $t (@dedup_all) {
849886
for my $disp (1, 64) {
850887
my $dl = build_dispboundary_line($rng, $mnem, $t->{ops}, $is_branch, $disp);
851-
push @extra_dispboundary, $dl if defined $dl;
888+
# avoid64 candidates (CALL/JMP rm16/rm32 near-indirect
889+
# targets -- see branch_narrow_only()) are dropped here
890+
# rather than fed into the bits=64 probe: they're
891+
# guaranteed to fail at 64-bit, and folding them into this
892+
# bucket would either cost the whole bucket its otherwise-
893+
# valid candidates (probe rejects the merge) or need a
894+
# second parallel probe path for no real benefit, since
895+
# this supplementary boundary coverage isn't the base
896+
# per-mnemonic content the 64-bit error-case block (below)
897+
# is built from.
898+
push @extra_dispboundary, $dl if defined $dl && !$dl->{avoid64};
852899
}
853900
}
854901

@@ -861,12 +908,21 @@ sub render_body {
861908
# which this generator doesn't parse directly (see comment above).
862909
for my $t (@dedup_all) {
863910
my $dl = build_implicitsize_line($rng, $mnem, $t->{ops}, $is_branch);
864-
push @extra_implicitsize, $dl if defined $dl;
911+
push @extra_implicitsize, $dl if defined $dl && !$dl->{avoid64};
865912
}
866913

914+
867915
next unless @lines; # nothing we knew how to generate
868916

869917
my @narrow_lines = grep { !$_->{needs64} } @lines;
918+
# Lines that only assemble in 16/32-bit mode (currently just
919+
# CALL/JMP rm16/rm32 near-indirect targets -- branch_narrow_only())
920+
# must symmetrically be excluded from the 64-bit "full" body: they
921+
# aren't flagged needs64 (they don't require 64-bit -- the opposite
922+
# holds, they're incompatible with it), so they'd otherwise poison
923+
# bits=64 assembly for the *entire* file the same way a needs64
924+
# line would poison bits=16/32.
925+
my @lines64 = grep { !$_->{avoid64} } @lines;
870926

871927
my $dirname = "$out_dir/" . lc($mnem);
872928
make_path($dirname);
@@ -923,7 +979,7 @@ sub render_body {
923979
return $ok;
924980
};
925981

926-
my @full_lines = @lines;
982+
my @full_lines = @lines64;
927983
for my $cat (\@extra_hireg, \@extra_apxreg, \@extra_mask, \@extra_maskz,
928984
\@extra_broadcast, \@extra_saeer, \@extra_dispboundary,
929985
\@extra_implicitsize) {
@@ -945,6 +1001,47 @@ sub render_body {
9451001
close($nfh);
9461002
}
9471003

1004+
# Error-case coverage: lines that only assemble in 64-bit mode
1005+
# (reg64/imm64 operands, hireg r8-r15, apxreg r16-r31, etc. -- see
1006+
# %needs64_token / build_variant_line) are, by construction, exactly
1007+
# the lines excluded from the 16/32-bit "narrow" body above. Rather
1008+
# than inventing a separate error-only source file, append them to
1009+
# the *same* narrow file under a %ifdef ERROR guard (per the user's
1010+
# preferred convention: one .asm file, assembled twice -- with and
1011+
# without -DERROR). Without -DERROR the block is invisible and
1012+
# narrow-mode coverage is unaffected; with -DERROR the block is
1013+
# included and attempting to assemble it at --bits 16/32 should
1014+
# fail with a mode/operand-mismatch diagnostic, which is exactly
1015+
# the negative-test coverage we want. Each bit width is probed
1016+
# independently below and only kept if it actually fails, so a line
1017+
# that unexpectedly *does* assemble at some width (this generator
1018+
# doesn't model every mode restriction) doesn't turn into a bogus
1019+
# "expected error" test.
1020+
my @error_lines = grep { $_->{needs64} } @full_lines;
1021+
my $has_narrow_file = ($asmfile_narrow ne $asmfile_full);
1022+
if ($has_narrow_file && @error_lines) {
1023+
open(my $efh, '>>', "$dirname/$asmfile_narrow") or die $!;
1024+
print $efh "\n%ifdef ERROR\n";
1025+
print $efh join('', map { "\t$_->{text}\n" } @error_lines);
1026+
print $efh "%endif\n";
1027+
close($efh);
1028+
}
1029+
1030+
# Symmetric case: lines that only assemble in 16/32-bit mode
1031+
# (CALL/JMP rm16/rm32 near-indirect targets -- branch_narrow_only())
1032+
# are excluded from @full_lines above; append them to the *full*
1033+
# (64-bit) body under the same %ifdef ERROR convention, so
1034+
# attempting to assemble them at --bits 64 with -DERROR is
1035+
# exercised as an expected-error case too.
1036+
my @error64_lines = grep { $_->{avoid64} } @lines;
1037+
if (@error64_lines) {
1038+
open(my $e6fh, '>>', "$dirname/$asmfile_full") or die $!;
1039+
print $e6fh "\n%ifdef ERROR\n";
1040+
print $e6fh join('', map { "\t$_->{text}\n" } @error64_lines);
1041+
print $e6fh "%endif\n";
1042+
close($e6fh);
1043+
}
1044+
9481045
my @json_entries;
9491046
for my $bits (16, 32, 64) {
9501047
my $asmfile = ($bits == 64 || !@narrow_lines) ? $asmfile_full : $asmfile_narrow;
@@ -979,9 +1076,47 @@ sub render_body {
9791076
}
9801077
}
9811078

982-
if (!@json_entries) {
1079+
# Error-case coverage: probe the %ifdef ERROR block(s) appended
1080+
# above with -DERROR defined, and only turn each into a json
1081+
# "expected error" entry for the (source file, bit width) pairs
1082+
# where it actually fails to assemble.
1083+
my $probe_error_bits = sub {
1084+
my ($src, @bitlist) = @_;
1085+
for my $bits (@bitlist) {
1086+
my $errbin = lc($mnem) . ".errprobe$bits.bin";
1087+
my $errstderr = lc($mnem) . ".stderr${bits}err";
1088+
my $relsrc = "$dirref/$src";
1089+
my $cmd = sprintf('%s --bits %d -DERROR -f bin %s %s -o %s.tmp 2>%s',
1090+
$nasm_bin, $bits, $warn_opts, $relsrc,
1091+
"$dirname/$errbin", "$dirname/$errstderr");
1092+
system($cmd);
1093+
my $rc = $? >> 8;
1094+
unlink("$dirname/$errbin.tmp");
1095+
my $fails = ($rc != 0);
1096+
unlink("$dirname/$errstderr");
1097+
if ($fails) {
1098+
push @json_entries, {
1099+
id => lc($mnem) . $bits . 'err',
1100+
bits => $bits,
1101+
source => $src,
1102+
opts => "-DERROR $warn_opts",
1103+
stderr => $errstderr,
1104+
is_error => 1,
1105+
};
1106+
}
1107+
}
1108+
};
1109+
$probe_error_bits->($asmfile_narrow, 16, 32) if $has_narrow_file && @error_lines;
1110+
$probe_error_bits->($asmfile_full, 64) if @error64_lines;
1111+
1112+
if (!grep { !$_->{is_error} } @json_entries) {
9831113
# Couldn't assemble in any mode -- drop the whole directory,
984-
# don't leave a dangling/empty test case behind.
1114+
# don't leave a dangling/empty test case behind. (Error-case
1115+
# entries alone don't count: a directory whose only "coverage"
1116+
# is "this asm never assembles" isn't meaningful regression
1117+
# coverage and would only mask a real generation bug -- see
1118+
# the is_branch operand-substitution fix above, discovered via
1119+
# exactly this scenario.)
9851120
unlink("$dirname/$asmfile_full");
9861121
unlink("$dirname/$asmfile_narrow") if $asmfile_narrow ne $asmfile_full;
9871122
rmdir($dirname);
@@ -995,6 +1130,22 @@ sub render_body {
9951130
for my $e (@json_entries) {
9961131
print $jf ",\n" unless $first;
9971132
$first = 0;
1133+
if ($e->{is_error}) {
1134+
printf $jf <<"JSON", $mnem, $e->{id}, $e->{source}, $e->{bits}, $e->{opts}, $dirname, $e->{stderr};
1135+
{
1136+
"description": "Pseudorandom error-case test for %s",
1137+
"id": "%s",
1138+
"format": "bin",
1139+
"source": "%s",
1140+
"option": "--bits %d %s -I./%s/",
1141+
"target": [
1142+
{ "stderr": "%s" }
1143+
],
1144+
"error": "expected"
1145+
}
1146+
JSON
1147+
next;
1148+
}
9981149
my $stderr_target = $e->{stderr}
9991150
? qq(,\n { "stderr": "$e->{stderr}" })
10001151
: '';

travis/insns/aadd/aadd.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,28 @@
99
{ "output": "aadd.bin64", "match": "aadd.bin64.t" }
1010
]
1111
}
12+
,
13+
{
14+
"description": "Pseudorandom error-case test for AADD",
15+
"id": "aadd16err",
16+
"format": "bin",
17+
"source": "aadd_narrow.asm",
18+
"option": "--bits 16 -DERROR -w-ea-absolute -w-implicit-abs-deprecated -I./travis/insns/aadd/",
19+
"target": [
20+
{ "stderr": "aadd.stderr16err" }
21+
],
22+
"error": "expected"
23+
}
24+
,
25+
{
26+
"description": "Pseudorandom error-case test for AADD",
27+
"id": "aadd32err",
28+
"format": "bin",
29+
"source": "aadd_narrow.asm",
30+
"option": "--bits 32 -DERROR -w-ea-absolute -w-implicit-abs-deprecated -I./travis/insns/aadd/",
31+
"target": [
32+
{ "stderr": "aadd.stderr32err" }
33+
],
34+
"error": "expected"
35+
}
1236
]

travis/insns/aadd/aadd.stderr16err

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
./travis/insns/aadd/aadd_narrow.asm:1: error: instruction not supported in 16-bit mode
2+
./travis/insns/aadd/aadd_narrow.asm:2: error: instruction not supported in 16-bit mode
3+
./travis/insns/aadd/aadd_narrow.asm:5: error: instruction not supported in 16-bit mode
4+
./travis/insns/aadd/aadd_narrow.asm:6: error: instruction not supported in 16-bit mode
5+
./travis/insns/aadd/aadd_narrow.asm:7: error: instruction not supported in 16-bit mode
6+
./travis/insns/aadd/aadd_narrow.asm:8: error: instruction not supported in 16-bit mode
7+
./travis/insns/aadd/aadd_narrow.asm:9: error: instruction not supported in 16-bit mode
8+
./travis/insns/aadd/aadd_narrow.asm:10: error: instruction not supported in 16-bit mode
9+
./travis/insns/aadd/aadd_narrow.asm:11: error: instruction not supported in 16-bit mode
10+
./travis/insns/aadd/aadd_narrow.asm:12: error: instruction not supported in 16-bit mode
11+
./travis/insns/aadd/aadd_narrow.asm:13: error: instruction not supported in 16-bit mode

travis/insns/aadd/aadd.stderr32err

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
./travis/insns/aadd/aadd_narrow.asm:1: error: instruction not supported in 32-bit mode
2+
./travis/insns/aadd/aadd_narrow.asm:2: error: instruction not supported in 32-bit mode
3+
./travis/insns/aadd/aadd_narrow.asm:5: error: instruction not supported in 32-bit mode
4+
./travis/insns/aadd/aadd_narrow.asm:6: error: instruction not supported in 32-bit mode
5+
./travis/insns/aadd/aadd_narrow.asm:7: error: instruction not supported in 32-bit mode
6+
./travis/insns/aadd/aadd_narrow.asm:8: error: instruction not supported in 32-bit mode
7+
./travis/insns/aadd/aadd_narrow.asm:9: error: instruction not supported in 32-bit mode
8+
./travis/insns/aadd/aadd_narrow.asm:10: error: instruction not supported in 32-bit mode
9+
./travis/insns/aadd/aadd_narrow.asm:11: error: instruction not supported in 32-bit mode
10+
./travis/insns/aadd/aadd_narrow.asm:12: error: instruction not supported in 32-bit mode
11+
./travis/insns/aadd/aadd_narrow.asm:13: error: instruction not supported in 32-bit mode

travis/insns/aadd/aadd_narrow.asm

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,14 @@
11
aadd dword [0xe1b], ebx
22
aadd dword [0x7dc], ecx
3+
4+
%ifdef ERROR
5+
aadd qword [0xeca], rcx
6+
aadd qword [0x4e4], rcx
7+
aadd dword [0xbc9], r13d
8+
aadd qword [0xa2a], r10
9+
aadd dword [0xcad], r16d
10+
aadd qword [0x5c3], r17
11+
aadd qword [eax+1], rbx
12+
aadd qword [eax+64], rcx
13+
aadd [0x5d8], rdi
14+
%endif

travis/insns/aand/aand.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,28 @@
99
{ "output": "aand.bin64", "match": "aand.bin64.t" }
1010
]
1111
}
12+
,
13+
{
14+
"description": "Pseudorandom error-case test for AAND",
15+
"id": "aand16err",
16+
"format": "bin",
17+
"source": "aand_narrow.asm",
18+
"option": "--bits 16 -DERROR -w-ea-absolute -w-implicit-abs-deprecated -I./travis/insns/aand/",
19+
"target": [
20+
{ "stderr": "aand.stderr16err" }
21+
],
22+
"error": "expected"
23+
}
24+
,
25+
{
26+
"description": "Pseudorandom error-case test for AAND",
27+
"id": "aand32err",
28+
"format": "bin",
29+
"source": "aand_narrow.asm",
30+
"option": "--bits 32 -DERROR -w-ea-absolute -w-implicit-abs-deprecated -I./travis/insns/aand/",
31+
"target": [
32+
{ "stderr": "aand.stderr32err" }
33+
],
34+
"error": "expected"
35+
}
1236
]

0 commit comments

Comments
 (0)