Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision bc3127d4673a19c1f70b8cc4cc5902edde3e61d8)
+++ src/CodeGen/CodeGenerator.cc	(revision 58094611c386c7e6f0ba52d00ecf89b154288c42)
@@ -546,11 +546,11 @@
 		extension( addressExpr );
 		output << "(&";
-		// this hack makes sure that we don't convert "constant_zero" to "0" if we're taking its address
-		if ( VariableExpr * variableExpr = dynamic_cast< VariableExpr* >( addressExpr->get_arg() ) ) {
-			output << mangleName( variableExpr->get_var() );
-		} else {
-			addressExpr->get_arg()->accept( *this );
-		} // if
+		addressExpr->arg->accept( *this );
 		output << ")";
+	}
+
+	void CodeGenerator::visit( LabelAddressExpr *addressExpr ) {
+		extension( addressExpr );
+		output << "(&&" << addressExpr->arg << ")";
 	}
 
Index: src/CodeGen/CodeGenerator.h
===================================================================
--- src/CodeGen/CodeGenerator.h	(revision bc3127d4673a19c1f70b8cc4cc5902edde3e61d8)
+++ src/CodeGen/CodeGenerator.h	(revision 58094611c386c7e6f0ba52d00ecf89b154288c42)
@@ -59,4 +59,5 @@
 		virtual void visit( NameExpr *nameExpr );
 		virtual void visit( AddressExpr *addressExpr );
+		virtual void visit( LabelAddressExpr *addressExpr );
 		virtual void visit( CastExpr *castExpr );
 		virtual void visit( VirtualCastExpr *castExpr );
Index: src/CodeGen/OperatorTable.cc
===================================================================
--- src/CodeGen/OperatorTable.cc	(revision bc3127d4673a19c1f70b8cc4cc5902edde3e61d8)
+++ src/CodeGen/OperatorTable.cc	(revision 58094611c386c7e6f0ba52d00ecf89b154288c42)
@@ -66,5 +66,4 @@
 			{	"?^=?",		"^=",	"_operator_bitxorassign",		OT_INFIXASSIGN		},
 			{	"?|=?",		"|=",	"_operator_bitorassign",		OT_INFIXASSIGN		},
-			{	"&&",		"&&",	"&&",							OT_LABELADDRESS		}
 		};
 
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision bc3127d4673a19c1f70b8cc4cc5902edde3e61d8)
+++ src/InitTweak/FixInit.cc	(revision 58094611c386c7e6f0ba52d00ecf89b154288c42)
@@ -127,5 +127,5 @@
 
 			// don't go into other functions
-			virtual void visit( __attribute__((unused)) FunctionDecl *decl ) override {}
+			virtual void visit( FunctionDecl * ) override {}
 
 		  protected:
@@ -913,5 +913,8 @@
 		// of the error.  See C++ Reference 6.6 Jump Statements for details.
 		void InsertDtors::handleGoto( BranchStmt * stmt ) {
-			assert( stmt->get_target() != "" && "BranchStmt missing a label" );
+			// can't do anything for computed goto
+			if ( stmt->computedTarget ) return;
+
+			assertf( stmt->get_target() != "", "BranchStmt missing a label: %s", toString( stmt ).c_str() );
 			// S_L = lvars = set of objects in scope at label definition
 			// S_G = curVars = set of objects in scope at goto statement
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision bc3127d4673a19c1f70b8cc4cc5902edde3e61d8)
+++ src/InitTweak/InitTweak.cc	(revision 58094611c386c7e6f0ba52d00ecf89b154288c42)
@@ -497,10 +497,7 @@
 		using Visitor::visit;
 
-		virtual void visit( __attribute((unused)) ApplicationExpr *applicationExpr ) { isConstExpr = false; }
-		virtual void visit( __attribute((unused)) UntypedExpr *untypedExpr ) { isConstExpr = false; }
-		virtual void visit( NameExpr *nameExpr ) {
-			// xxx - temporary hack, because 0 and 1 really should be constexprs, even though they technically aren't in Cforall today
-			if ( nameExpr->get_name() != "0" && nameExpr->get_name() != "1" ) isConstExpr = false;
-		}
+		virtual void visit( ApplicationExpr * ) { isConstExpr = false; }
+		virtual void visit( UntypedExpr * ) { isConstExpr = false; }
+		virtual void visit( NameExpr * ) { isConstExpr = false; }
 		// virtual void visit( CastExpr *castExpr ) { isConstExpr = false; }
 		virtual void visit( AddressExpr *addressExpr ) {
@@ -509,8 +506,7 @@
 			if ( ! dynamic_cast< NameExpr * >( arg) && ! dynamic_cast< VariableExpr * >( arg ) && ! dynamic_cast< MemberExpr * >( arg ) && ! dynamic_cast< UntypedMemberExpr * >( arg ) ) isConstExpr = false;
 		}
