Index: src/AST/Util.cpp
===================================================================
--- src/AST/Util.cpp	(revision 1ed5e9e2c3003b645b9001bc895374d8e8de1c37)
+++ src/AST/Util.cpp	(revision bfeb37a69a2103c6f286452df6318dc31a9c9238)
@@ -104,4 +104,13 @@
 	}
 	assertf( false, "Member not found." );
+}
+
+template<typename node_t>
+void oneOfExprOrType( const node_t * node ) {
+	if ( node->expr ) {
+		assertf( node->expr && !node->type, "Exactly one of expr or type should be set." );
+	} else {
+		assertf( !node->expr && node->type, "Exactly one of expr or type should be set." );
+	}
 }
 
@@ -152,4 +161,14 @@
 	}
 
+	void previsit( const SizeofExpr * node ) {
+		previsit( (const ParseNode *)node );
+		oneOfExprOrType( node );
+	}
+
+	void previsit( const AlignofExpr * node ) {
+		previsit( (const ParseNode *)node );
+		oneOfExprOrType( node );
+	}
+
 	void previsit( const StructInstType * node ) {
 		previsit( (const Node *)node );
@@ -181,4 +200,6 @@
 /// referring to is in scope by the structural rules of code.
 // Any escapes marked with a bug should be removed once the bug is fixed.
+// This is a separate pass because of it changes the visit pattern and
+// must always be run on the entire translation unit.
 struct InScopeCore : public ast::WithShortCircuiting {
 	ScopedSet<DeclWithType const *> typedDecls;
