Skip to content

Commit 9b63e88

Browse files
dplassgitcopybara-github
authored andcommitted
[DSLX Fuzz testing] Add a FuzzTestFunction AST node in addition to the
`#[fuzz_test]` attribute. This is needed to unlock parsing and type- checking the fuzz test domains as a tuple. PiperOrigin-RevId: 896502488
1 parent 801871b commit 9b63e88

File tree

7 files changed

+95
-0
lines changed

7 files changed

+95
-0
lines changed

xls/dslx/frontend/ast.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,8 @@ std::string_view AstNodeKindToString(AstNodeKind kind) {
311311
return "for";
312312
case AstNodeKind::kFunctionRef:
313313
return "function-ref";
314+
case AstNodeKind::kFuzzTestFunction:
315+
return "fuzz test function";
314316
case AstNodeKind::kStatementBlock:
315317
return "statement-block";
316318
case AstNodeKind::kTrait:
@@ -2419,6 +2421,10 @@ Function::LambdaReturnTypeParametrics() const {
24192421

24202422
TestFunction::~TestFunction() = default;
24212423

2424+
// -- class FuzzTestFunction
2425+
2426+
FuzzTestFunction::~FuzzTestFunction() = default;
2427+
24222428
// -- class Lambda
24232429

24242430
Lambda::Lambda(Module* owner, Span span, Function* function, bool in_parens)

xls/dslx/frontend/ast.h

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
X(ConstantDef) \
9595
X(EnumDef) \
9696
X(Function) \
97+
X(FuzzTestFunction) \
9798
X(Impl) \
9899
X(Import) \
99100
X(Let) \
@@ -3843,6 +3844,8 @@ class Range : public Expr {
38433844
// #[test]
38443845
// fn test_foo() { ... }
38453846
// ```
3847+
// TODO: davidplass - Add an optional parameter Expr to allow re-using as a
3848+
// FuzzTestFunction or QuickCheck.
38463849
class TestFunction : public AstNode {
38473850
public:
38483851
static std::string_view GetDebugTypeName() { return "test function"; }
@@ -3879,6 +3882,72 @@ class TestFunction : public AstNode {
38793882
Function& fn_;
38803883
};
38813884

3885+
// Represents a fuzz test construct.
3886+
//
3887+
// These are specified with an annotation as follows:
3888+
//
3889+
// ```dslx
3890+
// #[fuzz_test]
3891+
// fn test_foo() { ... }
3892+
// ```
3893+
//
3894+
// or with a domains argument:
3895+
//
3896+
// ```dslx
3897+
// #[fuzz_test(domains=`...`)]
3898+
// fn test_foo() { ... }
3899+
// ```
3900+
// TODO: davidplass - Migrate this into TestFunction, after adding an optional
3901+
// parameter to TestFunction to capture the domain tuple.
3902+
class FuzzTestFunction : public AstNode {
3903+
public:
3904+
static std::string_view GetDebugTypeName() { return "fuzz test function"; }
3905+
3906+
FuzzTestFunction(Module* owner, Span span, Function& fn,
3907+
std::optional<Expr*> domains)
3908+
: AstNode(owner),
3909+
span_(std::move(span)),
3910+
fn_(fn),
3911+
domains_(std::move(domains)) {}
3912+
3913+
~FuzzTestFunction() override;
3914+
3915+
AstNodeKind kind() const override { return AstNodeKind::kFuzzTestFunction; }
3916+
NameDef* name_def() const { return fn_.name_def(); }
3917+
3918+
absl::Status Accept(AstNodeVisitor* v) const override {
3919+
return v->HandleFuzzTestFunction(this);
3920+
}
3921+
3922+
std::vector<AstNode*> GetChildren(bool want_types) const override {
3923+
return {&fn_};
3924+
}
3925+
3926+
std::string_view GetNodeTypeName() const override {
3927+
return "FuzzTestFunction";
3928+
}
3929+
std::string ToString() const override {
3930+
if (domains_.has_value()) {
3931+
return absl::StrFormat("#[fuzz_test(domains=`%s`)]\n%s",
3932+
(*domains_)->ToString(), fn_.ToString());
3933+
}
3934+
return absl::StrFormat("#[fuzz_test]\n%s", fn_.ToString());
3935+
}
3936+
3937+
Function& fn() const { return fn_; }
3938+
std::optional<Span> GetSpan() const override { return span(); }
3939+
const Span& span() const { return span_; }
3940+
3941+
const std::string& identifier() const { return fn_.name_def()->identifier(); }
3942+
3943+
const std::optional<Expr*>& domains() const { return domains_; }
3944+
3945+
private:
3946+
const Span span_;
3947+
Function& fn_;
3948+
const std::optional<Expr*> domains_;
3949+
};
3950+
38823951
enum class QuickCheckTestCasesTag {
38833952
kExhaustive,
38843953
kCounted,
@@ -3914,6 +3983,8 @@ class QuickCheckTestCases {
39143983
};
39153984

39163985
// Represents a function to be quick-check'd.
3986+
// TODO: davidplass - Migrate this into TestFunction, since QuickCheck is an
3987+
// attribute which can capture the quick check test cases.
39173988
class QuickCheck : public AstNode {
39183989
public:
39193990
static std::string_view GetDebugTypeName() { return "quickcheck"; }

xls/dslx/frontend/ast_cloner.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,17 @@ class AstCloner : public AstNodeVisitor {
10471047
return absl::OkStatus();
10481048
}
10491049

1050+
absl::Status HandleFuzzTestFunction(const FuzzTestFunction* n) override {
1051+
XLS_RETURN_IF_ERROR(VisitChildren(n));
1052+
1053+
XLS_RETURN_IF_ERROR(ReplaceOrVisit(&n->fn()));
1054+
XLS_ASSIGN_OR_RETURN(Function * new_fn, CastIfNotVerbatim<Function*>(
1055+
old_to_new_.at(&n->fn())));
1056+
old_to_new_[n] =
1057+
module(n)->Make<FuzzTestFunction>(n->span(), *new_fn, n->domains());
1058+
return absl::OkStatus();
1059+
}
1060+
10501061
absl::Status HandleTestProc(const TestProc* n) override {
10511062
XLS_RETURN_IF_ERROR(VisitChildren(n));
10521063

xls/dslx/frontend/ast_node.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ enum class AstNodeKind : uint8_t {
5252
kFormatMacro,
5353
kFunction,
5454
kFunctionRef,
55+
kFuzzTestFunction,
5556
kImpl,
5657
kImport,
5758
kIndex,

xls/dslx/ir_convert/function_converter.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ class FunctionConverterVisitor : public AstNodeVisitor {
399399
// keep-sorted start
400400
INVALID(Attribute)
401401
INVALID(FunctionRef)
402+
INVALID(FuzzTestFunction)
402403
INVALID(MatchArm)
403404
INVALID(NameDef)
404405
INVALID(NameDefTree)

xls/dslx/type_system/type_info.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ enum AstNodeKindProto {
9797
AST_NODE_KIND_PROC_ALIAS = 72;
9898
AST_NODE_KIND_TRAIT = 73;
9999
AST_NODE_KIND_ATTRIBUTE = 74;
100+
AST_NODE_KIND_FUZZ_TEST_FUNCTION = 75;
100101
}
101102

102103
message BitsValueProto {

xls/dslx/type_system/type_info_to_proto.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ AstNodeKindProto ToProto(AstNodeKind kind) {
124124
return AST_NODE_KIND_SEND_IF;
125125
case AstNodeKind::kTestFunction:
126126
return AST_NODE_KIND_TEST_FUNCTION;
127+
case AstNodeKind::kFuzzTestFunction:
128+
return AST_NODE_KIND_FUZZ_TEST_FUNCTION;
127129
case AstNodeKind::kTestProc:
128130
return AST_NODE_KIND_TEST_PROC;
129131
case AstNodeKind::kWildcardPattern:
@@ -738,6 +740,8 @@ absl::StatusOr<AstNodeKind> FromProto(AstNodeKindProto p) {
738740
return AstNodeKind::kSendIf;
739741
case AST_NODE_KIND_TEST_FUNCTION:
740742
return AstNodeKind::kTestFunction;
743+
case AST_NODE_KIND_FUZZ_TEST_FUNCTION:
744+
return AstNodeKind::kFuzzTestFunction;
741745
case AST_NODE_KIND_TEST_PROC:
742746
return AstNodeKind::kTestProc;
743747
case AST_NODE_KIND_WILDCARD_PATTERN:

0 commit comments

Comments
 (0)