From 8cb1a1518f9632f49aed28342c6b17fa354a0285 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Thu, 7 Mar 2024 11:17:24 +0100 Subject: [PATCH] Expr: Handle TYPE_VOID in SizeExpr and AssignExpr::Typecheck() @vpax reported surprising behavior when working with "void values". While these are not exposed to script land, plumb the places he pointed out are causing confusing behavior. Closes #3640. --- src/Expr.cc | 11 ++++- .../Baseline/language.void-errors-2/output | 2 + .../Baseline/language.void-errors-3/output | 2 + .../Baseline/language.void-errors-4/output | 2 + .../Baseline/language.void-errors-5/output | 2 + .../Baseline/language.void-errors-6/output | 2 + .../Baseline/language.void-errors-7/output | 4 ++ .../Baseline/language.void-errors/output | 2 + testing/btest/language/void-errors.zeek | 43 +++++++++++++++++++ 9 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 testing/btest/Baseline/language.void-errors-2/output create mode 100644 testing/btest/Baseline/language.void-errors-3/output create mode 100644 testing/btest/Baseline/language.void-errors-4/output create mode 100644 testing/btest/Baseline/language.void-errors-5/output create mode 100644 testing/btest/Baseline/language.void-errors-6/output create mode 100644 testing/btest/Baseline/language.void-errors-7/output create mode 100644 testing/btest/Baseline/language.void-errors/output create mode 100644 testing/btest/language/void-errors.zeek diff --git a/src/Expr.cc b/src/Expr.cc index dde0575490..94c2b22e47 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -1313,7 +1313,9 @@ SizeExpr::SizeExpr(ExprPtr arg_op) : UnaryExpr(EXPR_SIZE, std::move(arg_op)) { auto& t = op->GetType(); - if ( t->Tag() == TYPE_ANY ) + if ( t->Tag() == TYPE_VOID ) + SetError("cannot take size of void"); + else if ( t->Tag() == TYPE_ANY ) SetType(base_type(TYPE_ANY)); else if ( t->Tag() == TYPE_FILE || t->Tag() == TYPE_SUBNET || t->InternalType() == TYPE_INTERNAL_DOUBLE ) SetType(base_type(TYPE_DOUBLE)); @@ -2204,6 +2206,11 @@ bool AssignExpr::TypeCheck(const AttributesPtr& attrs) { TypeTag bt1 = op1->GetType()->Tag(); TypeTag bt2 = op2->GetType()->Tag(); + if ( bt2 == TYPE_VOID ) { + ExprError("can't assign void value"); + return false; + } + if ( bt1 == TYPE_LIST && bt2 == TYPE_ANY ) // This is ok because we cannot explicitly declare lists on // the script level. @@ -2241,7 +2248,7 @@ bool AssignExpr::TypeCheck(const AttributesPtr& attrs) { } } - if ( op1->GetType()->Tag() == TYPE_RECORD && op2->GetType()->Tag() == TYPE_RECORD ) { + if ( bt1 == TYPE_RECORD && bt2 == TYPE_RECORD ) { if ( same_type(op1->GetType(), op2->GetType()) ) return true; diff --git a/testing/btest/Baseline/language.void-errors-2/output b/testing/btest/Baseline/language.void-errors-2/output new file mode 100644 index 0000000000..77c3fb552a --- /dev/null +++ b/testing/btest/Baseline/language.void-errors-2/output @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/void-errors.zeek, line 2: identifier not defined: void diff --git a/testing/btest/Baseline/language.void-errors-3/output b/testing/btest/Baseline/language.void-errors-3/output new file mode 100644 index 0000000000..5c126a4aab --- /dev/null +++ b/testing/btest/Baseline/language.void-errors-3/output @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/void-errors.zeek, line 1: identifier not defined: void diff --git a/testing/btest/Baseline/language.void-errors-4/output b/testing/btest/Baseline/language.void-errors-4/output new file mode 100644 index 0000000000..60fd435cfe --- /dev/null +++ b/testing/btest/Baseline/language.void-errors-4/output @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/void-errors.zeek, line 2: return statement cannot have an expression (return (a)) diff --git a/testing/btest/Baseline/language.void-errors-5/output b/testing/btest/Baseline/language.void-errors-5/output new file mode 100644 index 0000000000..6fe5ee9b76 --- /dev/null +++ b/testing/btest/Baseline/language.void-errors-5/output @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/void-errors.zeek, line 4: cannot take size of void (sizeofx[3.4.5.6]) diff --git a/testing/btest/Baseline/language.void-errors-6/output b/testing/btest/Baseline/language.void-errors-6/output new file mode 100644 index 0000000000..80d7585be8 --- /dev/null +++ b/testing/btest/Baseline/language.void-errors-6/output @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/void-errors.zeek, line 2: can't assign void value (y = x[3]) diff --git a/testing/btest/Baseline/language.void-errors-7/output b/testing/btest/Baseline/language.void-errors-7/output new file mode 100644 index 0000000000..29dbf68b43 --- /dev/null +++ b/testing/btest/Baseline/language.void-errors-7/output @@ -0,0 +1,4 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/void-errors.zeek, line 5: can't assign void value (z = x()) +error in <...>/void-errors.zeek, line 6: value of type void illegal (print x()) +error in <...>/void-errors.zeek, line 7: cannot take size of void (sizeofx()) diff --git a/testing/btest/Baseline/language.void-errors/output b/testing/btest/Baseline/language.void-errors/output new file mode 100644 index 0000000000..c64263c499 --- /dev/null +++ b/testing/btest/Baseline/language.void-errors/output @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/void-errors.zeek, line 7: identifier not defined: void diff --git a/testing/btest/language/void-errors.zeek b/testing/btest/language/void-errors.zeek new file mode 100644 index 0000000000..042872bd78 --- /dev/null +++ b/testing/btest/language/void-errors.zeek @@ -0,0 +1,43 @@ +# @TEST-DOC: Zeek does not have a script land void type, but internally it does exist (indexing a set, or a function returning no result). Regression test #3640. +# +# @TEST-EXEC-FAIL: zeek -b %INPUT >output 2>&1 +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff output + +# identifier void not defined... +global x: void = 1; + +# @TEST-START-NEXT +type R: record { + x: void; +}; + + +# @TEST-START-NEXT +function x(): void { + return "a"; +}; + +# @TEST-START-NEXT +function x() { + return "a"; +}; + +# @TEST-START-NEXT + +global x = set(3.4.5.6, 9.8.7.6); +print |x|; +print |x[3.4.5.6]|; + +# @TEST-START-NEXT +local x = set(5, 3); +local y: any = x[3]; +print y; + +# @TEST-START-NEXT +function x() { + print "x()"; +} + +global z: any = x(); +print x(); +print |x()|;