fixed constraint code

diff --git a/libasn1fix/asn1fix.c b/libasn1fix/asn1fix.c
index 4810079..d79fd3c 100644
--- a/libasn1fix/asn1fix.c
+++ b/libasn1fix/asn1fix.c
@@ -15,7 +15,8 @@
 static int asn1f_fix_module(arg_t *arg);
 static int asn1f_fix_simple(arg_t *arg);	/* For INTEGER/ENUMERATED */
 static int asn1f_fix_constructed(arg_t *arg);	/* For SEQUENCE/SET/CHOICE */
-static int asn1f_fix_constraints(arg_t *arg);	/* For subtype constraints */
+static int asn1f_resolve_constraints(arg_t *arg); /* For subtype constraints */
+static int asn1f_check_constraints(arg_t *arg);	/* For subtype constraints */
 
 arg_t a1f_replace_me_with_proper_interface_arg;
 
@@ -102,6 +103,7 @@
 asn1f_fix_module(arg_t *arg) {
 	asn1p_expr_t *expr;
 	int rvalue = 0;
+	int ret;
 
 	switch((arg->mod->module_flags & MSF_MASK_TAGS)) {
 	case MSF_NOFLAGS:
@@ -140,7 +142,6 @@
 	 * Order is not important.
 	 */
 	TQ_FOR(expr, &(arg->mod->members), next) {
-		int ret;
 		arg->expr = expr;
 
 		if(expr->meta_type == AMT_PARAMTYPE)
@@ -178,7 +179,7 @@
 		/*
 		 * Resolve references in constraints.
 		 */
-		ret = asn1f_recurse_expr(arg, asn1f_fix_constraints);
+		ret = asn1f_recurse_expr(arg, asn1f_resolve_constraints);
 		RET2RVAL(ret, rvalue);
 
 		/*
@@ -195,7 +196,6 @@
 	 * 5. Automatic tagging
 	 */
 	TQ_FOR(expr, &(arg->mod->members), next) {
-		int ret;
 
 		arg->expr = expr;
 
@@ -210,7 +210,6 @@
 	 * 9. fix spaces in cstrings
 	 */
 	TQ_FOR(expr, &(arg->mod->members), next) {
-		int ret;
 		arg->expr = expr;
 
 		ret = asn1f_recurse_expr(arg, asn1f_fix_bit_string);
@@ -226,7 +225,6 @@
 	 * ... Check for tags distinctness.
 	 */
 	TQ_FOR(expr, &(arg->mod->members), next) {
-		int ret;
 		arg->expr = expr;
 
 		ret = asn1f_recurse_expr(arg, asn1f_check_constr_tags_distinct);
@@ -235,6 +233,18 @@
 		assert(arg->expr == expr);
 	}
 
+	/*
+	 * Check semantic validity of constraints.
+	 */
+	TQ_FOR(expr, &(arg->mod->members), next) {
+		arg->expr = expr;
+
+		ret = asn1f_recurse_expr(arg, asn1f_check_constraints);
+		RET2RVAL(ret, rvalue);
+
+		assert(arg->expr == expr);
+	}
+
 	return rvalue;
 }
 
@@ -287,7 +297,7 @@
 }
 
 static int
-asn1f_fix_constraints(arg_t *arg) {
+asn1f_resolve_constraints(arg_t *arg) {
 	asn1p_expr_t *top_parent;
 	asn1p_expr_type_e etype;
 	int rvalue = 0;
@@ -302,25 +312,38 @@
 		arg->expr->constraints, etype, 0);
 	RET2RVAL(ret, rvalue);
 
+	return rvalue;
+}
+
+static int
+asn1f_check_constraints(arg_t *arg) {
+	static enum asn1p_constraint_type_e test_types[] = {
+		ACT_EL_RANGE, ACT_CT_SIZE, ACT_CT_FROM };
+	asn1p_expr_t *top_parent;
+	asn1cnst_range_t *range;
+	asn1p_expr_type_e etype;
+	unsigned int i;
+	int rvalue = 0;
+	int ret;
+
+	top_parent = asn1f_find_terminal_type(arg, arg->expr);
+	if(!top_parent)
+		return 0;
+	etype = top_parent->expr_type;
+
 	ret = asn1constraint_pullup(arg);
 	RET2RVAL(ret, rvalue);
 
-	if(top_parent) {
-		static enum asn1p_constraint_type_e test_types[] = {
-			ACT_EL_RANGE, ACT_CT_SIZE, ACT_CT_FROM };
-		unsigned int i;
-		for(i = 0; i < sizeof(test_types)/sizeof(test_types[0]); i++) {
-			asn1cnst_range_t *range;
-			range = asn1constraint_compute_PER_range(
-					top_parent->expr_type,
-					arg->expr->combined_constraints,
-					test_types[i], 0, 0);
-			if(!range && errno == EPERM)
-				return -1;
-			asn1constraint_range_free(range);
-		}
+	for(i = 0; i < sizeof(test_types)/sizeof(test_types[0]); i++) {
+		range = asn1constraint_compute_PER_range(
+				top_parent->expr_type,
+				arg->expr->combined_constraints,
+				test_types[i], 0, 0);
+		if(!range && errno == EPERM)
+			return -1;
+		asn1constraint_range_free(range);
 	}
-	
+
 	return rvalue;
 }
 
diff --git a/libasn1fix/asn1fix_constr.c b/libasn1fix/asn1fix_constr.c
index 1574c81..fab78d3 100644
--- a/libasn1fix/asn1fix_constr.c
+++ b/libasn1fix/asn1fix_constr.c
@@ -72,7 +72,7 @@
 	}
 
 	/* Move the stuff back */
-	TQ_HEAD_COPY(&(expr->members), &list);
+	TQ_MOVE(&(expr->members), &list);
 
 	return r_value;
 }
@@ -133,12 +133,12 @@
 	/*
 	 * Copy the root list and extension list back into the main list.
 	 */
-	TQ_HEAD_COPY(&(expr->members), &root_list);
+	TQ_MOVE(&(expr->members), &root_list);
 	while((v = TQ_REMOVE(&ext_list, next)))
 		TQ_ADD(&(expr->members), v, next);
 
 	if(arg->mod->module_flags & MSF_EXTENSIBILITY_IMPLIED
-	&& ext_count < 1) {
+	&& ext_count == 0) {
 		v = asn1p_expr_new(0);
 		if(v) {
 			v->Identifier = strdup("...");
diff --git a/libasn1fix/asn1fix_crange.c b/libasn1fix/asn1fix_crange.c
index 17618ca..3032799 100644
--- a/libasn1fix/asn1fix_crange.c
+++ b/libasn1fix/asn1fix_crange.c
@@ -313,6 +313,11 @@
 		if(type != ACT_CT_FROM)
 			return 0;
 		break;
+	case ATV_REFERENCED:
+		FATAL("Unrecognized constraint element \"%s\" at line %d",
+			asn1f_printable_reference(val->value.reference),
+			lineno);
+		return -1;
 	default:
 		FATAL("Unrecognized constraint element at line %d",
 			lineno);
@@ -878,7 +883,8 @@
 
 	ret  = _range_fill(vmin, minmax, &range->left,
 				range, type, ct->_lineno);
-	ret |= _range_fill(vmax, minmax, &range->right,
+	if(!ret)
+	ret = _range_fill(vmax, minmax, &range->right,
 				range, type, ct->_lineno);
 	if(ret) {
 		_range_free(range);