Index: libcfa/src/concurrency/locks.hfa
===================================================================
--- libcfa/src/concurrency/locks.hfa	(revision 2b910f95ca0d04d322653922044e80b152a19c5c)
+++ libcfa/src/concurrency/locks.hfa	(revision 27434e9e45b12c9edf6207f9298c791f73aeaab6)
@@ -174,4 +174,6 @@
 };
 
+static inline void ?{}(fast_lock & this) { this.owner = 0p; }
+
 static inline bool $try_lock(fast_lock & this, $thread * thrd) {
     $thread * exp = 0p;
Index: libcfa/src/concurrency/ready_queue.cfa
===================================================================
--- libcfa/src/concurrency/ready_queue.cfa	(revision 2b910f95ca0d04d322653922044e80b152a19c5c)
+++ libcfa/src/concurrency/ready_queue.cfa	(revision 27434e9e45b12c9edf6207f9298c791f73aeaab6)
@@ -20,7 +20,7 @@
 
 
-// #define USE_RELAXED_FIFO
+#define USE_RELAXED_FIFO
 // #define USE_WORK_STEALING
-#define USE_CPU_WORK_STEALING
+// #define USE_CPU_WORK_STEALING
 
 #include "bits/defs.hfa"
@@ -760,5 +760,5 @@
 		for(i; lanes.count) {
 			unsigned long long tsc1 = ts(lanes.data[i]);
-			unsigned long long tsc2 = rdtscl()
+			unsigned long long tsc2 = rdtscl();
 			lanes.tscs[i].tv = min(tsc1, tsc2);
 		}
Index: libcfa/src/containers/array.hfa
===================================================================
--- libcfa/src/containers/array.hfa	(revision 2b910f95ca0d04d322653922044e80b152a19c5c)
+++ libcfa/src/containers/array.hfa	(revision 27434e9e45b12c9edf6207f9298c791f73aeaab6)
@@ -137,9 +137,15 @@
 // Base
 forall( [Nq], Sq & | sized(Sq), Tbase & )
-static inline tag(arpk(Nq, Sq, Tbase, Tbase)) enq_( tag(Tbase), tag(Nq), tag(Sq), tag(Tbase) ) {}
+static inline tag(arpk(Nq, Sq, Tbase, Tbase)) enq_( tag(Tbase), tag(Nq), tag(Sq), tag(Tbase) ) {
+    tag(arpk(Nq, Sq, Tbase, Tbase)) ret;
+    return ret;
+}
 
 // Rec
 forall( [Nq], Sq & | sized(Sq), [N], S & | sized(S), recq &, recr &, Tbase & | { tag(recr) enq_( tag(Tbase), tag(Nq), tag(Sq), tag(recq) ); } )
-static inline tag(arpk(N, S, recr, Tbase)) enq_( tag(Tbase), tag(Nq), tag(Sq), tag(arpk(N, S, recq, Tbase)) ) {}
+static inline tag(arpk(N, S, recr, Tbase)) enq_( tag(Tbase), tag(Nq), tag(Sq), tag(arpk(N, S, recq, Tbase)) ) {
+    tag(arpk(N, S, recr, Tbase)) ret;
+    return ret;
+}
 
 // Wrapper
Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision 2b910f95ca0d04d322653922044e80b152a19c5c)
+++ src/Parser/DeclarationNode.cc	(revision 27434e9e45b12c9edf6207f9298c791f73aeaab6)
@@ -1076,8 +1076,8 @@
 	if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) {
 		// otype is internally converted to dtype + otype parameters
-		static const TypeDecl::Kind kindMap[] = { TypeDecl::Dtype, TypeDecl::DStype, TypeDecl::Dtype, TypeDecl::Ftype, TypeDecl::Ttype, TypeDecl::Dimension };
+		static const TypeDecl::Kind kindMap[] = { TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Ftype, TypeDecl::Ttype, TypeDecl::Dimension };
 		static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." );
 		assertf( variable.tyClass < sizeof(kindMap)/sizeof(kindMap[0]), "Variable's tyClass is out of bounds." );
-		TypeDecl * ret = new TypeDecl( *name, Type::StorageClasses(), nullptr, kindMap[ variable.tyClass ], variable.tyClass == TypeDecl::Otype, variable.initializer ? variable.initializer->buildType() : nullptr );
+		TypeDecl * ret = new TypeDecl( *name, Type::StorageClasses(), nullptr, kindMap[ variable.tyClass ], variable.tyClass == TypeDecl::Otype || variable.tyClass == TypeDecl::DStype, variable.initializer ? variable.initializer->buildType() : nullptr );
 		buildList( variable.assertions, ret->get_assertions() );
 		return ret;
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 2b910f95ca0d04d322653922044e80b152a19c5c)
+++ src/Parser/parser.yy	(revision 27434e9e45b12c9edf6207f9298c791f73aeaab6)
@@ -635,7 +635,10 @@
 postfix_expression:
 	primary_expression