-		virtual void visit( __attribute((unused)) LabelAddressExpr *labAddressExpr ) { isConstExpr = false; }
-		virtual void visit( __attribute((unused)) UntypedMemberExpr *memberExpr ) { isConstExpr = false; }
-		virtual void visit( __attribute((unused)) MemberExpr *memberExpr ) { isConstExpr = false; }
-		virtual void visit( __attribute((unused)) VariableExpr *variableExpr ) { isConstExpr = false; }
+		virtual void visit( UntypedMemberExpr * ) { isConstExpr = false; }
+		virtual void visit( MemberExpr * ) { isConstExpr = false; }
+		virtual void visit( VariableExpr * ) { isConstExpr = false; }
 		// these might be okay?
 		// virtual void visit( SizeofExpr *sizeofExpr );
@@ -523,11 +519,11 @@
 		// virtual void visit( LogicalExpr *logicalExpr );
 		// virtual void visit( ConditionalExpr *conditionalExpr );
-		virtual void visit( __attribute((unused)) TypeExpr *typeExpr ) { isConstExpr = false; }
-		virtual void visit( __attribute((unused)) AsmExpr *asmExpr ) { isConstExpr = false; }
-		virtual void visit( __attribute((unused)) UntypedValofExpr *valofExpr ) { isConstExpr = false; }
-		virtual void visit( __attribute((unused)) CompoundLiteralExpr *compLitExpr ) { isConstExpr = false; }
-		virtual void visit( __attribute((unused)) UntypedTupleExpr *tupleExpr ) { isConstExpr = false; }
-		virtual void visit( __attribute((unused)) TupleExpr *tupleExpr ) { isConstExpr = false; }
-		virtual void visit( __attribute((unused)) TupleAssignExpr *tupleExpr ) { isConstExpr = false; }
+		virtual void visit( TypeExpr * ) { isConstExpr = false; }
+		virtual void visit( AsmExpr * ) { isConstExpr = false; }
+		virtual void visit( UntypedValofExpr * ) { isConstExpr = false; }
+		virtual void visit( CompoundLiteralExpr * ) { isConstExpr = false; }
+		virtual void visit( UntypedTupleExpr * ) { isConstExpr = false; }
+		virtual void visit( TupleExpr * ) { isConstExpr = false; }
+		virtual void visit( TupleAssignExpr * ) { isConstExpr = false; }
 
 		bool isConstExpr;
Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision bc3127d4673a19c1f70b8cc4cc5902edde3e61d8)
+++ src/Parser/ExpressionNode.cc	(revision 58094611c386c7e6f0ba52d00ecf89b154288c42)
@@ -230,5 +230,5 @@
 	// 	ret = new UntypedExpr( new NameExpr( units, ret ) );
 	// } // if
-		
+
 	delete &str;										// created by lex
 	return ret;
@@ -282,5 +282,5 @@
 } // build_varref
 
-
+// TODO: get rid of this and OperKinds and reuse code from OperatorTable
 static const char * OperName[] = {						// must harmonize with OperKinds
 	// diadic
@@ -290,5 +290,5 @@
 	"?[?]", "...",
 	// monadic
-	"+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&"
+	"+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--",
 }; // OperName
 
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision bc3127d4673a19c1f70b8cc4cc5902edde3e61d8)
+++ src/Parser/ParseNode.h	(revision 58094611c386c7e6f0ba52d00ecf89b154288c42)
@@ -154,5 +154,5 @@
 	Index, Range,
 	// monadic
-	UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress,
+	UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost,
 	Ctor, Dtor,
 }; // OperKinds
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision bc3127d4673a19c1f70b8cc4cc5902edde3e61d8)
+++ src/Parser/parser.yy	(revision 58094611c386c7e6f0ba52d00ecf89b154288c42)
@@ -536,4 +536,7 @@
 				$$ = new ExpressionNode( build_unary_val( $1, $2 ) );
 				break;
+			  case OperKinds::And:
+				$$ = new ExpressionNode( new AddressExpr( build_addressOf( $2 ) ) );
+				break;
 			  default:
 				assert( false );
@@ -562,6 +565,4 @@
 	| ATTR_IDENTIFIER '(' type ')'
 		{ $$ = new ExpressionNode( build_attrtype( build_varref( $1 ), $3 ) ); }
