diff --git a/ChangeLog b/ChangeLog
index ec11c757d91f1bf84542ce4121cf10a37cdc4aca..de5ad71ae2c9c2d1f69589659d4dea06da837d35 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,12 @@
 2018-04-04  Jesper Öqvist <jesper.oqvist@cs.lth.se>
 
     * Fixed aliasing issue for parameterized NTAs in concurrent mode.
+    * Fixed race conditions for grammar-declared NTAs in concurrent mode.
+      See issue 291 and 292 on the issue tracker.
+    * Grammar-declared NTAs have been moved out of the child vector in
+      concurrent mode.
+    * Added a new internal helper method to ASTNode:
+      getChildNoTransformBase().
 
 2018-03-22  Jesper Öqvist <jesper.oqvist@cs.lth.se>
 
diff --git a/src/jastadd/ast/JaddCodeGen.jrag b/src/jastadd/ast/JaddCodeGen.jrag
index 96d09f14ba338e9631dc9f9c7dbfedef3162dae9..2f5a72f09506f475083fdb2610434ea334341244 100644
--- a/src/jastadd/ast/JaddCodeGen.jrag
+++ b/src/jastadd/ast/JaddCodeGen.jrag
@@ -105,6 +105,43 @@ aspect JaddCodeGen {
     return i;
   }
 
+  public void ASTDecl.emitConcurrentGetChild(PrintWriter out) {
+    // Build list of NTA indices.
+    String getNta = "";
+    int numNta = 0;
+    int i = 0;
+    for (Component c : components()) {
+      if (c instanceof TokenComponent) {
+        // Tokens are not stored in the child array.
+        continue;
+      }
+
+      String attrName = null;
+      if (c instanceof ListComponentNTA) {
+        attrName = "get" + c.name() + "List";
+      } else if (c instanceof OptionalComponentNTA) {
+        attrName = "get" + c.name() + "Opt";
+      } else if (c instanceof AggregateComponentNTA) {
+        attrName = "get" + c.name();
+      }
+
+      if (attrName != null) {
+        getNta += "case " + i + ":\n";
+        getNta += "  _value = " + attrName + "_value.get();\n";
+        getNta += "  break;\n";
+        numNta += 1;
+      }
+      i += 1;
+    }
+    TemplateContext tt = templateContext();
+    if (numNta > 0) {
+      tt.bind("GetNTAs", getNta);
+      tt.expand("ASTDecl.getChildNoTransform:concurrent", out);
+    } else {
+      tt.expand("ASTDecl.getChildNoTransform:concurrent:empty", out);
+    }
+  }
+
   /**
    * Default constructor: creates list and opt nodes for
    * all list and opt children. Initializes NTAs.
@@ -558,6 +595,14 @@ aspect JaddCodeGen {
     emitCopyNode(out);
     emitFullCopy(out);
     emitIsEqualMethods(out);
+
+    if (config().concurrentEval()
+        && !isASTNodeDecl()
+        && !isOptDecl()
+        && !isListDecl()) {
+      emitConcurrentGetChild(out);
+    }
+
     genIncremental(out);
   }
 
diff --git a/src/jastadd/ast/JragCodeGen.jrag b/src/jastadd/ast/JragCodeGen.jrag
index 4264d3aea553c503868e53cb608ad8ec4fa3add3..5f9e369a66619a7d4feac4996878fee1f9bda59e 100644
--- a/src/jastadd/ast/JragCodeGen.jrag
+++ b/src/jastadd/ast/JragCodeGen.jrag
@@ -731,7 +731,8 @@ aspect JragCodeGen {
           || attrName.equals(comp.name() + "Opt") && comp instanceof OptionalComponentNTA
           || attrName.equals(comp.name() + "List") && comp instanceof ListComponentNTA) {
         if (config().concurrentEval()) {
-          return "setChild(_result, get" + attrName + "ChildPosition());\n";
+          // Only link result with parent. Child vector is not used for NTAs in concurrent mode.
+          return "_result.setParent(this);\n";
         } else {
           return "setChild(" + signature() + "_value, get" + attrName + "ChildPosition());\n";
         }
diff --git a/src/template/ast/ASTNode.tt b/src/template/ast/ASTNode.tt
index d687c5f230d056b4ed50bc58d21e3718df01261e..8a7037396672df0e655e5c74c6bc3e034d4c9a52 100644
--- a/src/template/ast/ASTNode.tt
+++ b/src/template/ast/ASTNode.tt
@@ -495,15 +495,18 @@ $endif
 
 ASTNode.getChildNoTransform [[
   /**
-    * <p><em>This method does not invoke AST transformations.</em></p>
+    * Gets a child without triggering rewrites.
     * @apilevel low-level
     */
-  $if(IncrementalEnabled)
   public T $ASTNode.getChildNoTransform(int i) {
-  // Must be able to override get child methods for incremental evaluation
-  $else
-  public final T $ASTNode.getChildNoTransform(int i) {
-  $endif
+    return getChildNoTransformBase(i);
+  }
+
+  /**
+   * Directly accesses the child vector.
+   * @apilevel internal
+   */
+  public T $ASTNode.getChildNoTransformBase(int i) {
     if (children == null) {
       return null;
     }
diff --git a/src/template/concurrent/Attributes.tt b/src/template/concurrent/Attributes.tt
index 849c98c9511daa937907e6771efef4463b831579..51905a5db0b67123f6699ef74262c9bd76f23f8f 100644
--- a/src/template/concurrent/Attributes.tt
+++ b/src/template/concurrent/Attributes.tt
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2017, The JastAdd Team
+# Copyright (c) 2013-2018, The JastAdd Team
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -209,8 +209,17 @@ if (#(signature)_computed) {
     $else
 Object cached_value = #(signature)_value.get();
 if (cached_value != AttributeValue.NONE) {
-  #boxedType _value = (#boxedType) cached_value;
   $include(AttrDecl.traceCacheRead)
+  #boxedType _value = (#boxedType) cached_value;
+      $if(#isAttrNTA)$if(RewriteEnabled)
+  if (_value != null && _value.mayHaveRewrite()) {
+    $ASTNode rewritten = _value.rewrittenNode();
+    if (rewritten != _value) {
+      rewritten.setParent(this);
+      _value = (#boxedType) rewritten;
+    }
+  }
+      $endif$endif
   return _value;
     $endif
   $endif
@@ -339,3 +348,24 @@ if (state.inCircle()) {
 $endif
 $endif
 ]]
+
+# Delegates child lookups to corresponding higher-order attributes.
+ASTDecl.getChildNoTransform:concurrent [[
+  public $ASTNode #name.getChildNoTransform(int i) {
+    Object _value = AttributeValue.NONE;
+    switch (i) {
+      $GetNTAs
+    }
+    if (_value != AttributeValue.NONE) {
+      return ($ASTNode) _value;
+    }
+    return super.getChildNoTransformBase(i);
+  }
+]]
+
+ASTDecl.getChildNoTransform:concurrent:empty [[
+  public $ASTNode #name.getChildNoTransform(int i) {
+    return super.getChildNoTransformBase(i);
+  }
+]]
+