-	| postfix_expression '[' assignment_expression ',' comma_expression ']'
-		// { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, new ExpressionNode( build_binary_val( OperKinds::Index, $3, $5 ) ) ) ); }
-		{ SemanticError( yylloc, "New array subscript is currently unimplemented." ); $$ = nullptr; }
+	| postfix_expression '[' assignment_expression ',' tuple_expression_list ']'
+			// Historic, transitional: Disallow commas in subscripts.
+			// Switching to this behaviour may help check if a C compatibilty case uses comma-exprs in subscripts.
+		// { SemanticError( yylloc, "New array subscript is currently unimplemented." ); $$ = nullptr; }
+			// Current: Commas in subscripts make tuples.
+		{ $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); }
 	| postfix_expression '[' assignment_expression ']'
 		// CFA, comma_expression disallowed in this context because it results in a common user error: subscripting a
Index: tests/.expect/forall.txt
===================================================================
--- tests/.expect/forall.txt	(revision 2b910f95ca0d04d322653922044e80b152a19c5c)
+++ tests/.expect/forall.txt	(revision 27434e9e45b12c9edf6207f9298c791f73aeaab6)
@@ -1,1 +1,1 @@
-forall.cfa:216:25: warning: Compiled
+forall.cfa:242:25: warning: Compiled
Index: tests/array-container/array-basic.cfa
===================================================================
--- tests/array-container/array-basic.cfa	(revision 2b910f95ca0d04d322653922044e80b152a19c5c)
+++ tests/array-container/array-basic.cfa	(revision 27434e9e45b12c9edf6207f9298c791f73aeaab6)
@@ -105,5 +105,5 @@
     printf("result Ws [][][][] lo = %f\n", result);
 
-    result = total1d_low( wxyz[[all, slice_ix, slice_ix, slice_ix]] );
+    result = total1d_low( wxyz[all, slice_ix, slice_ix, slice_ix] );
     printf("result Ws [,,,]    lo = %f\n", result);
 
@@ -111,5 +111,5 @@
     printf("result Ws [][][][] hi = %f\n", result);
 
-    result = total1d_hi( wxyz[[all, slice_ix, slice_ix, slice_ix]] );
+    result = total1d_hi( wxyz[all, slice_ix, slice_ix, slice_ix] );
     printf("result Ws [,,,]    hi = %f\n", result);
 
@@ -124,5 +124,5 @@
     printf("result Xs [][][][] lo = %f\n", result);
 
-    result = total1d_low( wxyz[[slice_ix, all, slice_ix, slice_ix]] );
+    result = total1d_low( wxyz[slice_ix, all, slice_ix, slice_ix] );
     printf("result Xs [,,,]    lo = %f\n", result);
 
@@ -130,5 +130,5 @@
     printf("result Xs [][][][] hi = %f\n", result);
 
-    result = total1d_hi( wxyz[[slice_ix, all, slice_ix, slice_ix]] );
+    result = total1d_hi( wxyz[slice_ix, all, slice_ix, slice_ix] );
     printf("result Xs [,,,]    hi = %f\n", result);
 
Index: tests/array-container/array-md-sbscr-cases.cfa
===================================================================
--- tests/array-container/array-md-sbscr-cases.cfa	(revision 2b910f95ca0d04d322653922044e80b152a19c5c)
+++ tests/array-container/array-md-sbscr-cases.cfa	(revision 27434e9e45b12c9edf6207f9298c791f73aeaab6)
@@ -53,38 +53,38 @@
     // order wxyz, natural split (4-0 or 0-4, no intermediate to declare)
 