-//	| ANDAND IDENTIFIER									// GCC, address of label
-//		{ $$ = new ExpressionNode( new OperatorNode( OperKinds::LabelAddress ), new ExpressionNode( build_varref( $2 ) ); }
 	;
 
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision bc3127d4673a19c1f70b8cc4cc5902edde3e61d8)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 58094611c386c7e6f0ba52d00ecf89b154288c42)
@@ -698,16 +698,4 @@
 
 	void AlternativeFinder::visit( UntypedExpr *untypedExpr ) {
-		{
-			std::string fname = InitTweak::getFunctionName( untypedExpr );
-			if ( fname == "&&" ) {
-				VoidType v = Type::Qualifiers();		// resolve to type void *
-				PointerType pt( Type::Qualifiers(), v.clone() );
-				UntypedExpr *vexpr = untypedExpr->clone();
-				vexpr->set_result( pt.clone() );
-				alternatives.push_back( Alternative( vexpr, env, Cost::zero) );
-				return;
-			}
-		}
-
 		AlternativeFinder funcFinder( indexer, env );
 		funcFinder.findWithAdjustment( untypedExpr->get_function() );
@@ -856,4 +844,8 @@
 			} // if
 		} // for
+	}
+
+	void AlternativeFinder::visit( LabelAddressExpr * expr ) {
+		alternatives.push_back( Alternative( expr->clone(), env, Cost::zero) );
 	}
 
Index: src/ResolvExpr/AlternativeFinder.h
===================================================================
--- src/ResolvExpr/AlternativeFinder.h	(revision bc3127d4673a19c1f70b8cc4cc5902edde3e61d8)
+++ src/ResolvExpr/AlternativeFinder.h	(revision 58094611c386c7e6f0ba52d00ecf89b154288c42)
@@ -54,4 +54,5 @@
 		virtual void visit( UntypedExpr *untypedExpr );
 		virtual void visit( AddressExpr *addressExpr );
+		virtual void visit( LabelAddressExpr *labelExpr );
 		virtual void visit( CastExpr *castExpr );
 		virtual void visit( VirtualCastExpr *castExpr );
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision bc3127d4673a19c1f70b8cc4cc5902edde3e61d8)
+++ src/SymTab/Indexer.cc	(revision 58094611c386c7e6f0ba52d00ecf89b154288c42)
@@ -398,5 +398,4 @@
 	void Indexer::visit( LabelAddressExpr *labAddressExpr ) {
 		acceptNewScope( labAddressExpr->get_result(), *this );
-		maybeAccept( labAddressExpr->get_arg(), *this );
 	}
 
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision bc3127d4673a19c1f70b8cc4cc5902edde3e61d8)
+++ src/SymTab/Validate.cc	(revision 58094611c386c7e6f0ba52d00ecf89b154288c42)
@@ -244,4 +244,10 @@
 	};
 
+	struct LabelAddressFixer final : public WithGuards {
+		std::set< Label > labels;
+
+		void premutate( FunctionDecl * funcDecl );
+		Expression * postmutate( AddressExpr * addrExpr );
+	};
 
 	FunctionDecl * dereferenceOperator = nullptr;
@@ -257,4 +263,5 @@
 		PassVisitor<ValidateGenericParameters> genericParams;
 		PassVisitor<FindSpecialDeclarations> finder;
+		PassVisitor<LabelAddressFixer> labelAddrFixer;
 
 		EliminateTypedef::eliminateTypedef( translationUnit );
@@ -274,4 +281,5 @@
 		ArrayLength::computeLength( translationUnit );
 		acceptAll( translationUnit, finder );
+		mutateAll( translationUnit, labelAddrFixer );
 	}
 
@@ -977,4 +985,34 @@
 	}
 
