Skip to content

Crash when evaluating folds involving lambdas and variadic templates #99877

Open
@ilya-biryukov

Description

@ilya-biryukov

On this code:

struct tuple {
    int x[3];
};

template <class F>
void apply(F f, tuple v) {
    return f(v.x[0], v.x[1], v.x[2]);
}

void Cartesian(auto x, auto y) {
    apply([&](auto... xs) {
        (apply([xs](auto... ys) {
            (ys + ...);
        }, y), ...);
    }, x);
}

int main() {
    auto x = tuple({1, 2, 3});
    auto y = tuple({4, 5, 6});
    Cartesian(x, y);
}

Clang will crash with a following assertion error:

clang++: /root/llvm-project/clang/lib/Sema/TreeTransform.h:15248: clang::ExprResult clang::TreeTransform<Derived>::TransformCXXFoldExpr(clang::CXXFoldExpr*) [with Derived = {anonymous}::TemplateInstantiator; clang::ExprResult = clang::ActionResult<clang::Expr*>]: Assertion `!Unexpanded.empty() && "Pack expansion without parameter packs?"' failed.

The problem arises because when substituting into inner lambdas, Clang will incorrectly loose the ContainsUnexpandedPack dependency on a lambda expression. In turn, this confuses the CXXFoldExpr that relies in this flag to distinguish left and right folds, which will pass the nullptr expr to CollectUnexpandedParameterPacks and cause it to not find any packs when transforming the fold expression, leading to an asssertion.

I have already been working on a fix for a few days and more sophisticated tests, so assigning to myself right away.

Metadata

Metadata

Assignees

Labels

clang:frontendLanguage frontend issues, e.g. anything involving "Sema"crashPrefer [crash-on-valid] or [crash-on-invalid]lambdaC++11 lambda expressions

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions