Skip to content

Commit 4207c82

Browse files
Jordan Romejordalgo
authored andcommitted
Restrict use some map aggregation types
lhist/hist/stats have some restrictions in that they cannot be referenced inside tuples and single key values cannot be printed; the entire map must be printed. This latter restriction could be relaxed; it just requires the development work to support it. Issue: bpftrace#3540
1 parent 22b7ecd commit 4207c82

File tree

3 files changed

+33
-5
lines changed

3 files changed

+33
-5
lines changed

src/ast/passes/semantic_analyser.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ static bool IsValidVarDeclType(const SizedType &ty)
131131
// `@a = hist(10); @b = @a;`
132132
static bool IsValidAssignment(const SizedType &ty, bool is_map)
133133
{
134-
if (is_map && (ty.IsHistTy() || ty.IsLhistTy() || ty.IsStatsTy())) {
134+
if (is_map && (ty.IsMultiOutputMapTy())) {
135135
return false;
136136
}
137137
return true;
@@ -1209,10 +1209,16 @@ void SemanticAnalyser::visit(Call &call)
12091209
if (arg.is_map) {
12101210
Map &map = static_cast<Map &>(arg);
12111211
if (map.key_expr) {
1212-
if (call.vargs.size() > 1)
1212+
if (call.vargs.size() > 1) {
12131213
LOG(ERROR, call.loc, err_) << "Single-value (i.e. indexed) map "
12141214
"print cannot take additional "
12151215
"arguments.";
1216+
} else if (map.type.IsMultiOutputMapTy()) {
1217+
LOG(ERROR, call.loc, err_)
1218+
<< "Map type " << map.type
1219+
<< " cannot print the value of individual keys. You must print "
1220+
"the whole map.";
1221+
}
12161222
}
12171223

12181224
if (is_final_pass()) {
@@ -2756,8 +2762,12 @@ void SemanticAnalyser::visit(Tuple &tuple)
27562762
// If elem type is none that means that the tuple contains some
27572763
// invalid cast (e.g., (0, (aaa)0)). In this case, skip the tuple
27582764
// creation. Cast already emits the error.
2759-
if (elem->type.IsNoneTy() || elem->type.GetSize() == 0)
2765+
if (elem->type.IsNoneTy() || elem->type.GetSize() == 0) {
27602766
return;
2767+
} else if (elem->type.IsMultiOutputMapTy()) {
2768+
LOG(ERROR, elem->loc, err_)
2769+
<< "Map type " << elem->type << " cannot exist inside a tuple.";
2770+
}
27612771
elements.emplace_back(elem->type);
27622772
}
27632773

src/types.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -478,8 +478,15 @@ class SizedType {
478478
}
479479
bool IsMapIterableTy() const
480480
{
481-
return !(type_ == Type::hist_t || type_ == Type::lhist_t ||
482-
type_ == Type::stats_t);
481+
return !IsMultiOutputMapTy();
482+
}
483+
484+
// These are special map value types that can't be reduced to a single value
485+
// and output multiple lines when printed
486+
bool IsMultiOutputMapTy() const
487+
{
488+
return type_ == Type::hist_t || type_ == Type::lhist_t ||
489+
type_ == Type::stats_t;
483490
}
484491

485492
bool NeedsPercpuMap() const;

tests/semantic_analyser.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,6 +1041,11 @@ BEGIN { print(@x[2]); }
10411041
stdin:1:20-38: ERROR: Single-value (i.e. indexed) map print cannot take additional arguments.
10421042
BEGIN { @x[1] = 1; print(@x[1], 3, 5); }
10431043
~~~~~~~~~~~~~~~~~~
1044+
)");
1045+
test_error("BEGIN { @x[1] = hist(10); print(@x[1]); }", R"(
1046+
stdin:1:27-39: ERROR: Map type hist_t cannot print the value of individual keys. You must print the whole map.
1047+
BEGIN { @x[1] = hist(10); print(@x[1]); }
1048+
~~~~~~~~~~~~
10441049
)");
10451050
}
10461051

@@ -3428,6 +3433,12 @@ BEGIN { $t = ((uint8)1, (2, 3)); $t = (4, ((int8)5, 6)); }
34283433

34293434
test(R"_(BEGIN { @t = (1, 2, "hi"); @t = (3, 4, "hellolongstr"); })_");
34303435
test(R"_(BEGIN { $t = (1, ("hi", 2)); $t = (3, ("hellolongstr", 4)); })_");
3436+
3437+
test_error("BEGIN { @x[1] = hist(10); $y = (1, @x[1]); }", R"(
3438+
stdin:1:36-41: ERROR: Map type hist_t cannot exist inside a tuple.
3439+
BEGIN { @x[1] = hist(10); $y = (1, @x[1]); }
3440+
~~~~~
3441+
)");
34313442
}
34323443

34333444
TEST(semantic_analyser, tuple_indexing)

0 commit comments

Comments
 (0)