Index: src/ControlStruct/ExceptDecl.cpp
===================================================================
--- src/ControlStruct/ExceptDecl.cpp	(revision 29c8675099308007aaa5be2a10db2bc13c6dbca7)
+++ src/ControlStruct/ExceptDecl.cpp	(revision 478dadeb3c5d3140511bb4b837981f8b474530d3)
@@ -9,7 +9,7 @@
 // Author           : Andrew Beach
 // Created On       : Tue Jul 12 15:50:00 2022
-// Last Modified By : Andrew Beach
-// Last Modified On : Mon Jul 18 11:01:00 2022
-// Update Count     : 0
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Sat Sep  7 12:05:55 2024
+// Update Count     : 1
 //
 
@@ -286,5 +286,5 @@
 			new ast::ExprStmt( location,
 				new ast::UntypedExpr( location,
-					new ast::NameExpr( location, "?=?" ),
+					new ast::NameExpr( location, "?{}" ),
 					{
 						new ast::UntypedExpr( location,
Index: src/GenPoly/Box.cpp
===================================================================
--- src/GenPoly/Box.cpp	(revision 29c8675099308007aaa5be2a10db2bc13c6dbca7)
+++ src/GenPoly/Box.cpp	(revision 478dadeb3c5d3140511bb4b837981f8b474530d3)
@@ -515,4 +515,6 @@
 		ast::FunctionType const * adaptee,
 		TypeVarMap const & typeVars ) {
+	assertf( ast::FixedArgs == adaptee->isVarArgs,
+		"Cannot adapt a varadic function, should have been checked." );
 	ast::FunctionType * adapter = ast::deepCopy( adaptee );
 	if ( isDynRet( adapter, typeVars ) ) {
Index: src/Validate/CheckAssertions.cpp
===================================================================
--- src/Validate/CheckAssertions.cpp	(revision 478dadeb3c5d3140511bb4b837981f8b474530d3)
+++ src/Validate/CheckAssertions.cpp	(revision 478dadeb3c5d3140511bb4b837981f8b474530d3)
@@ -0,0 +1,96 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// CheckAssertions.cpp --
+//
+// Author           : Andrew Beach
+// Created On       : Thu Sep  5 14:43:00 2024
+// Last Modified By : Andrew Beach
+// Last Modified On : Thu Sep  5 14:43:00 2024
+// Update Count     : 0
+//
+
+#include "CheckAssertions.hpp"
+
+#include "AST/Decl.hpp"
+#include "AST/Pass.hpp"
+#include "AST/Type.hpp"
+#include "Common/SemanticError.hpp"
+#include "GenPoly/GenPoly.hpp"
+
+namespace Validate {
+
+namespace {
+
+/// Check for dynamic (sized polymorphic) variadic assertions.
+struct VariadicAssertionCore final {
+	void checkAssertion( GenPoly::TypeVarMap const & typeVars,
+			ast::FunctionDecl const * assert ) {
+		if ( ast::FixedArgs != assert->type->isVarArgs
+				&& needsAdapter( assert->type, typeVars ) ) {
+			SemanticError( assert,
+				"Cannot assert a function that both has by-value polymorphic "
+				"parameters or return values, and also takes variadic (...) "
+				"parameters. Consider using a va_list parameter instead.\n" );
+		}
+	}
+
+	template<typename T>
+	void checkList(
+			GenPoly::TypeVarMap const & typeVars,
+			SemanticErrorException & errors,
+			std::vector<ast::ptr<T>> const & members ) {
+		for ( const ast::ptr<T> & member : members ) {
+			try {
+				if ( auto func = member.template as<ast::FunctionDecl>() ) {
+					checkAssertion( typeVars, func );
+				}
+			} catch ( SemanticErrorException & error ) {
+				errors.append( error );
+			}
+		}
+	}
+
+	void postvisit( ast::FunctionDecl const * decl ) {
+		GenPoly::TypeVarMap typeVars;
+		SemanticErrorException errors;
+		makeTypeVarMap( decl, typeVars );
+		checkList( typeVars, errors, decl->assertions );
+		if ( !errors.isEmpty() ) { throw errors; }
+	}
+
+	void checkAggr( bool checkMembers,
+			ast::AggregateDecl const * decl ) {
+		SemanticErrorException errors;
+		GenPoly::TypeVarMap typeVars;
+		for ( auto & param : decl->params ) {
+			addToTypeVarMap( param, typeVars );
+			checkList( typeVars, errors, param->assertions );
+		}
+		if ( checkMembers ) checkList( typeVars, errors, decl->members );
+		if ( !errors.isEmpty() ) { throw errors; }
+	}
+
+	void postvisit( ast::StructDecl const * decl ) {
+	checkAggr( false, decl );
+	}
+
+	void postvisit( ast::UnionDecl const * decl ) {
+		checkAggr( false, decl );
+	}
+
+	void postvisit( ast::TraitDecl const * decl ) {
+		checkAggr( true, decl );
+	}
+};
+
+} // namespace
+
+void checkAssertions( ast::TranslationUnit & transUnit ) {
+	ast::Pass<VariadicAssertionCore>::run( transUnit );
+}
+
+} // namespace Validate
Index: src/Validate/CheckAssertions.hpp
===================================================================
--- src/Validate/CheckAssertions.hpp	(revision 478dadeb3c5d3140511bb4b837981f8b474530d3)
+++ src/Validate/CheckAssertions.hpp	(revision 478dadeb3c5d3140511bb4b837981f8b474530d3)
@@ -0,0 +1,27 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// CheckAssertions.hpp -- Check for invalid assertions.
+//
+// Author           : Andrew Beach
+// Created On       : Thu Sep  5 14:41:00 2024
+// Last Modified By : Andrew Beach
+// Last Modified On : Thu Sep  5 14:41:00 2024
+// Update Count     : 0
+//
+
+#pragma once
+
+namespace ast {
+	class TranslationUnit;
+}
+
+namespace Validate {
+
+/// Checks for problems in an assertion list.
+void checkAssertions( ast::TranslationUnit & transUnit );
+
+}
Index: src/Validate/module.mk
===================================================================
--- src/Validate/module.mk	(revision 29c8675099308007aaa5be2a10db2bc13c6dbca7)
+++ src/Validate/module.mk	(revision 478dadeb3c5d3140511bb4b837981f8b474530d3)
@@ -21,4 +21,6 @@
 	Validate/Autogen.cpp \
 	Validate/Autogen.hpp \
+	Validate/CheckAssertions.cpp \
+	Validate/CheckAssertions.hpp \
 	Validate/CompoundLiteral.cpp \
 	Validate/CompoundLiteral.hpp \
Index: src/main.cpp
===================================================================
--- src/main.cpp	(revision 29c8675099308007aaa5be2a10db2bc13c6dbca7)
+++ src/main.cpp	(revision 478dadeb3c5d3140511bb4b837981f8b474530d3)
@@ -67,4 +67,5 @@
 #include "Tuples/Tuples.hpp"                // for expandMemberTuples, expan...
 #include "Validate/Autogen.hpp"             // for autogenerateRoutines
+#include "Validate/CheckAssertions.hpp"     // for checkAssertions
 #include "Validate/CompoundLiteral.hpp"     // for handleCompoundLiterals
 #include "Validate/EliminateTypedef.hpp"    // for eliminateTypedef
@@ -314,4 +315,5 @@
 		PASS( "Replace Typedefs", Validate::replaceTypedef, transUnit );
 		PASS( "Fix Return Types", Validate::fixReturnTypes, transUnit );
+		PASS( "Check Assertions", Validate::checkAssertions, transUnit );
 		PASS( "Enum and Pointer Decay", Validate::decayEnumsAndPointers, transUnit );
 
Index: tests/.expect/var-assert.txt
===================================================================
--- tests/.expect/var-assert.txt	(revision 478dadeb3c5d3140511bb4b837981f8b474530d3)
+++ tests/.expect/var-assert.txt	(revision 478dadeb3c5d3140511bb4b837981f8b474530d3)
@@ -0,0 +1,32 @@
+var-assert.cfa:3:1 error: Cannot assert a function that both has by-value polymorphic parameters or return values, and also takes variadic (...) parameters. Consider using a va_list parameter instead.
+bad_format: function
+... with parameters
+  format: pointer to const char
+  and a variable number of other arguments
+... returning
+  _retval_bad_format: instance of type T (not function type)
+  ... with attributes:
+    Attribute with name: unused
+
+
+var-assert.cfa:5:1 error: Cannot assert a function that both has by-value polymorphic parameters or return values, and also takes variadic (...) parameters. Consider using a va_list parameter instead.
+val_format: function
+... with parameters
+  instance of type T (not function type)
+  format: pointer to const char
+  and a variable number of other arguments
+... returning
+  _retval_val_format: void
+  ... with attributes:
+    Attribute with name: unused
+
+
+var-assert.cfa:9:1 error: Cannot assert a function that both has by-value polymorphic parameters or return values, and also takes variadic (...) parameters. Consider using a va_list parameter instead.
+vaTuple: function
+  accepting unspecified arguments
+... returning
+  _retval_vaTuple: instance of type Us (not function type)
+  ... with attributes:
+    Attribute with name: unused
+
+
Index: tests/var-assert.cfa
===================================================================
--- tests/var-assert.cfa	(revision 478dadeb3c5d3140511bb4b837981f8b474530d3)
+++ tests/var-assert.cfa	(revision 478dadeb3c5d3140511bb4b837981f8b474530d3)
@@ -0,0 +1,15 @@
+// Check for the use of var-args assertions.
+
+forall(T | { T bad_format(const char * format, ...); })
+trait example {
+	void val_format(T, const char * format, ...);
+	void ref_format(T &, const char * format, ...);
+};
+
+forall(T &, Us | { Us vaTuple(...); })
+Us example(T &);
+
+// Noop Main;
+int main(int argc, char * argv[]) {
+	return 0;
+}