+	struct LabelFinder {
+		std::set< Label > & labels;
+		LabelFinder( std::set< Label > & labels ) : labels( labels ) {}
+		void previsit( Statement * stmt ) {
+			for ( Label & l : stmt->labels ) {
+				labels.insert( l );
+			}
+		}
+	};
+
+	void LabelAddressFixer::premutate( FunctionDecl * funcDecl ) {
+		GuardValue( labels );
+		PassVisitor<LabelFinder> finder( labels );
+		funcDecl->accept( finder );
+	}
+
+	Expression * LabelAddressFixer::postmutate( AddressExpr * addrExpr ) {
+		// convert &&label into label address
+		if ( AddressExpr * inner = dynamic_cast< AddressExpr * >( addrExpr->arg ) ) {
+			if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( inner->arg ) ) {
+				if ( labels.count( nameExpr->name ) ) {
+					Label name = nameExpr->name;
+					delete addrExpr;
+					return new LabelAddressExpr( name );
+				}
+			}
+		}
+		return addrExpr;
+	}
+
 	void FindSpecialDeclarations::previsit( FunctionDecl * funcDecl ) {
 		if ( ! dereferenceOperator ) {
Index: src/SynTree/AddressExpr.cc
===================================================================
--- src/SynTree/AddressExpr.cc	(revision bc3127d4673a19c1f70b8cc4cc5902edde3e61d8)
+++ src/SynTree/AddressExpr.cc	(revision 58094611c386c7e6f0ba52d00ecf89b154288c42)
@@ -70,4 +70,15 @@
 }
 
+LabelAddressExpr::LabelAddressExpr( const Label &arg ) : arg( arg ) {
+	// label address always has type void *
+	result = new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) );
+}
+LabelAddressExpr::LabelAddressExpr( const LabelAddressExpr & other ) : Expression( other ), arg( other.arg ) {}
+LabelAddressExpr::~LabelAddressExpr() {}
+
+void LabelAddressExpr::print( std::ostream & os, int indent ) const {
+	os << "Address of label:" << std::endl << std::string( indent+2, ' ' ) << arg;
+}
+
 // Local Variables: //
 // tab-width: 4 //
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision bc3127d4673a19c1f70b8cc4cc5902edde3e61d8)
+++ src/SynTree/Expression.h	(revision 58094611c386c7e6f0ba52d00ecf89b154288c42)
@@ -24,4 +24,5 @@
 #include "Constant.h"             // for Constant
 #include "Initializer.h"          // for Designation (ptr only), Initializer
+#include "Label.h"                // for Label
 #include "Mutator.h"              // for Mutator
 #include "SynTree.h"              // for UniqueId
@@ -173,15 +174,13 @@
 };
 
-// xxx - this doesn't appear to actually be hooked in anywhere. We should use this instead of the "&&"" UntypedExpr hack
+// GCC &&label
+// https://gcc.gnu.org/onlinedocs/gcc-3.4.2/gcc/Labels-as-Values.html
 class LabelAddressExpr : public Expression {
   public:
-	Expression * arg;
-
-	LabelAddressExpr( Expression * arg );
+	Label arg;
+
+	LabelAddressExpr( const Label &arg );
 	LabelAddressExpr( const LabelAddressExpr & other );
 	virtual ~LabelAddressExpr();
-
-	Expression * get_arg() const { return arg; }
-	void set_arg(Expression * newValue ) { arg = newValue; }
 
 	virtual LabelAddressExpr * clone() const { return new LabelAddressExpr( * this ); }
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision bc3127d4673a19c1f70b8cc4cc5902edde3e61d8)
+++ src/SynTree/Mutator.cc	(revision 58094611c386c7e6f0ba52d00ecf89b154288c42)
@@ -246,5 +246,4 @@
 	labelAddressExpr->set_env( maybeMutate( labelAddressExpr->get_env(), *this ) );
 	labelAddressExpr->set_result( maybeMutate( labelAddressExpr->get_result(), *this ) );
-	labelAddressExpr->set_arg( maybeMutate( labelAddressExpr->get_arg(), *this ) );
 	return labelAddressExpr;
 }
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision bc3127d4673a19c1f70b8cc4cc5902edde3e61d8)
+++ src/SynTree/Visitor.cc	(revision 58094611c386c7e6f0ba52d00ecf89b154288c42)
@@ -205,5 +205,4 @@
 void Visitor::visit( LabelAddressExpr *labAddressExpr ) {
 	maybeAccept( labAddressExpr->get_result(), *this );
-	maybeAccept( labAddressExpr->get_arg(), *this );
 }
 
Index: src/tests/dtor-early-exit.c
===================================================================
--- src/tests/dtor-early-exit.c	(revision bc3127d4673a19c1f70b8cc4cc5902edde3e61d8)
+++ src/tests/dtor-early-exit.c	(revision 58094611c386c7e6f0ba52d00ecf89b154288c42)
@@ -220,4 +220,22 @@
 }
 
+// TODO: implement __label__ and uncomment these lines
+void computedGoto() {
+  // __label__ bar;
+  void *ptr;
+  ptr = &&foo;
+  goto *ptr;
+  assert(false);
+foo: ;
+//   void f() {
+//     ptr = &&bar;
+//     goto *ptr;
+//     assert(false);
+//   }
+//   f();
+//   assert(false);
+// bar: ;
+}
+
 int main() {
 	sepDisable(sout);
@@ -229,4 +247,6 @@
 	sout | endl;
 	h();
+
+	computedGoto();
 }
 
