Index: libcfa/src/parseargs.cfa
===================================================================
--- libcfa/src/parseargs.cfa	(revision 985ff5f41da6231bbc7c38f716ebe95925c43cfa)
+++ libcfa/src/parseargs.cfa	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -73,99 +73,98 @@
 //-----------------------------------------------------------------------------
 // Parsing args
-forall([opt_count]) {
-	void parse_args( const array( cfa_option, opt_count ) & options, const char * usage, char ** & left ) {
-		if ( 0p != &cfa_args_argc ) {
-			parse_args( cfa_args_argc, cfa_args_argv, options, usage, left );
-		} else {
-			char * temp[1] = { 0p };
-			parse_args(0, temp, options, usage, left );
-		}
-	}
-
-	void parse_args(
-		int argc,
-		char * argv[],
-		const array( cfa_option, opt_count ) & options,
-		const char * usage,
-		char ** & left
-	) {
-		check_args( options );
-
-		int maxv = 'h';
-		char optstring[(opt_count * 3) + 2] = { '\0' };
-		{
-			int idx = 0;
-			for ( i; opt_count ) {
-				if ( options[i].short_name ) {
-					maxv = max( options[i].short_name, maxv );
-					optstring[idx] = options[i].short_name;
-					idx++;
-					if ( (intptr_t)options[i].parse != (intptr_t)parse_settrue
-						 && ((intptr_t)options[i].parse) != ((intptr_t)parse_setfalse) ) {
-						optstring[idx] = ':';
-						idx++;
-					}
-				}
-			}
-			optstring[idx+0] = 'h';
-			optstring[idx+1] = '\0';
-		}
-
-		struct option optarr[opt_count + 2];
-		{
-			int idx = 0;
-			for ( i; opt_count ) {
-				if ( options[i].long_name ) {
-					// we don't have the mutable keyword here, which is really what we would want
-					int & val_ref = (int &)(const int &)options[i].val;
-					val_ref = (options[i].short_name != '\0') ? ((int)options[i].short_name) : ++maxv;
-
-					optarr[idx].name = options[i].long_name;
-					optarr[idx].flag = 0p;
-					optarr[idx].val  = options[i].val;
-					if ( ((intptr_t)options[i].parse) == ((intptr_t)parse_settrue)
-						 || ((intptr_t)options[i].parse) == ((intptr_t)parse_setfalse) ) {
-						optarr[idx].has_arg = no_argument;
-					} else {
-						optarr[idx].has_arg = required_argument;
-					}
+forall([opt_count])
+void parse_args( const array( cfa_option, opt_count ) & options, const char * usage, char ** & left ) {
+	if ( 0p != &cfa_args_argc ) {
+		parse_args( cfa_args_argc, cfa_args_argv, options, usage, left );
+	} else {
+		char * temp[1] = { 0p };
+		parse_args(0, temp, options, usage, left );
+	}
+}
+
+forall([opt_count])
+void parse_args(
+	int argc,
+	char * argv[],
+	const array( cfa_option, opt_count ) & options,
+	const char * usage,
+	char ** & left
+) {
+	check_args( options );
+
+	int maxv = 'h';
+	char optstring[(opt_count * 3) + 2] = { '\0' };
+	{
+		int idx = 0;
+		for ( i; opt_count ) {
+			if ( options[i].short_name ) {
+				maxv = max( options[i].short_name, maxv );
+				optstring[idx] = options[i].short_name;
+				idx++;
+				if ( (intptr_t)options[i].parse != (intptr_t)parse_settrue
+					 && ((intptr_t)options[i].parse) != ((intptr_t)parse_setfalse) ) {
+					optstring[idx] = ':';
 					idx++;
 				}
 			}
-			optarr[idx+0].[name, has_arg, flag, val] = ["help", no_argument, 0, 'h'];
-			optarr[idx+1].[name, has_arg, flag, val] = [0, no_argument, 0, 0];
-		}
-
-		FILE * out = stderr;
-		NEXT_ARG:
-		for () {
-			int idx = 0;
-			int opt = getopt_long( argc, argv, optstring, optarr, &idx );
-			switch( opt ) {
-				case -1:
-					if ( &left != 0p ) left = argv + optind;
-					return;
-				case 'h':
-					out = stdout;
-				case '?':
+		}
+		optstring[idx+0] = 'h';
+		optstring[idx+1] = '\0';
+	}
+
+	struct option optarr[opt_count + 2];
+	{
+		int idx = 0;
+		for ( i; opt_count ) {
+			if ( options[i].long_name ) {
+				// we don't have the mutable keyword here, which is really what we would want
+				int & val_ref = (int &)(const int &)options[i].val;
+				val_ref = (options[i].short_name != '\0') ? ((int)options[i].short_name) : ++maxv;
+
+				optarr[idx].name = options[i].long_name;
+				optarr[idx].flag = 0p;
+				optarr[idx].val  = options[i].val;
+				if ( ((intptr_t)options[i].parse) == ((intptr_t)parse_settrue)
+					 || ((intptr_t)options[i].parse) == ((intptr_t)parse_setfalse) ) {
+					optarr[idx].has_arg = no_argument;
+				} else {
+					optarr[idx].has_arg = required_argument;
+				}
+				idx++;
+			}
+		}
+		optarr[idx+0].[name, has_arg, flag, val] = ["help", no_argument, 0, 'h'];
+		optarr[idx+1].[name, has_arg, flag, val] = [0, no_argument, 0, 0];
+	}
+
+	FILE * out = stderr;
+	NEXT_ARG:
+	for () {
+		int idx = 0;
+		int opt = getopt_long( argc, argv, optstring, optarr, &idx );
+		switch( opt ) {
+		case -1:
+			if ( &left != 0p ) left = argv + optind;
+			return;
+		case 'h':
+			out = stdout;
+		case '?':
+			usage( argv[0], options, usage, out );
+		default:
+			for ( i; opt_count ) {
+				if ( opt == options[i].val ) {
+					const char * arg = optarg ? optarg : "";
+					if ( arg[0] == '=' ) { arg++; }
+					// work around for some weird bug
+					void * variable = options[i].variable;
+					bool (*parse_func)(const char *, void * ) = options[i].parse;
+					bool success = parse_func( arg, variable );
+					if ( success ) continue NEXT_ARG;
+
+					fprintf( out, "Argument '%s' for option %c could not be parsed\n\n", arg, (char)opt );
 					usage( argv[0], options, usage, out );
-				default:
-					for ( i; opt_count ) {
-						if ( opt == options[i].val ) {
-							const char * arg = optarg ? optarg : "";
-							if ( arg[0] == '=' ) { arg++; }
-							// work around for some weird bug
-							void * variable = options[i].variable;
-							bool (*parse_func)(const char *, void * ) = options[i].parse;
-							bool success = parse_func( arg, variable );
-							if ( success ) continue NEXT_ARG;
-
-							fprintf( out, "Argument '%s' for option %c could not be parsed\n\n", arg, (char)opt );
-							usage( argv[0], options, usage, out );
-						}
-					}
-					abort( "Internal parse arg error\n" );
+				}
 			}
-
+			abort( "Internal parse arg error\n" );
 		}
 	}
@@ -240,12 +239,12 @@
 }
 
-forall( [N] ) {
-	void print_args_usage( const array(cfa_option, N ) & options, const char * usage, bool error ) {
-		usage( cfa_args_argv[0], options, usage, error ? stderr : stdout );
-	}
-
-	void print_args_usage( int argc, char * argv[], const array( cfa_option, N ) & options, const char * usage, bool error ) {
-		usage( argv[0], options, usage, error ? stderr : stdout );
-	}
+forall([N])
+void print_args_usage( const array(cfa_option, N ) & options, const char * usage, bool error ) {
+	usage( cfa_args_argv[0], options, usage, error ? stderr : stdout );
+}
+
+forall([N])
+void print_args_usage( int argc, char * argv[], const array( cfa_option, N ) & options, const char * usage, bool error ) {
+	usage( argv[0], options, usage, error ? stderr : stdout );
 }
 
Index: src/AST/Decl.cpp
===================================================================
--- src/AST/Decl.cpp	(revision 985ff5f41da6231bbc7c38f716ebe95925c43cfa)
+++ src/AST/Decl.cpp	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -169,8 +169,4 @@
 }
 
-bool EnumDecl::isTyped() const { return base; }
-
-bool EnumDecl::isOpaque() const { return isCfa && !isTyped(); }
-
 }
 
Index: src/AST/Decl.hpp
===================================================================
--- src/AST/Decl.hpp	(revision 985ff5f41da6231bbc7c38f716ebe95925c43cfa)
+++ src/AST/Decl.hpp	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -306,5 +306,5 @@
 enum class EnumAttribute{ Value, Posn, Label };
 
-/// enum declaration `enum Foo { ... };`
+/// enum declaration `enum Foo { ... };` or `enum(...) Foo { ... };`
 class EnumDecl final : public AggregateDecl {
 public:
@@ -317,4 +317,8 @@
 	std::vector< ast::ptr<ast::EnumInstType>> inlinedDecl; // child enums
 
+	bool is_c_enum     () const { return !isCfa; }
+	bool is_opaque_enum() const { return isCfa && nullptr == base; }
+	bool is_typed_enum () const { return isCfa && nullptr != base; }
+
 	EnumDecl( const CodeLocation& loc, const std::string& name, bool isCfa = false,
 		std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall,
@@ -331,6 +335,4 @@
 	const char * typeString() const override { return aggrString( Enum ); }
 
-	bool isTyped() const;
-	bool isOpaque() const;
 private:
 	EnumDecl * clone() const override { return new EnumDecl{ *this }; }
Index: src/AST/Util.cpp
===================================================================
--- src/AST/Util.cpp	(revision 985ff5f41da6231bbc7c38f716ebe95925c43cfa)
+++ src/AST/Util.cpp	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -85,4 +85,11 @@
 	// Check that `type->returns` corresponds with `decl->returns`.
 	assert( type->returns.size() == decl->returns.size() );
+}
+
+/// Check that an enumeration has not been made with an inconsistent spec.
+void isEnumerationConsistent( const EnumDecl * node ) {
+	if ( node->is_c_enum() ) {
+		assert( nullptr == node->base );
+	}
 }
 
@@ -135,4 +142,9 @@
 		previsit( (const ParseNode *)node );
 		functionDeclMatchesType( node );
+	}
+
+	void previsit( const EnumDecl * node ) {
+		previsit( (const ParseNode *)node );
+		isEnumerationConsistent( node );
 	}
 
Index: src/CodeGen/CodeGenerator.cpp
===================================================================
--- src/CodeGen/CodeGenerator.cpp	(revision 985ff5f41da6231bbc7c38f716ebe95925c43cfa)
+++ src/CodeGen/CodeGenerator.cpp	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -130,4 +130,5 @@
 	// TODO: Which means the ast::Pass is just providing a default no visit?
 	visit_children = false;
+	changeState_ArgToIntrinsic(false);
 }
 
@@ -466,4 +467,5 @@
 		if ( var->var->linkage == ast::Linkage::Intrinsic &&
 				( opInfo = operatorLookup( var->var->name ) ) ) {
+			changeState_ArgToIntrinsic(true);
 			auto arg = expr->args.begin();
 			switch ( opInfo->type ) {
@@ -558,4 +560,5 @@
 	if ( auto name = expr->func.as<ast::NameExpr>() ) {
 		if ( const OperatorInfo * opInfo = operatorLookup( name->name ) ) {
+			changeState_ArgToIntrinsic(true);
 			auto arg = expr->args.begin();
 			switch ( opInfo->type ) {
@@ -743,5 +746,12 @@
 	extension( expr );
 	const OperatorInfo * opInfo;
-	if ( expr->var->linkage == ast::Linkage::Intrinsic
+	if ( visitingArgToIntrinsic
+			&& options.genC
+			&& dynamic_cast<ast::ZeroType const *>( expr->var->get_type() ) ) {
+		// int * p; p = 0;               ==>  ?=?( p, (zero_t){} );  ==>  p = 0;
+		// void f( zero_t z ) { g(z); }  ==>  g(z);                  ==>  g(z);
+		// (we are at the last '==>')
+		output << "0";
+	} else if ( expr->var->linkage == ast::Linkage::Intrinsic
 			&& ( opInfo = operatorLookup( expr->var->name ) )
 			&& opInfo->type == OT_CONSTANT ) {
Index: src/CodeGen/CodeGenerator.hpp
===================================================================
--- src/CodeGen/CodeGenerator.hpp	(revision 985ff5f41da6231bbc7c38f716ebe95925c43cfa)
+++ src/CodeGen/CodeGenerator.hpp	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -181,4 +181,11 @@
 	void handleTypedef( ast::NamedTypeDecl const * type );
 	std::string mangleName( ast::DeclWithType const * decl );
+
+	bool nextVisitedNodeIsArgToIntrinsic = false;
+	bool visitingArgToIntrinsic = false;
+	void changeState_ArgToIntrinsic( bool newValue ) {
+		GuardValue( visitingArgToIntrinsic ) = nextVisitedNodeIsArgToIntrinsic;
+		GuardValue( nextVisitedNodeIsArgToIntrinsic ) = newValue;
+	}
 };
 
Index: src/CodeGen/GenType.cpp
===================================================================
--- src/CodeGen/GenType.cpp	(revision 985ff5f41da6231bbc7c38f716ebe95925c43cfa)
+++ src/CodeGen/GenType.cpp	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -268,5 +268,5 @@
 void GenType::postvisit( ast::ZeroType const * type ) {
 	// Ideally these wouldn't hit codegen at all, but should be safe to make them ints.
-	result = (options.pretty ? "zero_t " : "long int ") + result;
+	result = ( options.genC ? "long int /*zero_t*/ " : "zero_t " ) + result;
 	handleQualifiers( type );
 }
@@ -274,5 +274,5 @@
 void GenType::postvisit( ast::OneType const * type ) {
 	// Ideally these wouldn't hit codegen at all, but should be safe to make them ints.
-	result = (options.pretty ? "one_t " : "long int ") + result;
+	result = ( options.genC ? "long int /*one_t*/ " : "one_t " ) + result;
 	handleQualifiers( type );
 }
Index: src/CodeGen/Generate.cpp
===================================================================
--- src/CodeGen/Generate.cpp	(revision 985ff5f41da6231bbc7c38f716ebe95925c43cfa)
+++ src/CodeGen/Generate.cpp	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -46,4 +46,15 @@
 		}
 	};
+
+	struct ZeroOneObjectHider final {
+		ast::ObjectDecl const * postvisit( ast::ObjectDecl const * decl ) {
+			if ( decl->type.as<ast::ZeroType>() || decl->type.as<ast::OneType>() ) {
+				ast::ObjectDecl * mutDecl = ast::mutate( decl );
+				mutDecl->attributes.push_back( new ast::Attribute( "unused" ) );
+				return mutDecl;
+			}
+			return decl;
+		}
+	};
 } // namespace
 
@@ -52,4 +63,5 @@
 	erase_if( translationUnit.decls, shouldClean );
 	ast::Pass<TreeCleaner>::run( translationUnit );
+	ast::Pass<ZeroOneObjectHider>::run( translationUnit );
 
 	ast::Pass<CodeGenerator> cgv( os,
Index: src/Concurrency/Actors.cpp
===================================================================
--- src/Concurrency/Actors.cpp	(revision 985ff5f41da6231bbc7c38f716ebe95925c43cfa)
+++ src/Concurrency/Actors.cpp	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -29,9 +29,9 @@
 struct CollectactorStructDecls : public ast::WithGuards {
 	unordered_set<const StructDecl *> & actorStructDecls;
-	unordered_set<const StructDecl *>  & messageStructDecls;
-	const StructDecl ** requestDecl;
-	const EnumDecl ** allocationDecl;
-	const StructDecl ** actorDecl;
-	const StructDecl ** msgDecl;
+	unordered_set<const StructDecl *> & messageStructDecls;
+	const StructDecl *& requestDecl;
+	const EnumDecl *& allocationDecl;
+	const StructDecl *& actorDecl;
+	const StructDecl *& msgDecl;
 	StructDecl * parentDecl;
 	bool insideStruct = false;
@@ -40,5 +40,5 @@
 	// finds and sets a ptr to the allocation enum, which is needed in the next pass
 	void previsit( const EnumDecl * decl ) {
-		if( decl->name == "allocation" ) *allocationDecl = decl;
+		if( decl->name == "allocation" ) allocationDecl = decl;
 	}
 
@@ -48,10 +48,11 @@
 		if ( decl->name == "actor" ) {
 			actorStructDecls.insert( decl ); // skip inserting fwd decl
-			*actorDecl = decl;
+			actorDecl = decl;
 		} else if( decl->name == "message" ) {
 			messageStructDecls.insert( decl ); // skip inserting fwd decl
-			*msgDecl = decl;
-		} else if( decl->name == "request" ) *requestDecl = decl;
-		else {
+			msgDecl = decl;
+		} else if( decl->name == "request" ) {
+			requestDecl = decl;
+		} else {
 			GuardValue(insideStruct);
 			insideStruct = true;
@@ -73,5 +74,5 @@
 	// this collects the derived actor and message struct decl ptrs
 	void postvisit( const StructInstType * node ) {
-		if ( ! *actorDecl || ! *msgDecl ) return;
+		if ( !actorDecl || !msgDecl ) return;
 		if ( insideStruct && !namedDecl ) {
 			auto actorIter = actorStructDecls.find( node->aggr() );
@@ -89,5 +90,5 @@
   public:
 	CollectactorStructDecls( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls,
-		const StructDecl ** requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl ** msgDecl )
+		const StructDecl *& requestDecl, const EnumDecl *& allocationDecl, const StructDecl *& actorDecl, const StructDecl *& msgDecl )
 		: actorStructDecls( actorStructDecls ), messageStructDecls( messageStructDecls ), requestDecl( requestDecl ),
 		allocationDecl( allocationDecl ), actorDecl(actorDecl), msgDecl(msgDecl) {}
@@ -196,9 +197,9 @@
 struct GenFuncsCreateTables : public ast::WithDeclsToAdd {
 	unordered_set<const StructDecl *> & actorStructDecls;
-	unordered_set<const StructDecl *>  & messageStructDecls;
-	const StructDecl ** requestDecl;
-	const EnumDecl ** allocationDecl;
-	const StructDecl ** actorDecl;
-	const StructDecl ** msgDecl;
+	unordered_set<const StructDecl *> & messageStructDecls;
+	const StructDecl *& requestDecl;
+	const EnumDecl *& allocationDecl;
+	const StructDecl *& actorDecl;
+	const StructDecl *& msgDecl;
 	FwdDeclTable & forwardDecls;
 
@@ -279,10 +280,10 @@
 						decl->location,
 						"base_actor",
-						new PointerType( new PointerType( new StructInstType( *actorDecl ) ) )
+						new PointerType( new PointerType( new StructInstType( actorDecl ) ) )
 					),
 					new ObjectDecl(
 						decl->location,
 						"base_msg",
-						new PointerType( new PointerType( new StructInstType( *msgDecl ) ) )
+						new PointerType( new PointerType( new StructInstType( msgDecl ) ) )
 					)
 				},                      // params
@@ -291,5 +292,5 @@
 						decl->location,
 						"__CFA_receive_wrap_ret",
-						new EnumInstType( *allocationDecl )
+						new EnumInstType( allocationDecl )
 					)
 				},
@@ -323,5 +324,5 @@
 					decl->location,
 					"new_req",
-					new StructInstType( *requestDecl )
+					new StructInstType( requestDecl )
 				)
 			));
@@ -331,7 +332,7 @@
 			derivedReceive->params.push_back( ast::deepCopy( derivedActorRef ) );
 			derivedReceive->params.push_back( ast::deepCopy( derivedMsgRef ) );
-			derivedReceive->params.push_back( new PointerType( new PointerType( new StructInstType( *actorDecl ) ) ) );
-			derivedReceive->params.push_back( new PointerType( new PointerType( new StructInstType( *msgDecl ) ) ) );
-			derivedReceive->returns.push_back( new EnumInstType( *allocationDecl ) );
+			derivedReceive->params.push_back( new PointerType( new PointerType( new StructInstType( actorDecl ) ) ) );
+			derivedReceive->params.push_back( new PointerType( new PointerType( new StructInstType( msgDecl ) ) ) );
+			derivedReceive->returns.push_back( new EnumInstType( allocationDecl ) );
 
 			// Generates: allocation (*my_work_fn)( derived_actor &, derived_msg &, actor **, message ** ) = receive;
@@ -348,9 +349,9 @@
 			// Function type is: allocation (*)( actor &, message & )
 			FunctionType * genericReceive = new FunctionType();
-			genericReceive->params.push_back( new ReferenceType( new StructInstType( *actorDecl ) ) );
-			genericReceive->params.push_back( new ReferenceType( new StructInstType( *msgDecl ) ) );
-			genericReceive->params.push_back( new PointerType( new PointerType( new StructInstType( *actorDecl ) ) ) );
-			genericReceive->params.push_back( new PointerType( new PointerType( new StructInstType( *msgDecl ) ) ) );
-			genericReceive->returns.push_back( new EnumInstType( *allocationDecl ) );
+			genericReceive->params.push_back( new ReferenceType( new StructInstType( actorDecl ) ) );
+			genericReceive->params.push_back( new ReferenceType( new StructInstType( msgDecl ) ) );
+			genericReceive->params.push_back( new PointerType( new PointerType( new StructInstType( actorDecl ) ) ) );
+			genericReceive->params.push_back( new PointerType( new PointerType( new StructInstType( msgDecl ) ) ) );
+			genericReceive->returns.push_back( new EnumInstType( allocationDecl ) );
 
 			// Generates: allocation (*fn)( actor &, message & ) = (allocation (*)( actor &, message & ))my_work_fn;
@@ -378,6 +379,6 @@
 					{
 						new NameExpr( decl->location, "new_req" ),
-						new CastExpr( decl->location, new AddressExpr( new NameExpr( decl->location, "receiver" ) ), new PointerType( new StructInstType( *actorDecl ) ), ExplicitCast ),
-						new CastExpr( decl->location, new AddressExpr( new NameExpr( decl->location, "msg" ) ), new PointerType( new StructInstType( *msgDecl ) ), ExplicitCast ),
+						new CastExpr( decl->location, new AddressExpr( new NameExpr( decl->location, "receiver" ) ), new PointerType( new StructInstType( actorDecl ) ), ExplicitCast ),
+						new CastExpr( decl->location, new AddressExpr( new NameExpr( decl->location, "msg" ) ), new PointerType( new StructInstType( msgDecl ) ), ExplicitCast ),
 						new NameExpr( decl->location, "fn" )
 					}
@@ -443,5 +444,5 @@
   public:
 	GenFuncsCreateTables( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls,
-		const StructDecl ** requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl ** msgDecl,
+		const StructDecl *& requestDecl, const EnumDecl *& allocationDecl, const StructDecl *& actorDecl, const StructDecl *& msgDecl,
 		FwdDeclTable & forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls),
 		requestDecl(requestDecl), allocationDecl(allocationDecl), actorDecl(actorDecl), msgDecl(msgDecl), forwardDecls(forwardDecls) {}
@@ -453,5 +454,5 @@
 struct FwdDeclOperator : public ast::WithDeclsToAdd {
 	unordered_set<const StructDecl *> & actorStructDecls;
-	unordered_set<const StructDecl *>  & messageStructDecls;
+	unordered_set<const StructDecl *> & messageStructDecls;
 	FwdDeclTable & forwardDecls;
 
@@ -495,28 +496,22 @@
 	// for storing through the passes
 	// these are populated with various important struct decls
-	const StructDecl * requestDeclPtr = nullptr;
-	const EnumDecl * allocationDeclPtr = nullptr;
-	const StructDecl * actorDeclPtr = nullptr;
-	const StructDecl * msgDeclPtr = nullptr;
-
-	// double pointer to modify local ptrs above
-	const StructDecl ** requestDecl = &requestDeclPtr;
-	const EnumDecl ** allocationDecl = &allocationDeclPtr;
-	const StructDecl ** actorDecl = &actorDeclPtr;
-	const StructDecl ** msgDecl = &msgDeclPtr;
+	const StructDecl * requestDecl = nullptr;
+	const EnumDecl * allocationDecl = nullptr;
+	const StructDecl * actorDecl = nullptr;
+	const StructDecl * msgDecl = nullptr;
 
 	// first pass collects ptrs to allocation enum, request type, and generic receive fn typedef
 	// also populates maps of all derived actors and messages
-	Pass<CollectactorStructDecls>::run( translationUnit, actorStructDecls, messageStructDecls, requestDecl,
-		allocationDecl, actorDecl, msgDecl );
+	Pass<CollectactorStructDecls>::run( translationUnit, actorStructDecls, messageStructDecls,
+		requestDecl, allocationDecl, actorDecl, msgDecl );
 
 	// check that we have found all the decls we need from <actor.hfa>, if not no need to run the rest of this pass
-	if ( !allocationDeclPtr || !requestDeclPtr || !actorDeclPtr || !msgDeclPtr )
+	if ( !allocationDecl || !requestDecl || !actorDecl || !msgDecl )
 		return;
 
 	// second pass locates all receive() routines that overload the generic receive fn
 	// it then generates the appropriate operator '|' send routines for the receive routines
-	Pass<GenFuncsCreateTables>::run( translationUnit, actorStructDecls, messageStructDecls, requestDecl,
-		allocationDecl, actorDecl, msgDecl, forwardDecls );
+	Pass<GenFuncsCreateTables>::run( translationUnit, actorStructDecls, messageStructDecls,
+		requestDecl, allocationDecl, actorDecl, msgDecl, forwardDecls );
 
 	// The third pass forward declares operator '|' send routines
Index: src/InitTweak/GenInit.cpp
===================================================================
--- src/InitTweak/GenInit.cpp	(revision 985ff5f41da6231bbc7c38f716ebe95925c43cfa)
+++ src/InitTweak/GenInit.cpp	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -164,20 +164,16 @@
 				ast::ObjectDecl * arrayDimension = nullptr;
 
-				const ast::TypeExpr * ty = dynamic_cast< const ast::TypeExpr * >( arrayType->dimension.get() );
-				if ( ty ) {
+				if ( auto ty = dynamic_cast< const ast::TypeExpr * >( arrayType->dimension.get() ) ) {
 					auto inst = ty->type.as<ast::EnumInstType>();
-					if ( inst ) {
-						if ( inst->base->isCfa ) {
-							arrayDimension = new ast::ObjectDecl(
+					if ( inst && !inst->base->is_c_enum() ) {
+						arrayDimension = new ast::ObjectDecl(
+							arrayType->dimension->location,
+							dimensionName.newName(),
+							new ast::BasicType( ast::BasicKind::UnsignedChar ),
+							new ast::SingleInit(
 								arrayType->dimension->location,
-								dimensionName.newName(),
-								new ast::BasicType( ast::BasicKind::UnsignedChar ),
-								new ast::SingleInit(
-									arrayType->dimension->location,
-									ast::ConstantExpr::from_int( arrayType->dimension->location, inst->base->members.size() )
-								)
-							);
-							// return arrayType;
-						}
+								ast::ConstantExpr::from_int( arrayType->dimension->location, inst->base->members.size() )
+							)
+						);
 					}
 				}
Index: src/Parser/TypeData.cpp
===================================================================
--- src/Parser/TypeData.cpp	(revision 985ff5f41da6231bbc7c38f716ebe95925c43cfa)
+++ src/Parser/TypeData.cpp	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -1482,9 +1482,9 @@
 		object->isHidden = ast::EnumDecl::EnumHiding::Hide == ret->hide;
 		object->isMember = true;
-		if ( ret->isOpaque() && cur->has_enumeratorValue() ) {
+		if ( ret->is_opaque_enum() && cur->has_enumeratorValue() ) {
 			SemanticError( td->location, "Opague cannot have an explicit initializer value." );
 		} else if ( cur->has_enumeratorValue() ) {
 			ast::Expr * initValue;
-			if ( ret->isCfa && ret->base ) {
+			if ( ret->is_typed_enum() ) {
 				CodeLocation location = cur->enumeratorValue->location;
 				initValue = new ast::CastExpr( location, maybeMoveBuild( cur->consume_enumeratorValue() ), ret->base );
Index: src/ResolvExpr/CastCost.cpp
===================================================================
--- src/ResolvExpr/CastCost.cpp	(revision 985ff5f41da6231bbc7c38f716ebe95925c43cfa)
+++ src/ResolvExpr/CastCost.cpp	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -53,13 +53,13 @@
 		void postvisit( const ast::EnumInstType * enumInst ) {
 			cost = conversionCost( enumInst, dst, srcIsLvalue, symtab, env );
-			if ( enumInst->base->isTyped() ) {
-				auto baseConversionCost = 
+			if ( enumInst->base->is_typed_enum() ) {
+				auto baseConversionCost =
 					castCost( enumInst->base->base, dst, srcIsLvalue, symtab, env );
-				cost = baseConversionCost < cost? baseConversionCost: cost;
+				cost = baseConversionCost < cost ? baseConversionCost : cost;
 			}
 			static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
 			Cost intCost = costCalc( integer, dst, srcIsLvalue, symtab, env );
 			intCost.incSafe();
-			cost = intCost < cost? intCost: cost;
+			cost = intCost < cost ? intCost : cost;
 		}
 
Index: src/ResolvExpr/CommonType.cpp
===================================================================
--- src/ResolvExpr/CommonType.cpp	(revision 985ff5f41da6231bbc7c38f716ebe95925c43cfa)
+++ src/ResolvExpr/CommonType.cpp	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -386,5 +386,5 @@
 		} else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
 			const ast::EnumDecl* enumDecl = enumInst->base;
-			if ( !enumDecl->isCfa  ) {
+			if ( enumDecl->is_c_enum() ) {
 				ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ];
 				if (
@@ -654,5 +654,5 @@
 				result = param;
 			}
-		} else if ( param->base && !param->base->isCfa ) {
+		} else if ( param->base && param->base->is_c_enum() ) {
 			auto basicType = new ast::BasicType( ast::BasicKind::UnsignedInt );
 			result = commonType( basicType, type2, tenv, need, have, open, widen);
Index: src/ResolvExpr/ConversionCost.cpp
===================================================================
--- src/ResolvExpr/ConversionCost.cpp	(revision 985ff5f41da6231bbc7c38f716ebe95925c43cfa)
+++ src/ResolvExpr/ConversionCost.cpp	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -246,5 +246,5 @@
 		}
 		if (const ast::EnumInstType * srcAsInst = dynamic_cast< const ast::EnumInstType * >( src )) {
-			if (srcAsInst->base && !srcAsInst->base->isCfa) {
+			if ( srcAsInst->base && srcAsInst->base->is_c_enum() ) {
 				static const ast::BasicType* integer = new ast::BasicType( ast::BasicKind::UnsignedInt );
 				return ast::Pass<ConversionCost>::read( integer, dst, srcIsLvalue, symtab, env, conversionCost );
@@ -324,5 +324,5 @@
 		conversionCostFromBasicToBasic( basicType, dstAsBasic );
 	} else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
-		if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
+		if ( dstAsEnumInst->base && dstAsEnumInst->base->is_c_enum() ) {
 			cost = Cost::safe;
 		}
@@ -405,5 +405,5 @@
 	if ( auto dstInst = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
 		cost = enumCastCost(inst, dstInst, symtab, env);
-	} else if ( !inst->base->isCfa ) {
+	} else if ( inst->base->is_c_enum() ) {
 		static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
 		cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
@@ -455,6 +455,5 @@
 }
 
-void ConversionCost::postvisit( const ast::VarArgsType * varArgsType ) {
-	(void)varArgsType;
+void ConversionCost::postvisit( const ast::VarArgsType * ) {
 	if ( dynamic_cast< const ast::VarArgsType * >( dst ) ) {
 		cost = Cost::zero;
@@ -462,6 +461,5 @@
 }
 
-void ConversionCost::postvisit( const ast::ZeroType * zeroType ) {
-	(void)zeroType;
+void ConversionCost::postvisit( const ast::ZeroType * ) {
 	if ( dynamic_cast< const ast::ZeroType * >( dst ) ) {
 		cost = Cost::zero;
@@ -487,5 +485,5 @@
 		// assuming 0p is supposed to be used for pointers?
 	} else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
-		if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
+		if ( dstAsEnumInst->base && dstAsEnumInst->base->is_c_enum() ) {
 			cost = Cost::safe;
 		}
@@ -493,6 +491,5 @@
 }
 
-void ConversionCost::postvisit( const ast::OneType * oneType ) {
-	(void)oneType;
+void ConversionCost::postvisit( const ast::OneType * ) {
 	if ( dynamic_cast< const ast::OneType * >( dst ) ) {
 		cost = Cost::zero;
@@ -508,5 +505,5 @@
 		}
 	} else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
-		if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
+		if ( dstAsEnumInst->base && dstAsEnumInst->base->is_c_enum() ) {
 			cost = Cost::safe;
 		}
Index: src/ResolvExpr/ResolveTypeof.cpp
===================================================================
--- src/ResolvExpr/ResolveTypeof.cpp	(revision 985ff5f41da6231bbc7c38f716ebe95925c43cfa)
+++ src/ResolvExpr/ResolveTypeof.cpp	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -62,5 +62,5 @@
 			// replace basetypeof(<enum>) by int
 			auto enumInst = newType.as< ast::EnumInstType >();
-			if ( enumInst && (!enumInst->base || !enumInst->base->isCfa) ) {
+			if ( enumInst && (!enumInst->base || enumInst->base->is_c_enum() ) ) {
 				newType = new ast::BasicType(
 					ast::BasicKind::SignedInt, newType->qualifiers, copy(newType->attributes) );
@@ -144,9 +144,9 @@
 
 	auto enumInst = decl->type.as<ast::EnumInstType>();
-	if ( enumInst && enumInst->base->isCfa ) {
+	if ( enumInst && !enumInst->base->is_c_enum() ) {
 		if ( auto init = decl->init.as<ast::SingleInit>() ) {
 			if ( auto initExpr = init->value.as<ast::ConstantExpr>() ) {
 				if ( initExpr->result.as<ast::ZeroType>() ) {
-					auto newInit = new ast::SingleInit( init->location, 
+					auto newInit = new ast::SingleInit( init->location,
 						ast::UntypedExpr::createCall( init->location, "lowerBound", {} )
 					);
Index: src/Validate/ImplementEnumFunc.cpp
===================================================================
--- src/Validate/ImplementEnumFunc.cpp	(revision 985ff5f41da6231bbc7c38f716ebe95925c43cfa)
+++ src/Validate/ImplementEnumFunc.cpp	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -61,5 +61,4 @@
 	ast::FunctionDecl* genLabelProto() const;
 	ast::FunctionDecl* genValueProto() const;
-	ast::FunctionDecl* genQuasiValueProto() const;
 	ast::FunctionDecl* genTypeNameProto() const;
 
@@ -206,5 +205,5 @@
 
 ast::FunctionDecl* EnumAttrFuncGenerator::genValueProto() const {
-	assert (decl->isTyped());
+	assert( decl->is_typed_enum() );
 	return genProto(
 		"value",
@@ -414,5 +413,5 @@
 void EnumAttrFuncGenerator::genTypedEnumFunction(const ast::EnumAttribute attr) {
 	if (attr == ast::EnumAttribute::Value) {
-		if ( !decl->isTyped() ) return;
+		if ( !decl->is_typed_enum() ) return;
 		std::vector<ast::ptr<ast::Init>> inits = genValueInit();
 		ast::ObjectDecl* arrayProto =
@@ -483,5 +482,5 @@
 
 void ImplementEnumFunc::previsit(const ast::EnumDecl* enumDecl) {
-	if (!enumDecl->body || !enumDecl->isCfa) return;
+	if ( !enumDecl->body || enumDecl->is_c_enum() ) return;
 	ast::EnumInstType enumInst(enumDecl->name);
 	enumInst.base = enumDecl;
Index: tests/.expect/zero_one-ERR1.txt
===================================================================
--- tests/.expect/zero_one-ERR1.txt	(revision 332e93a66255ad36fd3a149fc533892743de4286)
+++ tests/.expect/zero_one-ERR1.txt	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -0,0 +1,6 @@
+zero_one.cfa:80:1 error: Invalid application of existing declaration(s) in expression Applying untyped:
+  Name: ?=?
+...to:
+  Name: p
+  Name: o
+
Index: tests/.expect/zero_one.txt
===================================================================
--- tests/.expect/zero_one.txt	(revision 985ff5f41da6231bbc7c38f716ebe95925c43cfa)
+++ tests/.expect/zero_one.txt	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -3,2 +3,12 @@
 It's a Number!
 2 2
+0 0
+42 42
+0 0
+1 1
+42 42
+1 1
+zero true
+zero true
+one false
+one false
Index: tests/Makefile.am
===================================================================
--- tests/Makefile.am	(revision 985ff5f41da6231bbc7c38f716ebe95925c43cfa)
+++ tests/Makefile.am	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -354,4 +354,8 @@
 	-cp ${test} ${abspath ${@}}
 
+zero_one-ERR1 : zero_one.cfa ${CFACCBIN}
+	${CFACOMPILE_SYNTAX} -DERR1
+	-cp ${test} ${abspath ${@}}
+
 ctrl-flow/loop_else : ctrl-flow/loop_else.cfa ${CFACCBIN}
 	${CC} ${AM_CFLAGS} -Wno-superfluous-else $< -o $@ 
Index: tests/bugs/238.cfa
===================================================================
--- tests/bugs/238.cfa	(revision 332e93a66255ad36fd3a149fc533892743de4286)
+++ tests/bugs/238.cfa	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -0,0 +1,27 @@
+// Trac ticket
+// https://cforall.uwaterloo.ca/trac/ticket/238
+
+#include <stdlib.hfa>
+#include <fstream.hfa>
+
+struct cluster {};
+void ?{}(cluster & this) { sout | "Cluster Ctor"; }
+void ?{}(cluster & this, cluster ) { sout | "Cluster CopyCtor"; }
+
+struct inner {
+	cluster * cl;
+};
+void ?{}(inner & this, cluster & ) { sout | "Inner Ctor"; }
+
+struct outer {
+	inner * in;
+};
+void ?{}(outer & this, cluster & cl ) {
+	this.in = new(cl);
+}
+void ^?{}(outer & this) { delete(this.in); }
+
+int main() {
+	cluster cl;
+	outer o = { cl };
+}
Index: tests/bugs/50.cfa
===================================================================
--- tests/bugs/50.cfa	(revision 332e93a66255ad36fd3a149fc533892743de4286)
+++ tests/bugs/50.cfa	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -0,0 +1,7 @@
+// Trac ticket
+// https://cforall.uwaterloo.ca/trac/ticket/50
+
+int main() {
+  [int, int] x;
+  x { [5, 5] };  // assert fail
+}
Index: tests/zero_one.cfa
===================================================================
--- tests/zero_one.cfa	(revision 985ff5f41da6231bbc7c38f716ebe95925c43cfa)
+++ tests/zero_one.cfa	(revision 332e93a66255ad36fd3a149fc533892743de4286)
@@ -39,7 +39,65 @@
 }
 
+void testCompats() {
+    zero_t zero = 0;
+    one_t one = 1;
+
+    int x = 0;
+	int xx = zero;
+
+	sout | x | xx;
+
+	x = xx = 42;
+	sout | x | xx;
+
+	x = 0;
+	xx = zero;
+	sout | x | xx;
+
+	int y = 1;
+	int yy = one;
+
+	sout | y | yy;
+
+	y = yy = 42;
+	sout | y | yy;
+
+	y = 1;
+	yy = one;
+	sout | y | yy;
+
+	void z_helper( int * p, zero_t z ) {
+		p = z;  // expect z not reported unused here; expect no missing cast from -Wint-conversion
+		sout | "zero" | (bool) (p == 0);
+	}
+
+	void z_call( int * p, zero_t z ) {
+		z_helper(p, z);
+	}
+
+	void o_helper( int * p, one_t o ) {
+	  #ifdef ERR1
+		p = o;
+	  #else
+		(void) x;  (void) o;
+	  #endif
+		sout | "one" | (bool) (p == 0);
+	}
+
+	void o_call( int * p, one_t o ) {
+		o_helper(p, o);
+	}
+
+	z_call( &x, 0 );
+	z_call( &x, zero );
+
+	o_call( &x, 1 );
+	o_call( &x, one );
+}
+
 int main() {
 	testOverloads();
 	testInitAssignQueryIncrement();
+	testCompats();
 	return 0;
 }