-    assert(( wxyz[[iw, ix, iy, iz]] == valExpected ));
+    assert(( wxyz[iw, ix, iy, iz] == valExpected ));
 
     // order wxyz, unnatural split 1-3  (three ways declared)
 
     typeof( wxyz[iw] ) xyz1 = wxyz[iw];
-    assert(( xyz1[[ix, iy, iz]]  == valExpected ));
+    assert(( xyz1[ix, iy, iz]  == valExpected ));
 
     typeof( wxyz[iw] ) xyz2;
     &xyz2 = &wxyz[iw];
-    assert(( xyz2[[ix, iy, iz]] == valExpected ));
-
-    assert(( wxyz[iw][[ix, iy, iz]] == valExpected ));
+    assert(( xyz2[ix, iy, iz] == valExpected ));
+
+    assert(( wxyz[iw][ix, iy, iz] == valExpected ));
 
     // order wxyz, unnatural split 2-2  (three ways declared)
 
-    typeof( wxyz[[iw, ix]] ) yz1 = wxyz[[iw,ix]];
-    assert(( yz1[[iy, iz]]  == valExpected ));
-
-    typeof( wxyz[[iw, ix]] ) yz2;
-    &yz2 = &wxyz[[iw, ix]];
-    assert(( yz2[[iy, iz]]  == valExpected ));
-
-    assert(( wxyz[[iw, ix]][[iy, iz]] == valExpected ));
+    typeof( wxyz[iw, ix] ) yz1 = wxyz[iw,ix];
+    assert(( yz1[iy, iz]  == valExpected ));
+
+    typeof( wxyz[iw, ix] ) yz2;
+    &yz2 = &wxyz[iw, ix];
+    assert(( yz2[iy, iz]  == valExpected ));
+
+    assert(( wxyz[iw, ix][iy, iz] == valExpected ));
 
     // order wxyz, unnatural split 3-1  (three ways declared)
 
-    typeof( wxyz[[iw, ix, iy]] ) z1 = wxyz[[iw, ix, iy]];
+    typeof( wxyz[iw, ix, iy] ) z1 = wxyz[iw, ix, iy];
     assert(( z1[iz]  == valExpected ));
 
-    typeof( wxyz[[iw, ix, iy]] ) z2;
-    &z2 = &wxyz[[iw, ix, iy]];
+    typeof( wxyz[iw, ix, iy] ) z2;
+    &z2 = &wxyz[iw, ix, iy];
     assert(( z2[iz] == valExpected ));
 
-    assert(( wxyz[[iw, ix, iy]][iz] == valExpected ));
+    assert(( wxyz[iw, ix, iy][iz] == valExpected ));
 }
 
@@ -104,25 +104,25 @@
     // order wxyz (no intermediates to declare)
 
-    assert(( wxyz[[iw  , ix  , iy  , iz  ]]       == valExpected ));
-    assert(( wxyz[[iw-1, ix  , iy  , iz  ]]       != valExpected ));
+    assert(( wxyz[iw  , ix  , iy  , iz  ]       == valExpected ));
+    assert(( wxyz[iw-1, ix  , iy  , iz  ]       != valExpected ));
 
     // order xyzw: *xyz, w
 
-    assert(( wxyz[[all , ix  , iy  , iz  ]][iw  ] == valExpected ));
-    assert(( wxyz[[all , ix-1, iy  , iz  ]][iw  ] != valExpected ));
-    assert(( wxyz[[all , ix  , iy  , iz  ]][iw-1] != valExpected ));
+    assert(( wxyz[all , ix  , iy  , iz  ][iw  ] == valExpected ));
+    assert(( wxyz[all , ix-1, iy  , iz  ][iw  ] != valExpected ));
+    assert(( wxyz[all , ix  , iy  , iz  ][iw-1] != valExpected ));
 
     // order wyzx: w*yz, x
 
