Skip to content

Fold expressions miss parentheses #558

@Ukilele

Description

@Ukilele

Hello Andreas, there might be an issue with the transformation of fold expressions.
Following code:

void f(int) { }

void TestA(auto... args) {
  f((... , args));
}

void TestB(auto... args) {
  int b = (... , args);
}

template<int... Is>
void TestC() {
  f((... , Is));
}

template<int... Is>
void TestD() {
  int d = (... , Is);
}

int main() {
  TestA(10, 15);
  TestB(7, 8);
  TestC<1, 2, 3>();
  TestD<4, 5, 6>();
} 

generates following outcome:

void f(int)
{
}


void TestA(auto... args) {
  f((... , args));
}

/* First instantiated from: insights.cpp:22 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
void TestA<int, int>(int __args0, int __args1)
{
  f(__args0 , __args1);
}
#endif


void TestB(auto... args) {
  int b = (... , args);
}

/* First instantiated from: insights.cpp:23 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
void TestB<int, int>(int __args0, int __args1)
{
  int b = __args0 , __args1;
}
#endif


template<int ...Is>
void TestC()
{
  f((... , Is));
}


/* First instantiated from: insights.cpp:24 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
void TestC<1, 2, 3>()
{
  f((1 , 2) , 3);
}
#endif


template<int ...Is>
void TestD()
{
  int d = (... , Is);
}


/* First instantiated from: insights.cpp:25 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
void TestD<4, 5, 6>()
{
  int d = (4 , 5) , 6;
}
#endif


int main()
{
  TestA(10, 15);
  TestB(7, 8);
  TestC<1, 2, 3>();
  TestD<4, 5, 6>();
  return 0;
}
 

In all four of my Test-functions, the issue is, that the fold expression does not contain the right amount of parentheses around them. According to https://eel.is/c++draft/temp.variadic#11, a unary left fold of the form (... , Is) should expand to ( ((Is1, Is2) , ...) , IsN ). But this is not, what cppinsights generates.
I added four Test-functions. TestA and TestB test the behavior with a function parameter pack, while TestC and TestD test the behavior with a template parameter pack. TestA and TestC use the fold expression within a function call, while TestC and TestD use the fold expression in an initialization. I did not check the behavior for the other kind of fold expressions (e.g. binary right fold) and other kind of operators, but I guess the behavior will be similar?

Cheers!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions