On Mon, Nov 14, 2016 at 11:53:55PM -0500, Jason Merrill wrote: > The standard says that references that refer to a constant address can > be used in a constant-expression, but we haven't allowed that. This > patch implements it, but without the parser.c hunk it broke > libgomp.c++/target-14.C.
The parser hunk can't be right, the decl you modify TREE_CONSTANT on is not in any way "an OpenMP variable", it is just a variable used in some OpenMP region, modifying the flag will affect all the handling of the variable, both outside and inside of OpenMP regions. > Apparently the target mapping wants to use 't' in a way that doesn't > actually refer to x? This seems like a strange use of references. Yes. The privatization and mapping of variables with reference type in OpenMP generally works by privatizing or mapping what that reference references, and then creating a new reference that references the privatized or mapped variable. Looking at the *.original dump diff without your patch to with your patch minus the parser.c hunk shows: - if ((*a != 8 || *c != 142) || *t != 19) + if ((*a != 8 || *c != 142) || *(int &) &x != 19) which might be fine outside of the OpenMP regions, from what you wrote I understood is required in constexpr contexts, but can't be right in the OpenMP regions - have to be deferred until omplower pass does whatever it needs to do. This is similar to DECL_VALUE_EXPR handling I've mentioned yesterday, there it is also dangerous to just fold var with DECL_VALUE_EXPR to its DECL_VALUE_EXPR until after omplower pass - the gimplifier gimplifies such vars to their DECL_VALUE_EXPR only if it is ok (omp_notice_variable function, e.g. together with disregard_value_expr langhook, decides on when it is ok or not). In target-14.C, there is mapping of reference t, so after lowering there is going to be in the region used variable t' that refers to some int in the target. Your patch replaces uses of t in the region much earlier with uses of &x, but that is something that isn't explicitly mapped, and the OpenMP 4.5 rules say that such variable is firstprivatized implicitly, so the code outside of the target region won't see any changes in the variable. So, is there a way to treat references the similarly? I.e. only "fold" reference vars to what they refer (DECL_INITIAL) in constexpr.c evaluation, or gimplification where a langhook or omp_notice_variable etc. has the last say on when it is ok to do that or not? Jakub