@@ -420,6 +420,11 @@ static void Instantiate(OmpStylizedExpression &ose,
420420 // 2. Run the parser to get the AST for the stylized expression.
421421 // 3. Create OmpStylizedInstance and append it to the list in ose.
422422 assert(types.size() == vars.size() && "List size mismatch");
423+ // A ParseState object is irreversibly modified during parsing (in
424+ // particular, it cannot be rewound to an earlier position in the source).
425+ // Because of that we need to create a local copy for each instantiation.
426+ // If rewinding was possible, we could just use the current one, and we
427+ // wouldn't need to save it in the AST node.
423428 ParseState state{DEREF(ose.state)};
424429
425430 std::list<OmpStylizedDeclaration> decls;
@@ -460,6 +465,7 @@ static void InstantiateDeclareReduction(OmpDirectiveSpecification &spec) {
460465 InstantiateForTypes(const_cast<OmpCombinerExpression &>(*cexpr), *typeNames,
461466 OmpCombinerExpression::Variables());
462467 delete cexpr->state;
468+ cexpr->state = nullptr;
463469 } else {
464470 // If there are no types, there is nothing else to do.
465471 return;
@@ -472,6 +478,7 @@ static void InstantiateDeclareReduction(OmpDirectiveSpecification &spec) {
472478 InstantiateForTypes(const_cast<OmpInitializerExpression &>(*iexpr),
473479 *typeNames, OmpInitializerExpression::Variables());
474480 delete iexpr->state;
481+ iexpr->state = nullptr;
475482 }
476483 }
477484 }
0 commit comments