-    assert(( wxyz[[iw  , all , iy  , iz  ]][ix  ] == valExpected ));
-    assert(( wxyz[[iw  , all , iy-1, iz  ]][ix  ] != valExpected ));
-    assert(( wxyz[[iw  , all , iy  , iz  ]][ix-1] != valExpected ));
+    assert(( wxyz[iw  , all , iy  , iz  ][ix  ] == valExpected ));
+    assert(( wxyz[iw  , all , iy-1, iz  ][ix  ] != valExpected ));
+    assert(( wxyz[iw  , all , iy  , iz  ][ix-1] != valExpected ));
 
     // order wxzy: wx*z, y
   #if 0
     // not working on 32-bit
-    assert(( wxyz[[iw  , ix  , all , iz  ]][iy  ] == valExpected ));
-    assert(( wxyz[[iw  , ix  , all , iz-1]][iy  ] != valExpected ));
-    assert(( wxyz[[iw  , ix  , all , iz  ]][iy-1] != valExpected ));
+    assert(( wxyz[iw  , ix  , all , iz  ][iy  ] == valExpected ));
+    assert(( wxyz[iw  , ix  , all , iz-1][iy  ] != valExpected ));
+    assert(( wxyz[iw  , ix  , all , iz  ][iy-1] != valExpected ));
   #endif
 }
@@ -131,5 +131,5 @@
 // The comments specify a covering set of orders, each in its most natural split.
 // Covering means that each edge on the lattice of dimesnions-provided is used.
-// Natural split means the arity of every -[[-,...]] tuple equals the dimensionality of its "this" operand, then that the fewest "all" subscripts are given.
+// Natural split means the arity of every -[-,...] tuple equals the dimensionality of its "this" operand, then that the fewest "all" subscripts are given.
 // The commented-out test code shows cases that don't work.  We wish all the comment-coverd cases worked.
 forall( [Nw], [Nx], [Ny], [Nz] )
@@ -147,5 +147,5 @@
     // order wxyz (no intermediates to declare)
 
