Bug 49043

Summary: [OpenMP & C++0x]: Compiler error when lambda-function within OpenMP loop
Product: gcc Reporter: Joel Yliluoma <bisqwit>
Component: c++Assignee: Jakub Jelinek <jakub>
Status: RESOLVED FIXED    
Severity: normal CC: jakub
Priority: P3    
Version: 4.6.1   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2011-05-19 08:55:08
Attachments: gcc46-pr49043.patch

Description Joel Yliluoma 2011-05-18 13:07:43 UTC
GCC incorrectly considers return statements within lambda functions as "exits" from an OpenMP structured block.

For the code below, this error message is generated:

tmp3.cc: In lambda function:
tmp3.cc:7:40: error: invalid exit from OpenMP structured block

#include <iostream>
int main()
{
    #pragma omp parallel for
    for(int a=0; a<10; ++a)
    {
        auto func = [=] () { return a; };
        std::cout << func();
    }
}

Compiled with: -fopenmp -std=gnu++0x
Tested versions: 4.5.3 , 4.6.1

The purpose of this error is to catch exits from an OpenMP construct (return, break, goto). No such thing happens when a lamdba function is called, which is not different from calling an inlined function, therefore the error message is misplaced.
Comment 1 Joel Yliluoma 2011-05-19 08:05:26 UTC
It also happens if the lambda-function does not explicitly contain the "return" statement.

For example, this code triggers the same error.

int main()
{
    #pragma omp parallel for
    for(int a=0; a<10; ++a)
    {
        auto func = [] () -> void { };
        func();
    }
}
Comment 2 Joel Yliluoma 2011-05-19 08:10:06 UTC
Even if the lambda function is not called, it happens. Merely defining the function causes it.
Interestingly though, it does not happen if a method body is defined within the loop. The code below does not cause the error. So it is restricted to lambda function bodies.
It also does not happen when calling lambda functions that are defined outside the loop.

int main()
{
    #pragma omp parallel for
    for(int a=0; a<10; ++a)
    {
        struct tmp
        {
            static int test() { return 0; }
        };
    }
}
Comment 3 Jakub Jelinek 2011-05-19 08:55:08 UTC
Created attachment 24287 [details]
gcc46-pr49043.patch

Untested fix.

That said, I'd advise not to use lambdas in OpenMP regions, because the OpenMP standard doesn't say anything about the data environment of those and how it
should behave.  Even the upcoming OpenMP 3.1 doesn't cover C++0x, I hope OpenMP 4.0 will.
Comment 4 Jakub Jelinek 2011-05-19 13:12:02 UTC
Author: jakub
Date: Thu May 19 13:11:56 2011
New Revision: 173907

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=173907
Log:
	PR c++/49043
	* decl.c (check_omp_return): Stop searching on sk_function_parms.

	* testsuite/libgomp.c++/pr49043.C: New test.

Added:
    trunk/libgomp/testsuite/libgomp.c++/pr49043.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/decl.c
    trunk/libgomp/ChangeLog
Comment 5 Jakub Jelinek 2011-05-19 13:14:00 UTC
Author: jakub
Date: Thu May 19 13:13:57 2011
New Revision: 173908

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=173908
Log:
	PR c++/49043
	* decl.c (check_omp_return): Stop searching on sk_function_parms.

	* testsuite/libgomp.c++/pr49043.C: New test.

Added:
    branches/gcc-4_6-branch/libgomp/testsuite/libgomp.c++/pr49043.C
Modified:
    branches/gcc-4_6-branch/gcc/cp/ChangeLog
    branches/gcc-4_6-branch/gcc/cp/decl.c
    branches/gcc-4_6-branch/libgomp/ChangeLog
Comment 6 Jakub Jelinek 2011-05-19 13:39:33 UTC
Fixed.
Comment 7 Jakub Jelinek 2011-07-25 09:54:13 UTC
*** Bug 49100 has been marked as a duplicate of this bug. ***