-    assert(( wxyz[[iw, ix, iy, iz]] == valExpected ));
+    assert(( wxyz[iw, ix, iy, iz] == valExpected ));
 
     {
@@ -153,16 +153,16 @@
         assert( wxyz[iw][all][iy][all] [ix][iz] == valExpected );
 
-        typeof( wxyz[[iw, all, iy, all]] ) xz1 = wxyz[[iw, all, iy, all]];
-        assert(( xz1[[ix, iz]]  == valExpected ));
-
-        typeof( wxyz[[iw, all, iy, all]] ) xz2;
-        &xz2 = &wxyz[[iw, all, iy, all]];
-        assert(( xz2[[ix, iz]]  == valExpected ));
-
-        assert(( wxyz[[iw  , all, iy  , all]][[ix  , iz  ]] == valExpected ));
-        assert(( wxyz[[iw-1, all, iy  , all]][[ix  , iz  ]] != valExpected ));
-        assert(( wxyz[[iw  , all, iy-1, all]][[ix  , iz  ]] != valExpected ));
-        assert(( wxyz[[iw  , all, iy  , all]][[ix-1, iz  ]] != valExpected ));
-        assert(( wxyz[[iw  , all, iy  , all]][[ix  , iz-1]] != valExpected ));
+        typeof( wxyz[iw, all, iy, all] ) xz1 = wxyz[iw, all, iy, all];
+        assert(( xz1[ix, iz]  == valExpected ));
+
+        typeof( wxyz[iw, all, iy, all] ) xz2;
+        &xz2 = &wxyz[iw, all, iy, all];
+        assert(( xz2[ix, iz]  == valExpected ));
+
+        assert(( wxyz[iw  , all, iy  , all][ix  , iz  ] == valExpected ));
+        assert(( wxyz[iw-1, all, iy  , all][ix  , iz  ] != valExpected ));
+        assert(( wxyz[iw  , all, iy-1, all][ix  , iz  ] != valExpected ));
+        assert(( wxyz[iw  , all, iy  , all][ix-1, iz  ] != valExpected ));
+        assert(( wxyz[iw  , all, iy  , all][ix  , iz-1] != valExpected ));
     }
     {
@@ -170,16 +170,16 @@
         assert( wxyz[iw][all][all][iz] [ix][iy] == valExpected );
 
-        // typeof( wxyz[[iw, all, all, iz]] ) xy1 = wxyz[[iw, all, all, iz]];
-        // assert(( xy1[[ix, iy]]  == valExpected ));
-
-        // typeof(  wxyz[[iw, all, all, iz]] ) xy2;
-        // &xy2 = &wxyz[[iw, all, all, iz]];
-        // assert(( xy2[[ix, iy]]  == valExpected ));
-
-        // assert(( wxyz[[iw  , all, all, iz  ]][[ix  , iy  ]] == valExpected ));
-        // assert(( wxyz[[iw-1, all, all, iz  ]][[ix  , iy  ]] != valExpected ));
-        // assert(( wxyz[[iw  , all, all, iz-1]][[ix  , iy  ]] != valExpected ));
-        // assert(( wxyz[[iw  , all, all, iz  ]][[ix-1, iy  ]] != valExpected ));
-        // assert(( wxyz[[iw  , all, all, iz  ]][[ix  , iy-1]] != valExpected ));
+        // typeof( wxyz[iw, all, all, iz] ) xy1 = wxyz[iw, all, all, iz];
+        // assert(( xy1[ix, iy]  == valExpected ));
+
+        // typeof(  wxyz[iw, all, all, iz] ) xy2;
+        // &xy2 = &wxyz[iw, all, all, iz];
+        // assert(( xy2[ix, iy]  == valExpected ));
+
+        // assert(( wxyz[iw  , all, all, iz  ][ix  , iy  ] == valExpected ));
+        // assert(( wxyz[iw-1, all, all, iz  ][ix  , iy  ] != valExpected ));
+        // assert(( wxyz[iw  , all, all, iz-1][ix  , iy  ] != valExpected ));
+        // assert(( wxyz[iw  , all, all, iz  ][ix-1, iy  ] != valExpected ));
+        // assert(( wxyz[iw  , all, all, iz  ][ix  , iy-1] != valExpected ));
     }
     {
@@ -187,8 +187,8 @@
         assert( wxyz[all][ix][iy][all] [iw][iz] == valExpected );
 
-        typeof( wxyz[[all, ix, iy, all]] ) wz1 = wxyz[[all, ix, iy, all]];
-        assert(( wz1[[iw, iz]]  == valExpected ));
-
-        assert(( wxyz[[all  , ix, iy  , all]][[iw  , iz  ]] == valExpected ));
+        typeof( wxyz[all, ix, iy, all] ) wz1 = wxyz[all, ix, iy, all];
+        assert(( wz1[iw, iz]  == valExpected ));
+
+        assert(( wxyz[all  , ix, iy  , all][iw  , iz  ] == valExpected ));
     }
     {
@@ -196,5 +196,5 @@
         assert( wxyz[all][ix][all][iz] [iw][iy] == valExpected );
 
-        // assert(( wxyz[[all , ix  , all , iz  ]][[iw  , iy  ]] == valExpected ));
+        // assert(( wxyz[all , ix  , all , iz  ][iw  , iy  ] == valExpected ));
     }
     {
@@ -202,5 +202,5 @@
         assert( wxyz[all][all][iy][iz] [iw][ix] == valExpected );
 
-        // assert(( wxyz[[all , all , iy  , iz  ]][[iw  , ix  ]] == valExpected ));
+        // assert(( wxyz[all , all , iy  , iz  ][iw  , ix  ] == valExpected ));
     }
     {
@@ -208,9 +208,9 @@
         assert( wxyz[all][ix][all][all] [iw][all][iz] [iy] == valExpected );
 
-        typeof( wxyz[all][ix][all][all] ) wyz_workaround = wxyz[[all , ix , all  , all  ]];
-        typeof( wyz_workaround[iw][all][iz] ) y_workaround = wyz_workaround[[iw , all , iz  ]];
+        typeof( wxyz[all][ix][all][all] ) wyz_workaround = wxyz[all , ix , all  , all  ];
+        typeof( wyz_workaround[iw][all][iz] ) y_workaround = wyz_workaround[iw , all , iz  ];
         assert( y_workaround[iy] == valExpected );
 
-        // assert(( wxyz[[all , ix , all  , all  ]][[iw  , all , iz  ]][iy  ] == valExpected ));
+        // assert(( wxyz[all , ix , all  , all  ][iw  , all , iz  ][iy  ] == valExpected ));
     }
     {
@@ -239,33 +239,33 @@
     valExpected = getMagicNumber(2, 3, 4, 5);
     assert(( wxyz [2] [3] [4] [5]  == valExpected ));
-    assert(( wxyz[[2,  3]][4] [5]  == valExpected ));
-    assert(( wxyz [2][[3,  4]][5]  == valExpected ));
-    assert(( wxyz [2] [3][[4,  5]] == valExpected ));
-    assert(( wxyz[[2,  3,  4]][5]  == valExpected ));
-    assert(( wxyz [2][[3,  4,  5]] == valExpected ));
-    assert(( wxyz[[2,  3,  4,  5]] == valExpected ));
+    assert(( wxyz[2,  3][4] [5]  == valExpected ));
+    assert(( wxyz [2][3,  4][5]  == valExpected ));
+    assert(( wxyz [2] [3][4,  5] == valExpected ));
+    assert(( wxyz[2,  3,  4][5]  == valExpected ));
+    assert(( wxyz [2][3,  4,  5] == valExpected ));
+    assert(( wxyz[2,  3,  4,  5] == valExpected ));
 
     for ( i; Nw ) {
-        assert(( wxyz[[ i, 3, 4, 5 ]] == getMagicNumber(i, 3, 4, 5) ));
+        assert(( wxyz[ i, 3, 4, 5 ] == getMagicNumber(i, 3, 4, 5) ));
     }
 
     for ( i; Nx ) {
-        assert(( wxyz[[ 2, i, 4, 5 ]] == getMagicNumber(2, i, 4, 5) ));
+        assert(( wxyz[ 2, i, 4, 5 ] == getMagicNumber(2, i, 4, 5) ));
     }
 
     for ( i; Ny ) {
-        assert(( wxyz[[ 2, 3, i, 5 ]] == getMagicNumber(2, 3, i, 5) ));
+        assert(( wxyz[ 2, 3, i, 5 ] == getMagicNumber(2, 3, i, 5) ));
     }
 
     for ( i; Nz ) {
-        assert(( wxyz[[ 2, 3, 4, i ]] == getMagicNumber(2, 3, 4, i) ));
+        assert(( wxyz[ 2, 3, 4, i ] == getMagicNumber(2, 3, 4, i) ));
     }
 
     for ( i; Nw ) {
-        assert(( wxyz[[ i, all, 4, 5 ]][3] == getMagicNumber(i, 3, 4, 5) ));
+        assert(( wxyz[ i, all, 4, 5 ][3] == getMagicNumber(i, 3, 4, 5) ));
     }
 
     for ( i; Nw ) {
-        assert(( wxyz[[ all, 3, 4, 5 ]][i] == getMagicNumber(i, 3, 4, 5) ));
+        assert(( wxyz[ all, 3, 4, 5 ][i] == getMagicNumber(i, 3, 4, 5) ));
     }
 }
Index: tests/forall.cfa
===================================================================
--- tests/forall.cfa	(revision 2b910f95ca0d04d322653922044e80b152a19c5c)
+++ tests/forall.cfa	(revision 27434e9e45b12c9edf6207f9298c791f73aeaab6)
@@ -199,4 +199,30 @@
 }
 
+forall( T ) void check_otype() {
+	T & tr = *0p;
+	T * tp = 0p;
+
+	&tr += 1;
+	tp += 1;
+	T & tx = tp[1];
+
+	T t;
+	T t2 = t;
+}
+
+forall( T * ) void check_dstype() {
+	T & tr = *0p;
+	T * tp = 0p;
+
+	&tr += 1;
+	tp += 1;
+	T & tx = tp[1];
+}
+
+forall( T & ) void check_dtype() {
+	T & tr = *0p;
+	T * tp = 0p;
+}
+
 //otype T1 | { void xxx( T1 ); };
 
