diff --git a/compiler2/CompField.cc b/compiler2/CompField.cc
index e017e850e5765efab570c7f3559742c93b6d100c..47dca525b17b90bce7c50e3c76c227e862d58031 100644
--- a/compiler2/CompField.cc
+++ b/compiler2/CompField.cc
@@ -23,9 +23,10 @@ namespace Common {
 // =================================
 
 CompField::CompField(Identifier *p_name, Type *p_type, bool p_is_optional,
-  Value *p_defval)
+  Value *p_defval, bool p_default_modifier)
   : Node(), Location(), name(p_name), type(p_type),
-    is_optional(p_is_optional), defval(p_defval), rawattrib(0)
+    is_optional(p_is_optional), defval(p_defval),
+    default_modifier(p_default_modifier), rawattrib(0)
 {
   if(!p_name || !p_type)
     FATAL_ERROR("NULL parameter: Common::CompField::CompField()");
@@ -33,7 +34,8 @@ CompField::CompField(Identifier *p_name, Type *p_type, bool p_is_optional,
 }
 
 CompField::CompField(const CompField& p)
-  : Node(p), Location(p), is_optional(p.is_optional), rawattrib(0)
+  : Node(p), Location(p), is_optional(p.is_optional),
+    default_modifier(p.default_modifier), rawattrib(0)
 {
   name=p.name->clone();
   type=p.type->clone();
@@ -84,6 +86,9 @@ void CompField::dump(unsigned level) const
     DEBUG(level + 1, "with default value");
     defval->dump(level + 2);
   }
+  if (default_modifier) {
+    DEBUG(level + 1, "@default");
+  }
 }
 
 // =================================
@@ -145,6 +150,14 @@ CompField* CompFieldMap::get_comp_byName(const Identifier& p_name)
   return m[p_name.get_name()];
 }
 
+CompField* CompFieldMap::get_default()
+{
+  if (!checked) {
+    chk_uniq();
+  }
+  return default_alt;
+}
+
 const char *CompFieldMap::get_typetype_name() const
 {
   if (!my_type) FATAL_ERROR("CompFieldMap::get_typetype_name()");
@@ -178,6 +191,36 @@ void CompFieldMap::chk_uniq()
       comp->error("Duplicate %s field name `%s'", typetype_name, dispname);
       m[name]->note("Field `%s' is already defined here", dispname);
     } else m.add(name, comp);
+    if (comp->has_default_modifier()) {
+      if (default_alt == NULL) {
+        default_alt = comp;
+      }
+      else {
+        comp->error("Multiple union fields defined with the `@default' modifier");
+        default_alt->note("The `@default' modifier was already used here");
+      }
+    }
+  }
+  if (default_alt != NULL) {
+    CompField* current_default = default_alt;
+    while (current_default) {
+      Type* current_type = current_default->get_type()->get_type_refd_last();
+      if (!current_type->is_secho()) {
+        break;
+      }
+      for (size_t i = 0; i < nof_comps; ++i) {
+        CompField* comp = v[i];
+        const Identifier& id = comp->get_name();
+        if (current_type->has_comp_withName(id)) {
+          CompField* clashing_comp = current_type->get_comp_byName(id);
+          const char* dispname = id.get_dispname().c_str();
+          comp->error("Duplicate union field name `%s'", dispname);
+          clashing_comp->note("Field `%s' of the default alternative is here", dispname);
+        }
+      }
+      current_default = current_type->get_typetype() == Type::T_CHOICE_T ?
+        current_type->get_default_alternative() : NULL;
+    }
   }
   checked = true;
 }
diff --git a/compiler2/CompField.hh b/compiler2/CompField.hh
index e4c96d34ba96f27c0bb20a828bfe80ff52229ee1..9588d6e4c7c905072b9420997f3f8082fd80adf0 100644
--- a/compiler2/CompField.hh
+++ b/compiler2/CompField.hh
@@ -32,6 +32,8 @@ private:
   bool is_optional;
   /** Default value or 0 if no default value. Owned. */
   Value *defval;
+  /** @default modifier */
+  bool default_modifier;
   /** Raw attributes or 0. Owned */
   RawAST *rawattrib;
   /** Copy constructor not implemented */
@@ -40,7 +42,7 @@ private:
   CompField& operator=(const CompField& p);
 public:
   CompField(Identifier *p_name, Type *p_type, bool p_is_optional=false,
-    Value *p_defval=0);
+    Value *p_defval=0, bool p_default_modifier = false);
   virtual ~CompField();
   virtual CompField *clone() const;
   virtual void set_fullname(const string& p_fullname);
@@ -52,6 +54,7 @@ public:
   bool get_is_optional() const { return is_optional; }
   bool has_default() const { return defval != 0; }
   Value *get_defval() const { return defval; }
+  bool has_default_modifier() const { return default_modifier; }
   virtual void dump(unsigned level) const;
 };
 
@@ -68,6 +71,9 @@ private:
   /** Contains pointers to the individual CompField s.
    * The CompFieldMap owns the CompFields and will free them. */
   vector<CompField> v;
+  /** Pointer to the union alternative with the '@default' modifier.
+   * Null if there is none, or if the structure is not a union. */
+  CompField* default_alt;
   /** Points to the owner type, which shall be a TTCN-3 record, set or
    * union or an ASN.1 open type.
    * The CompFieldMap does not own the type. */
@@ -80,7 +86,7 @@ private:
   /** Assignment disabled */
   CompFieldMap& operator=(const CompFieldMap& p);
 public:
-  CompFieldMap() : Node(), m(), v(), my_type(0), checked(false) {}
+  CompFieldMap() : Node(), m(), v(), default_alt(NULL), my_type(0), checked(false) {}
   virtual ~CompFieldMap();
   virtual CompFieldMap *clone() const;
   virtual void set_fullname(const string& p_fullname);
@@ -91,6 +97,7 @@ public:
   CompField* get_comp_byIndex(size_t n) const { return v[n]; }
   bool has_comp_withName(const Identifier& p_name);
   CompField* get_comp_byName(const Identifier& p_name);
+  CompField* get_default();
 private:
   const char *get_typetype_name() const;
   /** Check the uniqueness of field identifiers.
diff --git a/compiler2/Type.cc b/compiler2/Type.cc
index 3711acf52b62312d9770a950909cf779f0944951..be2d4838cdab37406d1e53c8f7e00ae13cc1828e 100644
--- a/compiler2/Type.cc
+++ b/compiler2/Type.cc
@@ -1771,6 +1771,13 @@ namespace Common {
         }
         else {
           if (!t->has_comp_withName(id)) {
+            CompField* def_alt = t->get_default_alternative();
+            if (def_alt != NULL) {
+              Error_Context cntxt(ref, "Using default alternative `%s' in value of union type `%s'",
+                def_alt->get_name().get_dispname().c_str(), t->get_typename().c_str());
+              subrefs->use_default_alternative(i, def_alt->get_name());
+              return get_field_type(subrefs, expected_index, refch, interrupt_if_optional, last_method);
+            }
             if (!silent) {
               ref->error("Reference to non-existent field `%s' in type `%s'",
                 id.get_dispname().c_str(), t->get_typename().c_str());
@@ -1923,6 +1930,15 @@ namespace Common {
             embedded_type = t;
             break;
           }
+        case T_CHOICE_T: {
+          CompField* def_alt = t->get_default_alternative();
+          if (def_alt != NULL) {
+            Error_Context cntxt(ref, "Using default alternative `%s' in value of union type `%s'",
+              def_alt->get_name().get_dispname().c_str(), t->get_typename().c_str());
+            subrefs->use_default_alternative(i, def_alt->get_name());
+            return get_field_type(subrefs, expected_index, refch, interrupt_if_optional, last_method);
+          }
+          /* otherwise fall through */ }
         default:
           if (!silent) {
             ref->error("Type `%s' cannot be indexed",
@@ -6018,6 +6034,18 @@ namespace Common {
     }
     return *(*t->u.secho.field_by_name)[p_name.get_name()];
   }
+  
+  CompField* Type::get_default_alternative()
+  {
+    if (!checked) {
+      chk();
+    }
+    Type* t = get_type_refd_last();
+    if (t->typetype != T_CHOICE_T) {
+      return NULL;
+    }
+    return t->u.secho.cfm->get_default();
+  }
 
   size_t Type::get_eis_index_byName(const Identifier& p_name)
   {
diff --git a/compiler2/Type.hh b/compiler2/Type.hh
index f3423ab861f2455ae7d3358058cb90dc966de83d..825677c6de54f6693cd618527829a3553f5eff05 100644
--- a/compiler2/Type.hh
+++ b/compiler2/Type.hh
@@ -977,7 +977,9 @@ namespace Common {
     void chk_this_value_Any(Value *value);
     bool chk_this_value_Choice(Value *value, Common::Assignment *lhs,
       expected_value_t expected_value, namedbool incomplete_allowed,
-      namedbool implicit_omit = NOT_IMPLICIT_OMIT);
+      namedbool omit_allowed, namedbool sub_chk,
+      namedbool implicit_omit = NOT_IMPLICIT_OMIT,
+      namedbool str_elem = NOT_STR_ELEM);
     bool chk_this_value_Se(Value *value, Common::Assignment *lhs,
       expected_value_t expected_value, namedbool incomplete_allowed,
       namedbool implicit_omit = NOT_IMPLICIT_OMIT);
@@ -1030,8 +1032,9 @@ namespace Common {
     void chk_this_template_length_restriction(Template *t);
     bool chk_this_template_concat_operand(Template* t, namedbool implicit_omit,
       Common::Assignment *lhs);
-    bool chk_this_template(Template *t, namedbool incomplete_allowed, namedbool sub_chk,
-      namedbool implicit_omit, Common::Assignment *);
+    bool chk_this_template(Template *t, namedbool incomplete_allowed,
+      namedbool allow_omit, namedbool allow_any_or_omit, namedbool sub_chk,
+      namedbool implicit_omit, Common::Assignment *lhs);
     bool chk_this_template_Str(Template *t, namedbool implicit_omit,
       Common::Assignment *lhs);
     /** Checks whether \a v is a correct range boundary for this type.
@@ -1049,6 +1052,7 @@ namespace Common {
     void chk_this_template_Int_Real(Template *t);
     void chk_this_template_Enum(Template *t);
     bool chk_this_template_Choice(Template *t, namedbool incomplete_allowed,
+      namedbool allow_omit, namedbool allow_any_or_omit, namedbool sub_chk,
       namedbool implicit_omit, Common::Assignment *lhs);
     bool chk_this_template_Seq(Template *t, namedbool incomplete_allowed,
       namedbool implicit_omit, Common::Assignment *lhs);
@@ -1109,6 +1113,8 @@ namespace Common {
      * T_CHOICE_T, T_SEQ_T, T_SET_T, T_OPENTYPE,
      * T_SEQ_A, T_SET_A, T_CHOICE_A, T_ANYTYPE */
     size_t get_comp_index_byName(const Identifier& p_name);
+    
+    CompField* get_default_alternative();
 
     /** Get the index of the enum item with the given name
      *
diff --git a/compiler2/Type_chk.cc b/compiler2/Type_chk.cc
index 41843b00d84e2c228b263322676fd25aa872492a..95247f4098419b18326d759bb080a5caed9d8b7a 100644
--- a/compiler2/Type_chk.cc
+++ b/compiler2/Type_chk.cc
@@ -3962,6 +3962,13 @@ void Type::chk_this_value_ref(Value *value)
     case T_OCFT:
       get_type_refd()->chk_this_value_ref(value);
       return;
+    case T_CHOICE_T: {
+      CompField* def_alt = get_default_alternative();
+      if (def_alt != NULL) {
+        def_alt->get_type()->chk_this_value_ref(value);
+        return;
+      }
+      break; }
     default:
       break;
     } // switch
@@ -4003,6 +4010,15 @@ bool Type::chk_this_value(Value *value, Common::Assignment *lhs, expected_value_
     if (value->is_unfoldable(0, expected_value)) {
       typetype_t tt = value->get_expr_returntype(expected_value);
       if (!is_compatible_tt(tt, value->is_asn1(), value->get_expr_governor_last())) {
+        CompField* def_alt = get_default_alternative();
+        if (def_alt != NULL) {
+          Error_Context cntxt(value, "Using default alternative `%s' in value of union type `%s'",
+            def_alt->get_name().get_dispname().c_str(), get_typename().c_str());
+          self_ref = def_alt->get_type()->chk_this_value(value, lhs, expected_value,
+            incomplete_allowed, omit_allowed, sub_chk, implicit_omit, is_str_elem);
+          value->use_default_alternative(this);
+          return self_ref;
+        }
         value->error("Incompatible value: `%s' value was expected",
                      get_typename().c_str());
         value->set_valuetype(Value::V_ERROR);
@@ -4085,8 +4101,8 @@ bool Type::chk_this_value(Value *value, Common::Assignment *lhs, expected_value_
   case T_CHOICE_T:
   case T_OPENTYPE:
   case T_ANYTYPE:
-    self_ref = chk_this_value_Choice(value, lhs, expected_value, incomplete_allowed,
-      implicit_omit);
+    self_ref = chk_this_value_Choice(value, lhs, expected_value, omit_allowed,
+      sub_chk, incomplete_allowed, implicit_omit, is_str_elem);
     break;
   case T_SEQ_T:
   case T_SET_T:
@@ -4340,6 +4356,26 @@ bool Type::chk_this_refd_value(Value *value, Common::Assignment *lhs, expected_v
       if (info.is_subtype_error()) {
         value->error("%s", info.get_subtype_error().c_str());
       } else if (!info.is_erroneous()) {
+        CompField* def_alt_ref = governor->get_default_alternative();
+        Ttcn::Reference* ttcn_ref = dynamic_cast<Ttcn::Reference*>(ref);
+        if (def_alt_ref != NULL && ttcn_ref != NULL) {
+          // first try using default alternatives on the right-hand-side
+          Error_Context cntxt(value, "Using default alternative `%s' in reference to "
+            "value of union type `%s'", def_alt_ref->get_name().get_dispname().c_str(),
+            governor->get_typename().c_str());
+          ttcn_ref->use_default_alternative(def_alt_ref->get_name());
+          return chk_this_refd_value(value, lhs, expected_value, refch, str_elem);
+        }
+        CompField* def_alt = get_default_alternative();
+        if (def_alt != NULL) {
+          // afterwards try using default alternatives on the left-hand-side
+          Error_Context cntxt(value, "Using default alternative `%s' in value of union type `%s'",
+            def_alt->get_name().get_dispname().c_str(), get_typename().c_str());
+          self_ref = def_alt->get_type()->chk_this_refd_value(value, lhs,
+            expected_value, refch, str_elem);
+          value->use_default_alternative(this);
+          return self_ref;
+        }
         value->error("Type mismatch: a %s of type `%s' was expected "
                      "instead of `%s'", expected_value == EXPECTED_TEMPLATE
                      ? "value or template" : "value",
@@ -4932,12 +4968,22 @@ static string actual_fields(Type& t) // alas, not even get_nof_comps() is const
 
 
 bool Type::chk_this_value_Choice(Value *value, Common::Assignment *lhs,
-  expected_value_t expected_value, namedbool incomplete_allowed, namedbool implicit_omit)
+  expected_value_t expected_value, namedbool omit_allowed, namedbool sub_chk,
+  namedbool incomplete_allowed, namedbool implicit_omit, namedbool str_elem)
 {
   bool self_ref = false;
+  CompField* def_alt = get_default_alternative();
   switch(value->get_valuetype()) {
   case Value::V_SEQ:
     if (value->is_asn1()) {
+      if (def_alt != NULL) {
+        Error_Context cntxt(value, "Using default alternative `%s' in value of union type `%s'",
+          def_alt->get_name().get_dispname().c_str(), get_typename().c_str());
+        self_ref = def_alt->get_type()->chk_this_value(value, lhs, expected_value,
+          incomplete_allowed, omit_allowed, sub_chk, implicit_omit, str_elem);
+        value->use_default_alternative(this);
+        return self_ref;
+      }
       value->error("CHOICE value was expected for type `%s'",
                    get_fullname().c_str());
       value->set_valuetype(Value::V_ERROR);
@@ -4945,6 +4991,15 @@ bool Type::chk_this_value_Choice(Value *value, Common::Assignment *lhs,
     } else {
       // the valuetype can be ERROR if the value has no fields at all
       if (value->get_valuetype() == Value::V_ERROR) return false;
+      if (def_alt != NULL && (value->get_nof_comps() != 1 ||
+          !has_comp_withName(value->get_se_comp_byIndex(0)->get_name()))) {
+        Error_Context cntxt(value, "Using default alternative `%s' in value of union type `%s'",
+          def_alt->get_name().get_dispname().c_str(), get_typename().c_str());
+        self_ref = def_alt->get_type()->chk_this_value(value, lhs, expected_value,
+          incomplete_allowed, omit_allowed, sub_chk, implicit_omit, str_elem);
+        value->use_default_alternative(this);
+        return self_ref;
+      }
       // The value notation for TTCN record/union types
       // cannot be distinguished during parsing.  Now we know it's a union.
       value->set_valuetype(Value::V_CHOICE);
@@ -4957,20 +5012,30 @@ bool Type::chk_this_value_Choice(Value *value, Common::Assignment *lhs,
     }
     const Identifier& alt_name = value->get_alt_name();
     if(!has_comp_withName(alt_name)) {
-      if (value->is_asn1()) {
-        value->error("Reference to non-existent alternative `%s' in CHOICE"
-                     " value for type `%s'",
-                     alt_name.get_dispname().c_str(),
-                     get_fullname().c_str());
-      } else {
-        value->error("Reference to non-existent field `%s' in union "
-                     "value for type `%s'",
-                     alt_name.get_dispname().c_str(),
-                     get_fullname().c_str());
+      if (def_alt != NULL) {
+        Error_Context cntxt(value, "Using default alternative `%s' in value of union type `%s'",
+          def_alt->get_name().get_dispname().c_str(), get_typename().c_str());
+        self_ref = def_alt->get_type()->chk_this_value(value, lhs, expected_value,
+          incomplete_allowed, omit_allowed, sub_chk, implicit_omit, str_elem);
+        value->use_default_alternative(this);
+        return self_ref;
+      }
+      else {
+        if (value->is_asn1()) {
+          value->error("Reference to non-existent alternative `%s' in CHOICE"
+                       " value for type `%s'",
+                       alt_name.get_dispname().c_str(),
+                       get_fullname().c_str());
+        } else {
+          value->error("Reference to non-existent field `%s' in union "
+                       "value for type `%s'",
+                       alt_name.get_dispname().c_str(),
+                       get_fullname().c_str());
+        }
+        value->set_valuetype(Value::V_ERROR);
+        value->note("%s", actual_fields(*this).c_str());
+        return self_ref;
       }
-      value->set_valuetype(Value::V_ERROR);
-      value->note("%s", actual_fields(*this).c_str());
-      return self_ref;
     }
     Type *alt_type = get_comp_byName(alt_name)->get_type();
     Value *alt_value = value->get_alt_value();
@@ -4986,10 +5051,19 @@ bool Type::chk_this_value_Choice(Value *value, Common::Assignment *lhs,
     }
     break;}
   default:
-    value->error("%s value was expected for type `%s'",
-                 value->is_asn1() ? "CHOICE" : "union",
-                 get_fullname().c_str());
-    value->set_valuetype(Value::V_ERROR);
+    if (def_alt != NULL) {
+      Error_Context cntxt(value, "Using default alternative `%s' in value of union type `%s'",
+        def_alt->get_name().get_dispname().c_str(), get_typename().c_str());
+      self_ref = def_alt->get_type()->chk_this_value(value, lhs, expected_value,
+        incomplete_allowed, omit_allowed, sub_chk, implicit_omit, str_elem);
+      value->use_default_alternative(this);
+      return self_ref;
+    }
+    else {
+      value->error("%s value was expected for type `%s'",
+        value->is_asn1() ? "CHOICE" : "union", get_fullname().c_str());
+      value->set_valuetype(Value::V_ERROR);
+    }   
     break;
   }
   return self_ref;
@@ -6537,7 +6611,8 @@ bool Type::chk_this_template_generic(Template *t, namedbool incomplete_allowed,
     }
     break;
   default:
-    self_ref = chk_this_template(t, incomplete_allowed, sub_chk, implicit_omit, lhs);
+    self_ref = chk_this_template(t, incomplete_allowed, allow_omit, allow_any_or_omit,
+      sub_chk, implicit_omit, lhs);
     break;
   }
   if (t->get_length_restriction()) chk_this_template_length_restriction(t);
@@ -6687,8 +6762,9 @@ bool Type::chk_this_template_concat_operand(Template* t, namedbool implicit_omit
   return self_ref;
 }
 
-bool Type::chk_this_template(Template *t, namedbool incomplete_allowed, namedbool,
-  namedbool implicit_omit, Common::Assignment *lhs)
+bool Type::chk_this_template(Template *t, namedbool incomplete_allowed,
+                             namedbool allow_omit, namedbool allow_any_or_omit, namedbool sub_chk,
+                             namedbool implicit_omit, Common::Assignment *lhs)
 {
   bool self_ref = false;
   Type *t_last = get_type_refd_last();
@@ -6742,7 +6818,8 @@ bool Type::chk_this_template(Template *t, namedbool incomplete_allowed, namedboo
   case T_CHOICE_T:
   case T_OPENTYPE:
   case T_ANYTYPE:
-    self_ref = t_last->chk_this_template_Choice(t, incomplete_allowed, implicit_omit, lhs);
+    self_ref = t_last->chk_this_template_Choice(t, incomplete_allowed, allow_omit,
+      allow_any_or_omit, sub_chk, implicit_omit, lhs);
     break;
   case T_SEQ_A:
   case T_SEQ_T:
@@ -7030,12 +7107,23 @@ void Type::chk_this_template_Enum(Template *t)
 }
 
 bool Type::chk_this_template_Choice(Template *t, namedbool incomplete_allowed,
+  namedbool allow_omit, namedbool allow_any_or_omit, namedbool sub_chk,
   namedbool implicit_omit, Common::Assignment *lhs)
 {
   bool self_ref = false;
+  CompField* def_alt = get_default_alternative();
   switch (t->get_templatetype()) {
   case Ttcn::Template::NAMED_TEMPLATE_LIST: {
     size_t nof_nts = t->get_nof_comps();
+    if (def_alt != NULL && (nof_nts != 1 ||
+        !has_comp_withName(t->get_namedtemp_byIndex(0)->get_name()))) {
+      Error_Context cntxt(t, "Using default alternative `%s' in template of union type `%s'",
+        def_alt->get_name().get_dispname().c_str(), get_typename().c_str());
+      self_ref = def_alt->get_type()->chk_this_template_generic(t, incomplete_allowed, allow_omit,
+        allow_any_or_omit, sub_chk, implicit_omit, lhs);
+      t->use_default_alternative(this);
+      return self_ref;
+    }
     if (nof_nts != 1) t->error("A template for union type must contain "
       "exactly one selected field");
     // We check all named templates, even though it is an error
@@ -7072,6 +7160,14 @@ bool Type::chk_this_template_Choice(Template *t, namedbool incomplete_allowed,
     }
     break;}
   default:
+    if (def_alt != NULL) {
+      Error_Context cntxt(t, "Using default alternative `%s' in value of union type `%s'",
+        def_alt->get_name().get_dispname().c_str(), get_typename().c_str());
+      self_ref = def_alt->get_type()->chk_this_template_generic(t, incomplete_allowed, allow_omit,
+        allow_any_or_omit, sub_chk, implicit_omit, lhs);
+      t->use_default_alternative(this);
+      return self_ref;
+    }
     t->error("%s cannot be used for union type `%s'",
       t->get_templatetype_str(), get_typename().c_str());
     break;
diff --git a/compiler2/Value.cc b/compiler2/Value.cc
index 0846c3ba24b3f370b3d653165d76b0d7885cf410..6dd9179434028ce9bf6ffa13a48c21a2dc1e50d1 100644
--- a/compiler2/Value.cc
+++ b/compiler2/Value.cc
@@ -80,7 +80,7 @@ namespace Common {
   // =================================
 
   Value::Value(const Value& p)
-    : GovernedSimple(p), valuetype(p.valuetype), my_governor(0)
+    : GovernedSimple(p), valuetype(p.valuetype), my_governor(p.my_governor)
     , in_brackets(p.in_brackets)
   {
     switch(valuetype) {
@@ -3681,7 +3681,8 @@ namespace Common {
     }
   }
 
-  Type::typetype_t Value::get_expr_returntype(Type::expected_value_t exp_val)
+  Type::typetype_t Value::get_expr_returntype(Type::expected_value_t exp_val,
+                                              bool use_def_alt /* = false */)
   {
     switch (valuetype) {
     case V_CHARSYMS:
@@ -3710,8 +3711,23 @@ namespace Common {
     case V_REFD:
     case V_INVOKE: {
       Type *t = get_expr_governor(exp_val);
-      if (t) return t->get_type_refd_last()->get_typetype_ttcn3();
-      else return Type::T_ERROR; }
+      if (t != NULL) {
+        t = t->get_type_refd_last();
+      }
+      Type::typetype_t tt = t != NULL ? t->get_typetype_ttcn3() : Type::T_ERROR;
+      if (use_def_alt) {
+        while (tt == Type::T_CHOICE_T) {
+          CompField* def_alt = t->get_default_alternative();
+          if (def_alt != NULL) {
+            t = def_alt->get_type()->get_type_refd_last();
+            tt = t->get_typetype_ttcn3();
+          }
+          else {
+            break; // exit the 'while' loop if there's no default alternative
+          }
+        }
+      }
+      return tt; }
     case V_FUNCTION:
       return Type::T_FUNCTION;
     case V_ALTSTEP:
@@ -3801,7 +3817,7 @@ namespace Common {
           Error_Context cntxt(this, "In the operand of operation `%s'",
                               get_opname());
           u.expr.v1->set_lowerid_to_ref();
-          tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
+          tmp_tt=u.expr.v1->get_expr_returntype(exp_val, true);
         }
         switch(tmp_tt) {
         case Type::T_INT:
@@ -3821,7 +3837,7 @@ namespace Common {
           Error_Context cntxt(this, "In the left operand of operation `%s'",
                               get_opname());
           u.expr.v1->set_lowerid_to_ref();
-          tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
+          tmp_tt=u.expr.v1->get_expr_returntype(exp_val, true);
         }
         switch(tmp_tt) {
         case Type::T_INT:
@@ -3834,7 +3850,7 @@ namespace Common {
               Error_Context cntxt(this, "In the right operand of operation `%s'",
                                   get_opname());
               u.expr.v2->set_lowerid_to_ref();
-              tmp_tt2=u.expr.v2->get_expr_returntype(exp_val);
+              tmp_tt2=u.expr.v2->get_expr_returntype(exp_val, true);
             }
             Type::typetype_t ret_val=Type::T_ERROR;
             bool maybeconcat=false;
@@ -3882,7 +3898,7 @@ namespace Common {
                               u.expr.v_optype==OPTYPE_NOT4B?"":"left ",
                               get_opname());
           u.expr.v1->set_lowerid_to_ref();
-          tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
+          tmp_tt=u.expr.v1->get_expr_returntype(exp_val, true);
         }
         switch(tmp_tt) {
         case Type::T_BSTR:
@@ -3966,7 +3982,7 @@ namespace Common {
           Error_Context cntxt(this, "In the first operand of operation `%s'",
                               get_opname());
           u.expr.v1->set_lowerid_to_ref();
-          tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
+          tmp_tt=u.expr.v1->get_expr_returntype(exp_val, true);
         }
         switch(tmp_tt) {
         case Type::T_CSTR:
@@ -4583,29 +4599,6 @@ namespace Common {
     } // switch
   }
 
-  void Value::chk_expr_operandtype_enum(const char *opname, Value *v,
-                                        Type::expected_value_t exp_val)
-  {
-    v->set_lowerid_to_ref(); // can only be reference to enum
-    Type *t = v->get_expr_governor(exp_val);
-    if (v->valuetype==V_ERROR) return;
-    if (!t) {
-      v->error("Please use reference to an enumerated value as the operand of "
-            "operation `%s'", get_opname());
-      set_valuetype(V_ERROR);
-      return;
-    }
-    t = t->get_type_refd_last();
-    if (t->get_typetype()!=Type::T_ENUM_A && t->get_typetype()!=Type::T_ENUM_T) {
-      v->error("The operand of operation `%s' should be enumerated value", opname);
-      set_valuetype(V_ERROR);
-    }
-    if (v->get_value_refd_last()->valuetype==V_OMIT) {
-      v->error("The operand of operation `%s' cannot be omit", opname);
-      set_valuetype(V_ERROR);
-    }
-  }
-
   void Value::chk_expr_operandtype_bool(Type::typetype_t tt,
                                         const char *opnum,
                                         const char *opname,
@@ -4956,6 +4949,26 @@ namespace Common {
           if (!info1.is_erroneous() && !info2.is_erroneous()) {
             // the subtypes don't need to be compatible here
             if (!info1.is_subtype_error() && !info2.is_subtype_error()) {
+              if (v1->is_ref()) {
+                CompField* def_alt = t1->get_default_alternative();
+                Ttcn::Reference* ttcn_ref = dynamic_cast<Ttcn::Reference*>(v1->get_reference());
+                if (def_alt != NULL && ttcn_ref != NULL) {
+                  Error_Context cntxt(v1, "Using default alternative `%s' in value of union type `%s'",
+                    def_alt->get_name().get_dispname().c_str(), t1->get_typename().c_str());
+                  ttcn_ref->use_default_alternative(def_alt->get_name());
+                  return chk_expr_operandtypes_compat(exp_val, v1, v2, opnum1, opnum2);
+                }
+              }
+              if (v2->is_ref()) {
+                CompField* def_alt = t2->get_default_alternative();
+                Ttcn::Reference* ttcn_ref = dynamic_cast<Ttcn::Reference*>(v2->get_reference());
+                if (def_alt != NULL && ttcn_ref != NULL) {
+                  Error_Context cntxt(v2, "Using default alternative `%s' in value of union type `%s'",
+                    def_alt->get_name().get_dispname().c_str(), t2->get_typename().c_str());
+                  ttcn_ref->use_default_alternative(def_alt->get_name());
+                  return chk_expr_operandtypes_compat(exp_val, v1, v2, opnum1, opnum2);
+                }
+              }
               error("The operands of operation `%s' should be of compatible "
                     "types", get_opname());
               set_valuetype(V_ERROR);
@@ -5272,6 +5285,16 @@ namespace Common {
           ->get_field_type(ref->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE);
         if(!ret_val) goto error;
         Type* t_type=ret_val->get_type_refd_last();
+        if (t_type->get_typetype() == Type::T_CHOICE_T) {
+          CompField* def_alt = t_type->get_default_alternative();
+          Ttcn::Reference* ttcn_ref = dynamic_cast<Ttcn::Reference*>(ref);
+          if (def_alt != NULL && ttcn_ref != NULL) {
+            Error_Context cntxt(val, "Using default alternative `%s' in value of union type `%s'",
+              def_alt->get_name().get_dispname().c_str(), t_type->get_typename().c_str());
+            ttcn_ref->use_default_alternative(def_alt->get_name());
+            return chk_expr_operand_compref(val, opnum, opname, any_from);
+          }
+        }
         if(t_type->get_typetype() != (any_from ? Type::T_ARRAY : Type::T_COMPONENT)) {
           ref->error("%s operand of operation `%s': Type mismatch:"
                      " component%s reference was expected instead of `%s'",
@@ -6446,14 +6469,31 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
       case Type::T_CHOICE_T:
       case Type::T_ANYTYPE:
       case Type::T_OPENTYPE:
-	if (!t_governor->has_comp_withName(*u.expr.i2)) {
-	  error(t_governor->get_typetype()==Type::T_ANYTYPE ?
-	    "%s does not have a field named `%s'"   :
-	    "Union type `%s' does not have a field named `%s'",
-	    t_governor->get_typename().c_str(),
-	    u.expr.i2->get_dispname().c_str());
-	  error_flag = true;
-	}
+        if (!t_governor->has_comp_withName(*u.expr.i2)) {
+          CompField* def_alt = t_governor->get_default_alternative();
+          Ttcn::Reference* ref = u.expr.v_optype == OPTYPE_ISCHOSEN_V ?
+            dynamic_cast<Ttcn::Reference*>(u.expr.v1->get_reference()) :
+            u.expr.t1->get_reference();
+          if (def_alt != NULL && ref != NULL) {
+            Error_Context cntxt2(ref, "Using default alternative `%s' in value or template of union type `%s'",
+              def_alt->get_name().get_dispname().c_str(), t_governor->get_typename().c_str());
+            ref->use_default_alternative(def_alt->get_name());
+            if (u.expr.v_optype == OPTYPE_ISCHOSEN_V) {
+              u.expr.v1->set_my_governor(def_alt->get_type());
+            }
+            else {
+              u.expr.t1->set_my_governor(def_alt->get_type());
+            }
+            chk_expr_operands_ischosen(refch, exp_val);
+            return;
+          }
+          error(t_governor->get_typetype()==Type::T_ANYTYPE ?
+            "%s does not have a field named `%s'"   :
+            "Union type `%s' does not have a field named `%s'",
+            t_governor->get_typename().c_str(),
+            u.expr.i2->get_dispname().c_str());
+          error_flag = true;
+        }
         break;
       default:
 	loc->error("The operand of operation `%s' should be a union value "
@@ -6581,6 +6621,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
       }
       v_enc_info->set_lowerid_to_ref();
       Type::typetype_t tt = v_enc_info->get_expr_returntype(exp_val);
+      if (tt == Type::T_CHOICE_T && v_enc_info->is_ref() &&
+          chk_expr_operand_default_alternative(v_enc_info, refch, exp_val)) {
+        // this function was already re-called with the default alternative, abort this call
+        return;
+      }
       chk_expr_operandtype_charstr(tt, u.expr.v_optype == OPTYPE_ENCODE ?
         "Second" : "Third", opname, v_enc_info);
       chk_expr_eval_value(v_enc_info, t_chk, refch, exp_val);
@@ -6597,6 +6642,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
       }
       v_dyn_enc->set_lowerid_to_ref();
       Type::typetype_t tt = v_dyn_enc->get_expr_returntype(exp_val);
+      if (tt == Type::T_CHOICE_T && v_dyn_enc->is_ref() &&
+          chk_expr_operand_default_alternative(v_dyn_enc, refch, exp_val)) {
+        // this function was already re-called with the default alternative, abort this call
+        return;
+      }
       chk_expr_operandtype_charstr(tt, u.expr.v_optype == OPTYPE_ENCODE ?
         "Third" : "Fourth", opname, v_dyn_enc);
       chk_expr_eval_value(v_dyn_enc, t_chk, refch, exp_val);
@@ -6667,6 +6717,16 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
       if (!t_type) {
         goto error;
       }
+      if (t_type->get_type_refd_last()->get_typetype() == Type::T_CHOICE_T) {
+        CompField* def_alt = t_type->get_default_alternative();
+        if (def_alt != NULL) {
+          Error_Context cntxt2(ref, "Using default alternative `%s' in reference to value of union type `%s'",
+            def_alt->get_name().get_dispname().c_str(), t_type->get_typename().c_str());
+          ref->use_default_alternative(def_alt->get_name());
+          chk_expr_operands_decode(refch, exp_val);
+          return;
+        }
+      }
       switch(u.expr.v_optype) {
         case OPTYPE_DECODE:
           if (t_type->get_type_refd_last()->get_typetype() != Type::T_BSTR){
@@ -6750,6 +6810,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         }
         v_enc_info->set_lowerid_to_ref();
         Type::typetype_t tt = v_enc_info->get_expr_returntype(exp_val);
+        if (tt == Type::T_CHOICE_T && v_enc_info->is_ref() &&
+            chk_expr_operand_default_alternative(v_enc_info, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_charstr(tt, u.expr.v_optype == OPTYPE_DECODE ?
           "Third" : "Fourth", opname, v_enc_info);
         chk_expr_eval_value(v_enc_info, t_chk, refch, exp_val);
@@ -6766,6 +6831,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         }
         v_dyn_enc->set_lowerid_to_ref();
         Type::typetype_t tt = v_dyn_enc->get_expr_returntype(exp_val);
+        if (tt == Type::T_CHOICE_T && v_dyn_enc->is_ref() &&
+            chk_expr_operand_default_alternative(v_dyn_enc, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_charstr(tt, u.expr.v_optype == OPTYPE_DECODE ?
           "Fourth" : "Fifth", opname, v_dyn_enc);
         chk_expr_eval_value(v_dyn_enc, t_chk, refch, exp_val);
@@ -6835,7 +6905,8 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
   }
 
   Int Value::chk_eval_expr_sizeof(ReferenceChain *refch,
-                                  Type::expected_value_t exp_val)
+                                  Type::expected_value_t exp_val,
+                                  Type* def_alt_type)
   {
     if(valuetype==V_ERROR) return -1;
     if(u.expr.state==EXPR_CHECKING_ERR) return -1;
@@ -6899,7 +6970,8 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
     Assignment* t_ass = 0;
     Reference* ref = 0;
     Ttcn::FieldOrArrayRefs* t_subrefs = 0;
-    t_type = chk_expr_operands_ti(u.expr.ti1, exp_val);
+    t_type = def_alt_type != NULL ? def_alt_type :
+      chk_expr_operands_ti(u.expr.ti1, exp_val);
     if (t_type) {
       chk_expr_eval_ti(u.expr.ti1, t_type, refch, exp_val);
       t_type = t_type->get_type_refd_last();
@@ -6917,6 +6989,10 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
     case Template::INDEXED_TEMPLATE_LIST:
       return -1;
     case Template::TEMPLATE_REFD:
+      ref = t_templ->get_reference();
+      t_ass = ref->get_refd_assignment();
+      t_subrefs = ref->get_subrefs();
+      break;
     case Template::TEMPLATE_LIST:
     case Template::NAMED_TEMPLATE_LIST:
       // computed later
@@ -6996,10 +7072,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
     case Assignment::A_PAR_TEMPL_IN:
     case Assignment::A_PAR_TEMPL_OUT:
     case Assignment::A_PAR_TEMPL_INOUT:
-      if (exp_val!=Type::EXPECTED_TEMPLATE)
+      if (exp_val!=Type::EXPECTED_TEMPLATE) {
         u.expr.ti1->error("Reference to a value was expected instead of %s",
                    t_ass->get_description().c_str());
-      goto error;
+        goto error;
+      }
       break;
     case Assignment::A_FUNCTION_RVAL:
     case Assignment::A_EXT_FUNCTION_RVAL:
@@ -7079,6 +7156,18 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
     case Type::T_OID:
     case Type::T_ROID:
       break;
+    case Type::T_CHOICE_T:
+      if (ref != NULL) {
+        CompField* def_alt = t_type->get_default_alternative();
+        Ttcn::Reference* ttcn_ref = dynamic_cast<Ttcn::Reference*>(ref);
+        if (def_alt != NULL && ttcn_ref != NULL) {
+          Error_Context cntxt2(ref, "Using default alternative `%s' in value or template of union type `%s'",
+            def_alt->get_name().get_dispname().c_str(), t_type->get_typename().c_str());
+          ttcn_ref->use_default_alternative(def_alt->get_name());
+          return chk_eval_expr_sizeof(refch, exp_val, def_alt->get_type());
+        }
+      }
+      // otherwise fall through
     default:
       u.expr.ti1->error("Reference to value or template of type record, record of,"
                  " set, set of, objid or array was expected");
@@ -7358,6 +7447,58 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
       set_valuetype(V_ERROR);
     }
   }
+  
+  bool Value::chk_expr_operand_default_alternative(Value* v, ReferenceChain *refch,
+                                                   Type::expected_value_t exp_val)
+  {
+    if (!v->is_ref()) {
+      FATAL_ERROR("Value::chk_default_alternative_ref");
+    }
+    Type* t = v->get_expr_governor(exp_val);
+    CompField* def_alt = t->get_default_alternative();
+    Ttcn::Reference* ttcn_ref = dynamic_cast<Ttcn::Reference*>(v->get_reference());
+    if (def_alt != NULL && ttcn_ref != NULL) {
+      Error_Context cntxt(v, "Using default alternative `%s' in value of union type `%s'",
+        def_alt->get_name().get_dispname().c_str(), t->get_typename().c_str());
+      ttcn_ref->use_default_alternative(def_alt->get_name());
+      if (u.expr.state != EXPR_CHECKING_ERR) {
+        chk_expr_operands(refch, exp_val);
+      }
+      return true;
+    }
+    return false;
+  }
+  
+  bool Value::chk_expr_operand_default_alternative(TemplateInstance* ti, Type* ti_gov,
+                                                   ReferenceChain *refch, Type::expected_value_t exp_val)
+  {
+    CompField* def_alt = ti_gov->get_default_alternative();
+    if (def_alt == NULL) {
+      return false;
+    }
+    Ttcn::Reference* ttcn_ref = NULL;
+    Template* temp = ti->get_Template();
+    switch (temp->get_templatetype()) {
+    case Ttcn::Template::TEMPLATE_REFD:
+      ttcn_ref = temp->get_reference();
+      break;
+    case Ttcn::Template::SPECIFIC_VALUE:
+      ttcn_ref = dynamic_cast<Ttcn::Reference*>(temp->get_specific_value()->get_reference());
+      break;
+    default:
+      break;
+    }
+    if (ttcn_ref != NULL) {
+      Error_Context cntxt(ti, "Using default alternative `%s' in value or template of union type `%s'",
+        def_alt->get_name().get_dispname().c_str(), ti_gov->get_typename().c_str());
+      ttcn_ref->use_default_alternative(def_alt->get_name());
+      if (u.expr.state != EXPR_CHECKING_ERR) {
+        chk_expr_operands(refch, exp_val);
+      }
+      return true;
+    }
+    return false;
+  }
 
   void Value::chk_expr_operands(ReferenceChain *refch,
                                 Type::expected_value_t exp_val)
@@ -7431,6 +7572,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_int_float(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -7441,6 +7587,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_bool(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -7451,6 +7602,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_binstr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -7463,6 +7619,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_bstr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -7473,6 +7634,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_bstr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
         // Skip `chk_expr_val_bitstr_intsize(v1, the, opname);'.
@@ -7484,6 +7650,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_cstr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
         chk_expr_val_len1(v1, the, opname);
@@ -7495,6 +7666,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_cstr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -7505,6 +7681,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_cstr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
         chk_expr_val_str_int(v1, the, opname);
@@ -7516,6 +7697,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_cstr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
         chk_expr_val_str_float(v1, the, opname);
@@ -7527,6 +7713,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_cstr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
         chk_expr_val_str_bindigits(v1, the, opname);
@@ -7538,6 +7729,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_cstr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
         chk_expr_val_str_hexdigits(v1, the, opname);
@@ -7549,6 +7745,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_cstr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
         chk_expr_val_str_len_even(v1, the, opname);
@@ -7559,7 +7760,29 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
       v1=u.expr.v1;
       {
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
-        chk_expr_operandtype_enum(opname, v1, exp_val);
+        v1->set_lowerid_to_ref(); // can only be reference to enum
+        Type *t = v1->get_expr_governor(exp_val);
+        if (v1->valuetype==V_ERROR) return;
+        if (!t) {
+          v1->error("Please use reference to an enumerated value as the operand of "
+            "operation `%s'", get_opname());
+          set_valuetype(V_ERROR);
+          return;
+        }
+        t = t->get_type_refd_last();
+        if (t->get_typetype() == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
+        if (t->get_typetype()!=Type::T_ENUM_A && t->get_typetype()!=Type::T_ENUM_T) {
+          v1->error("The operand of operation `%s' should be enumerated value", opname);
+          set_valuetype(V_ERROR);
+        }
+        if (v1->get_value_refd_last()->valuetype==V_OMIT) {
+          v1->error("The operand of operation `%s' cannot be omit", opname);
+          set_valuetype(V_ERROR);
+        }
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
       break;
@@ -7573,6 +7796,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_float(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
         if (u.expr.v_optype==OPTYPE_FLOAT2INT)
@@ -7585,6 +7813,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_float(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
         chk_expr_operand_valid_float(v1, the, opname);
@@ -7599,6 +7832,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_hstr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -7609,6 +7847,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_hstr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
         // Skip `chk_expr_val_hexstr_intsize(v1, the, opname);'.
@@ -7620,6 +7863,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_int(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
         chk_expr_val_int_pos7bit(v1, the, opname);
@@ -7631,6 +7879,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_int(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
         chk_expr_val_int_pos31bit(v1, first, opname);
@@ -7643,6 +7896,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_int(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -7657,6 +7915,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_ostr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -7667,6 +7930,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_ostr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
         // Simply skip `chk_expr_val_hexstr_intsize(v1, the, opname);' for
@@ -7679,6 +7947,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_ostr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
         chk_expr_val_str_7bitoctets(v1, the, opname);
@@ -7690,6 +7963,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_ostr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -7700,6 +7978,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_ostr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -7710,6 +7993,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_ostr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -7719,6 +8007,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
         v2->set_lowerid_to_ref();
         tt2=v2->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_bool(tt2, second, opname, v2);
         chk_expr_eval_value(v2, t_chk, refch, exp_val);
       }
@@ -7729,6 +8022,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_cstr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -7739,6 +8037,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_charstr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
         chk_expr_val_len1(v1, the, opname);
@@ -7750,6 +8053,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_charstr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
         chk_expr_val_ustr_7bitchars(v1, the, opname);
@@ -7762,6 +8070,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_cstr(tt1, second, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -7773,6 +8086,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_charstr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -7783,6 +8101,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_charstr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -7792,6 +8115,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
         v2->set_lowerid_to_ref();
         tt2=v2->get_expr_returntype(exp_val);
+        if (tt2 == Type::T_CHOICE_T && v2->is_ref() &&
+            chk_expr_operand_default_alternative(v2, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_cstr(tt2, second, opname, v2);
         chk_expr_eval_value(v2, t_chk, refch, exp_val);
       }
@@ -7802,6 +8130,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_ostr(tt1, the, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -7811,6 +8144,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
         v2->set_lowerid_to_ref();
         tt2=v2->get_expr_returntype(exp_val);
+        if (tt2 == Type::T_CHOICE_T && v2->is_ref() &&
+            chk_expr_operand_default_alternative(v2, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_cstr(tt2, second, opname, v2);
         chk_expr_eval_value(v2, t_chk, refch, exp_val);
       }
@@ -7828,6 +8166,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
       Error_Context cntxt(u.expr.v2, "In the second operand of operation `%s'", opname);
       u.expr.v2->set_lowerid_to_ref();
       tt2=u.expr.v2->get_expr_returntype(exp_val);
+      if (tt2 == Type::T_CHOICE_T && u.expr.v2->is_ref() &&
+          chk_expr_operand_default_alternative(u.expr.v2, refch, exp_val)) {
+        // this function was already re-called with the default alternative, abort this call
+        return;
+      }
       chk_expr_operandtype_charstr(tt2, second, opname, u.expr.v2);
       chk_expr_eval_value(u.expr.v2, t_chk, refch, exp_val);
       if (!u.expr.v2->is_unfoldable()) {
@@ -7853,6 +8196,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
         v2->set_lowerid_to_ref();
         tt2=v2->get_expr_returntype(exp_val);
+        if (tt2 == Type::T_CHOICE_T && v2->is_ref() &&
+            chk_expr_operand_default_alternative(v2, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_charstr(tt2, second, opname, v2);
         chk_expr_eval_value(v2, t_chk, refch, exp_val);
         if (!u.expr.v2->is_unfoldable()) {
@@ -7875,6 +8223,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the thrid operand of operation `%s'", opname);
         v3->set_lowerid_to_ref();
         tt3=v3->get_expr_returntype(exp_val);
+        if (tt3 == Type::T_CHOICE_T && v3->is_ref() &&
+            chk_expr_operand_default_alternative(v3, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_charstr(tt3, third, opname, v3);
         chk_expr_eval_value(v3, t_chk, refch, exp_val);
         if (!u.expr.v3->is_unfoldable()) {
@@ -7899,7 +8252,17 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
       v1->set_lowerid_to_ref();
       v2->set_lowerid_to_ref();
       tt1=v1->get_expr_returntype(exp_val);
+      if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+          chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+        // this function was already re-called with the default alternative, abort this call
+        return;
+      }
       tt2=v2->get_expr_returntype(exp_val);
+      if (tt2 == Type::T_CHOICE_T && v2->is_ref() &&
+          chk_expr_operand_default_alternative(v2, refch, exp_val)) {
+        // this function was already re-called with the default alternative, abort this call
+        return;
+      }
       chk_expr_operandtype_int_float(tt1, first, opname, v1);
       chk_expr_operandtype_int_float(tt2, second, opname, v2);
       chk_expr_eval_value(v1, t_chk, refch, exp_val);
@@ -7916,6 +8279,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_int(tt1, left, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -7924,6 +8292,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
         v2->set_lowerid_to_ref();
         tt2=v2->get_expr_returntype(exp_val);
+        if (tt2 == Type::T_CHOICE_T && v2->is_ref() &&
+            chk_expr_operand_default_alternative(v2, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_int(tt2, right, opname, v2);
         chk_expr_eval_value(v2, t_chk, refch, exp_val);
         chk_expr_val_int_float_not0(v2, right, opname);
@@ -7938,12 +8311,22 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         {
           Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
           tt1=v1->get_expr_returntype(exp_val);
+          if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+              chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+            // this function was already re-called with the default alternative, abort this call
+            return;
+          }
           chk_expr_operandtype_str(tt1, left, opname, v1);
           chk_expr_eval_value(v1, t_chk, refch, exp_val);
         }
         {
           Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
           tt2=v2->get_expr_returntype(exp_val);
+          if (tt2 == Type::T_CHOICE_T && v2->is_ref() &&
+              chk_expr_operand_default_alternative(v2, refch, exp_val)) {
+            // this function was already re-called with the default alternative, abort this call
+            return;
+          }
           chk_expr_operandtype_str(tt2, right, opname, v2);
           chk_expr_eval_value(v2, t_chk, refch, exp_val);
         }
@@ -7951,6 +8334,8 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
             || (tt2==Type::T_CSTR && tt1==Type::T_USTR)))
           chk_expr_operandtypes_same(tt1, tt2, opname);
       } else { // other list types
+        v1->get_value_refd_last();
+        v2->get_value_refd_last();
         Type* v1_gov = v1->get_expr_governor(exp_val);
         Type* v2_gov = v2->get_expr_governor(exp_val);
         if (!v1_gov) {
@@ -7959,6 +8344,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
           return;
         } else {
           Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
+          if (v1->is_ref() && v1_gov->get_type_refd_last()->get_typetype() == Type::T_CHOICE_T &&
+              chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+            // this function was already re-called with the default alternative, abort this call
+            return;
+          }
           v1_gov->chk_this_value_ref(v1);
           (void)v1_gov->chk_this_value(v1, 0, exp_val,
             INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
@@ -7972,6 +8362,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         {
           Error_Context cntxt(this, "In the right operand of operation `%s'",
                               opname);
+          if (v2->is_ref() && v2_gov->get_type_refd_last()->get_typetype() == Type::T_CHOICE_T &&
+              chk_expr_operand_default_alternative(v2, refch, exp_val)) {
+            // this function was already re-called with the default alternative, abort this call
+            return;
+          }
           v2_gov->chk_this_value_ref(v2);
           (void)v2_gov->chk_this_value(v2, 0, exp_val,
             INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
@@ -8027,6 +8422,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the left operand of operation `%s'",
                             opname);
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_int_float_enum(tt1, left, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -8034,6 +8434,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the right operand of operation `%s'",
                             opname);
         tt2=v2->get_expr_returntype(exp_val);
+        if (tt2 == Type::T_CHOICE_T && v2->is_ref() &&
+            chk_expr_operand_default_alternative(v2, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_int_float_enum(tt2, right, opname, v2);
         chk_expr_eval_value(v2, t_chk, refch, exp_val);
       }
@@ -8047,6 +8452,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
                             opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_bool(tt1, left, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -8056,6 +8466,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
                             opname);
         v2->set_lowerid_to_ref();
         tt2=v2->get_expr_returntype(exp_val);
+        if (tt2 == Type::T_CHOICE_T && v2->is_ref() &&
+            chk_expr_operand_default_alternative(v2, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_bool(tt2, right, opname, v2);
         chk_expr_eval_value(v2, t_chk, refch, exp_val);
       }
@@ -8069,6 +8484,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
                             opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_binstr(tt1, left, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -8078,6 +8498,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
                             opname);
         v2->set_lowerid_to_ref();
         tt2=v2->get_expr_returntype(exp_val);
+        if (tt2 == Type::T_CHOICE_T && v2->is_ref() &&
+            chk_expr_operand_default_alternative(v2, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_binstr(tt2, right, opname, v2);
         chk_expr_eval_value(v2, t_chk, refch, exp_val);
       }
@@ -8091,6 +8516,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_binstr(tt1, left, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       }
@@ -8099,6 +8529,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
         v2->set_lowerid_to_ref();
         tt2=v2->get_expr_returntype(exp_val);
+        if (tt2 == Type::T_CHOICE_T && v2->is_ref() &&
+            chk_expr_operand_default_alternative(v2, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_int(tt2, right, opname, v2);
         chk_expr_eval_value(v2, t_chk, refch, exp_val);
         chk_expr_val_large_int(v2, right, opname);
@@ -8111,14 +8546,25 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
       if (v1->is_string_type(exp_val)) {
         Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_str(tt1, left, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
       } else { // other list types
+        v1->get_value_refd_last();
         Type* v1_gov = v1->get_expr_governor(exp_val);
         if (!v1_gov) { // a recof/setof literal would be a syntax error here
           error("Cannot determine the type of the left operand of `%s' operation", opname);
         } else {
           Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
+          if (v1->is_ref() && v1_gov->get_type_refd_last()->get_typetype() == Type::T_CHOICE_T &&
+              chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+            // this function was already re-called with the default alternative, abort this call
+            return;
+          }
           v1_gov->chk_this_value_ref(v1);
           (void)v1_gov->chk_this_value(v1, 0, exp_val,
             INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
@@ -8130,6 +8576,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
         v2->set_lowerid_to_ref();
         tt2=v2->get_expr_returntype(exp_val);
+        if (tt2 == Type::T_CHOICE_T && v2->is_ref() &&
+            chk_expr_operand_default_alternative(v2, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_int(tt2, right, opname, v2);
         chk_expr_eval_value(v2, t_chk, refch, exp_val);
         chk_expr_val_large_int(v2, right, opname);
@@ -8143,6 +8594,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
         v1->set_lowerid_to_ref();
         tt1=v1->get_expr_returntype(exp_val);
+        if (tt1 == Type::T_CHOICE_T && v1->is_ref() &&
+            chk_expr_operand_default_alternative(v1, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_int(tt1, first, opname, v1);
         chk_expr_eval_value(v1, t_chk, refch, exp_val);
         chk_expr_val_int_pos0(v1, first, opname);
@@ -8152,6 +8608,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
         v2->set_lowerid_to_ref();
         tt2=v2->get_expr_returntype(exp_val);
+        if (tt2 == Type::T_CHOICE_T && v2->is_ref() &&
+            chk_expr_operand_default_alternative(v2, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_int(tt2, second, opname, v2);
         chk_expr_eval_value(v2, t_chk, refch, exp_val);
         chk_expr_val_int_pos0(v2, second, opname);
@@ -8168,6 +8629,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
         Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
         if (!governor) return;
+        if (governor->get_type_refd_last()->get_typetype() == Type::T_CHOICE_T &&
+            chk_expr_operand_default_alternative(u.expr.ti1, governor, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
         if (valuetype!=V_ERROR)
           u.expr.ti1->get_Template()->chk_specific_value(false);
@@ -8178,6 +8644,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
         v2->set_lowerid_to_ref();
         tt2=v2->get_expr_returntype(exp_val);
+        if (tt2 == Type::T_CHOICE_T && v2->is_ref() &&
+            chk_expr_operand_default_alternative(v2, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_int(tt2, second, opname, v2);
         chk_expr_eval_value(v2, t_chk, refch, exp_val);
         chk_expr_val_int_pos0(v2, second, opname);
@@ -8187,6 +8658,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
         v3->set_lowerid_to_ref();
         tt3=v3->get_expr_returntype(exp_val);
+        if (tt3 == Type::T_CHOICE_T && v3->is_ref() &&
+            chk_expr_operand_default_alternative(v3, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_int(tt3, third, opname, v3);
         chk_expr_eval_value(v3, t_chk, refch, exp_val);
         chk_expr_val_int_pos0(v3, third, opname);
@@ -8200,6 +8676,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
         Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
         if (!governor) return;
+        if (governor->get_type_refd_last()->get_typetype() == Type::T_CHOICE_T &&
+            chk_expr_operand_default_alternative(u.expr.ti1, governor, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
         if (valuetype!=V_ERROR) {
           u.expr.ti1->get_Template()->chk_specific_value(false);
@@ -8211,6 +8692,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
         Type* governor = chk_expr_operands_ti(u.expr.t2, ti_exp_val);
         if (!governor) return;
+        if (governor->get_type_refd_last()->get_typetype() == Type::T_CHOICE_T &&
+            chk_expr_operand_default_alternative(u.expr.t2, governor, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_eval_ti(u.expr.t2, governor, refch, ti_exp_val);
         chk_expr_operandtype_charstr(governor->get_type_refd_last()->
           get_typetype_ttcn3(), second, opname, u.expr.t2);
@@ -8220,6 +8706,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
         v3->set_lowerid_to_ref();
         tt3=v3->get_expr_returntype(exp_val);
+        if (tt3 == Type::T_CHOICE_T && v3->is_ref() &&
+            chk_expr_operand_default_alternative(v3, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_int(tt3, third, opname, v3);
         chk_expr_eval_value(v3, t_chk, refch, exp_val);
         chk_expr_val_int_pos0(v3, third, opname);
@@ -8283,6 +8774,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
       Error_Context cntxt(this, "In the operand of operation `%s'", opname);
       Type *governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
       if (!governor) return;
+      if (governor->get_type_refd_last()->get_typetype() == Type::T_CHOICE_T &&
+          chk_expr_operand_default_alternative(u.expr.ti1, governor, refch, exp_val)) {
+        // this function was already re-called with the default alternative, abort this call
+        return;
+      }
       chk_expr_operandtype_list(governor, the, opname, u.expr.ti1, true);
       if (valuetype == V_ERROR) return;
       chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
@@ -8384,8 +8880,13 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
         Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
         v2->set_lowerid_to_ref();
         tt2=v2->get_expr_returntype(exp_val);
-	chk_expr_operandtype_cstr(tt2, first, opname, v2);
-	chk_expr_eval_value(v2, t_chk, refch, exp_val);
+        if (tt2 == Type::T_CHOICE_T && v2->is_ref() &&
+            chk_expr_operand_default_alternative(v2, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
+        chk_expr_operandtype_cstr(tt2, first, opname, v2);
+        chk_expr_eval_value(v2, t_chk, refch, exp_val);
       }
       break;
     case OPTYPE_ACTIVATE_REFD:{ //v1 t_list2
@@ -8417,6 +8918,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
                             opname);
         Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
         if (!governor) return;
+        if (governor->get_type_refd_last()->get_typetype() == Type::T_CHOICE_T &&
+            chk_expr_operand_default_alternative(u.expr.ti1, governor, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
         if (valuetype != V_ERROR)
           u.expr.ti1->get_Template()->chk_specific_value(false);
@@ -8428,6 +8934,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
                             opname);
         v2->set_lowerid_to_ref();
         tt2 = v2->get_expr_returntype(exp_val);
+        if (tt2 == Type::T_CHOICE_T && v2->is_ref() &&
+            chk_expr_operand_default_alternative(v2, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_int(tt2, second, opname, v2);
         chk_expr_eval_value(v2, t_chk, refch, exp_val);
         chk_expr_val_int_pos0(v2, second, opname);
@@ -8438,6 +8949,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
                             opname);
         v3->set_lowerid_to_ref();
         tt3 = v3->get_expr_returntype(exp_val);
+        if (tt3 == Type::T_CHOICE_T && v3->is_ref() &&
+            chk_expr_operand_default_alternative(v3, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_operandtype_int(tt3, third, opname, v3);
         chk_expr_eval_value(v3, t_chk, refch, exp_val);
         chk_expr_val_int_pos0(v3, third, opname);
@@ -8447,6 +8963,11 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
                             opname);
         Type* governor = chk_expr_operands_ti(u.expr.ti4, ti_exp_val);
         if (!governor) return;
+        if (governor->get_type_refd_last()->get_typetype() == Type::T_CHOICE_T &&
+            chk_expr_operand_default_alternative(u.expr.ti4, governor, refch, exp_val)) {
+          // this function was already re-called with the default alternative, abort this call
+          return;
+        }
         chk_expr_eval_ti(u.expr.ti4, governor, refch, ti_exp_val);
         if (valuetype != V_ERROR)
           u.expr.ti4->get_Template()->chk_specific_value(false);
@@ -9682,6 +10203,26 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
       FATAL_ERROR("Value::add_id()");
     } // switch
   }
+  
+  void Value::use_default_alternative(Type* p_union_type)
+  {
+    if (valuetype == V_ERROR) {
+      return;
+    }
+    CompField* def_alt = p_union_type->get_default_alternative();
+    if (def_alt == NULL) {
+      FATAL_ERROR("Value::use_default_alternative");
+    }
+    Value* def_val = clone();
+    def_val->my_governor = def_alt->get_type();
+    def_val->set_my_scope(my_scope);
+    def_val->set_fullname(get_fullname() + ".<default_alternative>");
+    clean_up();
+    valuetype = V_CHOICE;
+    u.choice.alt_name = def_alt->get_name().clone();
+    u.choice.alt_value = def_val;
+    my_governor = p_union_type;
+  }
 
   Value* Value::get_value_refd_last(ReferenceChain *refch,
                                     Type::expected_value_t exp_val)
@@ -10546,8 +11087,23 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
     set_lowerid_to_ref();
     Type::typetype_t r_tt = get_expr_returntype(exp_val);
     bool error_flag = r_tt != Type::T_ERROR && r_tt != p_tt;
-    if (error_flag)
+    if (error_flag) {
+      if (is_ref() && r_tt == Type::T_CHOICE_T) {
+        Type* t = get_expr_governor(exp_val);
+        if (t != NULL) {
+          CompField* def_alt = t->get_default_alternative();
+          Ttcn::Reference* ttcn_ref = dynamic_cast<Ttcn::Reference*>(get_reference());
+          if (def_alt != NULL && ttcn_ref != NULL) {
+            Error_Context cntxt(this, "Using default alternative `%s' in value of union type `%s'",
+              def_alt->get_name().get_dispname().c_str(), t->get_typename().c_str());
+            ttcn_ref->use_default_alternative(def_alt->get_name());
+            chk_expr_type(p_tt, type_name, exp_val);
+            return;
+          }
+        }
+      }
       error("A value or expression of type %s was expected", type_name);
+    }
     if (valuetype == V_REFD) {
       Type *t_chk = Type::get_pooltype(Type::T_ERROR);
       t_chk->chk_this_refd_value(this, 0, exp_val);
@@ -12898,7 +13454,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
 
   bool Value::is_string_type(Type::expected_value_t exp_val)
   {
-    switch (get_expr_returntype(exp_val)) {
+    switch (get_expr_returntype(exp_val, true)) {
     case Type::T_CSTR:
     case Type::T_USTR:
     case Type::T_BSTR:
diff --git a/compiler2/Value.hh b/compiler2/Value.hh
index 5e24451ee17218457b92e4426a311e76efb9091e..2be02078ee864996736ec69711cd3845ff7222ed 100644
--- a/compiler2/Value.hh
+++ b/compiler2/Value.hh
@@ -523,6 +523,12 @@ namespace Common {
     void set_valuetype(valuetype_t p_valuetype, Identifier *p_id);
     void set_valuetype(valuetype_t p_valuetype, Assignment *p_ass);
     void add_id(Identifier *p_id);
+    /** Converts the value into a union value, with the union type's @default alternative
+      * as its name and the original (cloned) value as its value.
+      * Used when a value of a different type appears in a context, where a value of
+      * the specified union type was expected.
+      * This attempts to use the value as the union's default alternative instead. */
+    void use_default_alternative(Type* p_union_type);
     /** Follows the chain of references if any and returns the last
      *  element of the chain. In other words, the returned value is
      *  the first value which is not a reference. */
@@ -551,7 +557,8 @@ namespace Common {
 
     /** If this value is used in an expression, what is its return type? */
     Type::typetype_t get_expr_returntype
-    (Type::expected_value_t exp_val=Type::EXPECTED_DYNAMIC_VALUE);
+    (Type::expected_value_t exp_val=Type::EXPECTED_DYNAMIC_VALUE,
+     bool use_def_alt = false);
     /** If this value is used in an expression, what is its governor?
      *  If has no governor, but is reference, then tries the
      *  referenced stuff... If not known, returns NULL. */
@@ -565,8 +572,6 @@ namespace Common {
     /** Used to determine whether the reference points to value or
      *  template in ISCHOSEN, then convert to {ISCHOSEN}_{V,T} */
     void chk_expr_ref_ischosen();
-    void chk_expr_operandtype_enum(const char *opname, Value *v,
-                                   Type::expected_value_t exp_val);
     void chk_expr_operandtype_bool(Type::typetype_t tt, const char *opnum,
                                    const char *opname, const Location *loc);
     void chk_expr_operandtype_int(Type::typetype_t tt, const char *opnum,
@@ -697,7 +702,8 @@ namespace Common {
      * should be a referenced value pointing to a optional record/set field. */
     void chk_expr_omit_comparison(Type::expected_value_t exp_val);
     Int chk_eval_expr_sizeof(ReferenceChain *refch,
-                             Type::expected_value_t exp_val);
+                             Type::expected_value_t exp_val,
+                             Type* def_alt_type = NULL);
     /** The governor is returned. */
     Type *chk_expr_operands_ti(TemplateInstance* ti, Type::expected_value_t exp_val);
     void chk_expr_operands_match(Type::expected_value_t exp_val);
@@ -709,6 +715,17 @@ namespace Common {
     void chk_expr_operands(ReferenceChain *refch,
                            Type::expected_value_t exp_val);
     void chk_expr_operand_valid_float(Value* v, const char *opnum, const char *opname);
+    /** Checks whether the type of the specified union value has a @default alternative.
+      * If it is, then the default alternative's subreference is appended to the end of
+      * the value (which must be a reference) and 'chk_expr_operands' is re-called. */
+    bool chk_expr_operand_default_alternative(Value* v, ReferenceChain *refch,
+      Type::expected_value_t exp_val);
+    /** Checks whether the template instance is a reference to a value or template of a union
+      * type, that has a @default alternative.
+      * If it is, then the default alternative's subreference is appended to the end of
+      * the value/template reference and 'chk_expr_operands' is re-called. */
+    bool chk_expr_operand_default_alternative(TemplateInstance* ti, Type* ti_gov,
+      ReferenceChain *refch, Type::expected_value_t exp_val);
     /** Evaluate...
      * Called by Value::get_value_refd_last() for V_EXPR */
     void evaluate_value(ReferenceChain *refch, Type::expected_value_t exp_val);
diff --git a/compiler2/ttcn3/AST_ttcn3.cc b/compiler2/ttcn3/AST_ttcn3.cc
index f3f13e321bf03cb3cde763e4fd0d8cbd246b8b4c..e5d3569b29b367ea7e45063b885afab7d8ff4c33 100644
--- a/compiler2/ttcn3/AST_ttcn3.cc
+++ b/compiler2/ttcn3/AST_ttcn3.cc
@@ -554,6 +554,14 @@ namespace Ttcn {
   {
     for (size_t i = 0; i < refs.size(); i++) refs[i]->append_stringRepr(str);
   }
+  
+  void FieldOrArrayRefs::use_default_alternative(size_t p_idx, const Identifier& p_alt_name)
+  {
+    FieldOrArrayRef* alt_ref = new FieldOrArrayRef(new Identifier(p_alt_name));
+    alt_ref->set_my_scope(my_scope);
+    refs.insert(alt_ref, p_idx);
+    set_fullname(get_fullname());
+  }
 
   // =================================
   // ===== Ref_base
@@ -564,7 +572,7 @@ namespace Ttcn {
   {
     modid = p.modid ? p.modid->clone() : 0;
     id = p.id ? p.id->clone() : 0;
-    params_checked = p.is_erroneous;
+    params_checked = p.params_checked;
   }
 
   Ref_base::Ref_base(Identifier *p_modid, Identifier *p_id)
@@ -696,10 +704,11 @@ namespace Ttcn {
   // =================================
   
   Reference::Reference(const Reference& p)
-    : Ref_base(p), reftype(p.reftype), parlist(NULL), gen_const_prefix(false),
+    : Ref_base(p), reftype(p.reftype), gen_const_prefix(false),
     expr_cache(NULL)
   {
     params = p.params != NULL ? p.params->clone() : NULL;
+    parlist = p.parlist != NULL ? p.parlist->clone() : NULL;
   }
 
   Reference::Reference(Identifier *p_id)
@@ -1084,6 +1093,16 @@ namespace Ttcn {
     }
   }
   
+  
+  void Reference::use_default_alternative(const Identifier& p_alt_name)
+  {
+    FieldOrArrayRef* alt_ref = new FieldOrArrayRef(new Identifier(p_alt_name));
+    alt_ref->set_my_scope(my_scope);
+    alt_ref->set_fullname(get_fullname() +
+      ".<sub_reference" + Int2string(subrefs.get_nof_refs()) + ">");
+    subrefs.add(alt_ref);
+  }
+  
   void Reference::set_code_section(
     GovernedSimple::code_section_t p_code_section)
   {
diff --git a/compiler2/ttcn3/AST_ttcn3.hh b/compiler2/ttcn3/AST_ttcn3.hh
index 2d7039ac1dd358e8abb3fa70180455deabd9a681..39ac73082b8e4adb948ad1e821d5ed4ee4a54673 100644
--- a/compiler2/ttcn3/AST_ttcn3.hh
+++ b/compiler2/ttcn3/AST_ttcn3.hh
@@ -288,6 +288,10 @@ namespace Ttcn {
     bool refers_to_string_element() const { return refs_str_element; }
     void set_string_element_ref() { refs_str_element = true; }
     void clear_string_element_ref() { refs_str_element = false; }
+    /** Adds a new field ref for the union type's @default alternative at the specified index.
+      * Used when the subreference at the given index is not a valid field name or array index 
+      * for the union type it is attributed to. This attempts to use the union's default alternative instead. */
+    void use_default_alternative(size_t p_idx, const Identifier& p_alt_name);
   };
 
   /**
@@ -409,6 +413,10 @@ namespace Ttcn {
     /** Lets the referenced assignment object know, that the reference is used
       * at least once (only relevant for formal parameters and external constants). */
     void ref_usage_found();
+    /** Appends a new field subref for the union type's @default alternative at the end of the reference.
+      * Used when the reference points to a union value or template in a context where a union is not allowed.
+      * This attempts to use the union's default alternative instead. */
+    void use_default_alternative(const Identifier& p_alt_name);
   private:
     /** Detects whether the first identifier in subrefs is a module id */
     void detect_modid();
diff --git a/compiler2/ttcn3/PatternString.cc b/compiler2/ttcn3/PatternString.cc
index 89cc7350ba72ae0dcd7ba2b51b3ee287caf22a6b..2a355cf6cafd02a4014a2f45ee463b7ac57c7423 100644
--- a/compiler2/ttcn3/PatternString.cc
+++ b/compiler2/ttcn3/PatternString.cc
@@ -276,7 +276,8 @@ namespace Ttcn {
   // =================================
 
   PatternString::PatternString(const PatternString& p)
-    : Node(p), my_scope(0), cstr_value(0), pattern_type(p.pattern_type)
+    : Node(p), my_scope(0), cstr_value(0), pattern_type(p.pattern_type),
+      nocase(p.nocase)
   {
     size_t nof_elems = p.elems.size();
     for (size_t i = 0; i < nof_elems; i++) elems.add(p.elems[i]->clone());
diff --git a/compiler2/ttcn3/Statement.cc b/compiler2/ttcn3/Statement.cc
index 7b6fc066286f82b4f2c9cd4c311a359cc4b448d1..9c69f8e8854fd2b73bf0ad4ed37ea5591b3816f9 100644
--- a/compiler2/ttcn3/Statement.cc
+++ b/compiler2/ttcn3/Statement.cc
@@ -3003,10 +3003,24 @@ namespace Ttcn {
       error("Could not determine the assignment for second parameter");
       goto error;
     }
-    if (Type::T_ENUM_T != convert_op.ref->chk_variable_ref()->get_type_refd_last()->get_typetype_ttcn3()) {
-      convert_op.ref->error("A reference to variable or value parameter of "
-        "type enumerated was expected");
-      goto error;
+    {
+      Type* t = convert_op.ref->chk_variable_ref()->get_type_refd_last();
+      Type::typetype_t tt = t->get_typetype_ttcn3();
+      if (Type::T_ENUM_T != tt) {
+        if (Type::T_CHOICE_T == tt) {
+          CompField* def_alt = t->get_default_alternative();
+          if (def_alt != NULL) {
+            Error_Context cntxt2(convert_op.ref, "Using default alternative `%s' in value of union type `%s'",
+              def_alt->get_name().get_dispname().c_str(), t->get_typename().c_str());
+            convert_op.ref->use_default_alternative(def_alt->get_name());
+            chk_int2enum();
+            return;
+          }
+        }
+        convert_op.ref->error("A reference to variable or value parameter of "
+          "type enumerated was expected");
+        goto error;
+      }
     }
     return;
   error:
@@ -5953,6 +5967,18 @@ error:
         }
       }
       break;
+    case Type::T_CHOICE_T: 
+      if (v->is_ref()) {
+        CompField* def_alt = ret_val->get_default_alternative();
+        Reference* ttcn_ref = dynamic_cast<Reference*>(v->get_reference());
+        if (def_alt != NULL && ttcn_ref != NULL) {
+          Error_Context cntxt(v, "Using default alternative `%s' in value of union type `%s'",
+            def_alt->get_name().get_dispname().c_str(), ret_val->get_typename().c_str());
+          ttcn_ref->use_default_alternative(def_alt->get_name());
+          return chk_comp_ref(p_val, allow_mtc, allow_system, p_any_from);
+        }
+      }
+      break;
     default:
       break;
     }
diff --git a/compiler2/ttcn3/TtcnTemplate.cc b/compiler2/ttcn3/TtcnTemplate.cc
index a1c734238f80e97f595fcdbd1d6bed37b197713a..808d039d02697c5b93446c3982573e75e1dcc954 100644
--- a/compiler2/ttcn3/TtcnTemplate.cc
+++ b/compiler2/ttcn3/TtcnTemplate.cc
@@ -42,7 +42,8 @@ namespace Ttcn {
   Template::Template(const Template& p) : GovernedSimple(p),
     templatetype(p.templatetype), my_governor(p.my_governor),
     is_ifpresent(p.is_ifpresent), specific_value_checked(false),
-    has_permutation(p.has_permutation), base_template(p.base_template)
+    has_permutation(p.has_permutation), flattened(p.flattened),
+    base_template(p.base_template)
   {
     switch (templatetype) {
     case TEMPLATE_ERROR:
@@ -1431,6 +1432,27 @@ namespace Ttcn {
       return 0;
     } else return u.templates->get_t_byIndex(n);
   }
+  
+  void Template::use_default_alternative(Type* p_union_type)
+  {
+    if (templatetype == TEMPLATE_ERROR) {
+      return;
+    }
+    CompField* def_alt = p_union_type->get_default_alternative();
+    if (def_alt == NULL) {
+      FATAL_ERROR("Value::use_default_alternative");
+    }
+    Template* def_temp = clone();
+    def_temp->my_governor = def_alt->get_type();
+    def_temp->set_my_scope(my_scope);
+    def_temp->set_fullname(get_fullname() + ".<default_alternative>");
+    clean_up();
+    NamedTemplate* nt = new NamedTemplate(def_alt->get_name().clone(), def_temp);
+    templatetype = NAMED_TEMPLATE_LIST;
+    u.named_templates = new NamedTemplates;
+    u.named_templates->add_nt(nt);
+    my_governor = p_union_type;
+  }
 
   /** \todo revise and merge with get_template_refd() */
   Template* Template::get_template_refd_last(ReferenceChain *refch)
@@ -2989,6 +3011,17 @@ end:
             delete new_templates; // cannot flatten at compile time
             new_templates = 0;
             break;
+          case Common::Type::T_CHOICE_T: {
+            CompField* def_alt = type->get_default_alternative();
+            Ttcn::Reference* ttcn_ref = dynamic_cast<Ttcn::Reference*>(ref);
+            if (def_alt != NULL && ttcn_ref != NULL) {
+              Error_Context cntxt(t, "Using default alternative `%s' in template of union type `%s'",
+                def_alt->get_name().get_dispname().c_str(), type->get_typename().c_str());
+              ttcn_ref->use_default_alternative(def_alt->get_name());
+              delete new_templates;
+              return harbinger(t, from_permutation, killer);
+            }
+            /* otherwise fall through */ }
           default: {
             // not an array type => error
             const char* ass_name = ass->get_assname();
@@ -3028,6 +3061,7 @@ end:
             }
             type->error("%s of type `%s' can not be used as target of 'all from'",
               descr.c_str(), type->get_typename().c_str());
+            delete new_templates;
             break; }
           }
         } // switch(typetype)
@@ -4066,10 +4100,10 @@ end:
         char* str_set_size = NULL;
         char* str_preamble = NULL;
         char* str_body = NULL;
-        string counter = get_temporary_id();
+        string counter_str = get_temporary_id();
         
         if (has_permutation || has_allfrom()) {
-          str_body = mputprintf(str_body, "int %s = %lld;\n", counter.c_str(), index_offset);
+          str_body = mputprintf(str_body, "int %s = %lld;\n", counter_str.c_str(), index_offset);
           for (size_t i = 0; i < nof_ts; ++i) {
             Template *t = u.templates->get_t_byIndex(i);
             if (t->templatetype == ALL_FROM) {
@@ -4172,16 +4206,16 @@ end:
                 "for (int i_i = 0, i_lim = %s.n_elem(); i_i < i_lim; ++i_i) {\n",
                 expr.expr);
               str_body = t->generate_code_init_seof_element(str_body, name,
-                (counter + " + i_i").c_str(),
+                (counter_str + " + i_i").c_str(),
                 oftype_name_str);
               str_body = mputstrn(str_body, "}\n", 2);
-              str_body = mputprintf(str_body, "%s += %s.n_elem();\n", counter.c_str(), expr.expr);
+              str_body = mputprintf(str_body, "%s += %s.n_elem();\n", counter_str.c_str(), expr.expr);
               Code::free_expr(&expr);
               t->set_code_generated();
             } else if (t->templatetype == PERMUTATION_MATCH) {
               string permutation_start = get_temporary_id();
               str_body = mputprintf(str_body, "int %s = %s;\n",
-                permutation_start.c_str(), counter.c_str());
+                permutation_start.c_str(), counter_str.c_str());
               size_t nof_perm_ts = t->u.templates->get_nof_ts();
               for (size_t j = 0; j < nof_perm_ts; j++) {
                 Template *subt = t->u.templates->get_t_byIndex(j);
@@ -4240,7 +4274,7 @@ end:
                 } else {
                   fixed_part++;
                   str_body = subt->generate_code_init_seof_element(str_body, name,
-                    counter.c_str(), oftype_name_str);
+                    counter_str.c_str(), oftype_name_str);
                 }
                 
                 if (subt->templatetype == ALL_FROM) {
@@ -4294,29 +4328,29 @@ end:
                     expr.expr);
 
                   str_body = subt->generate_code_init_seof_element(str_body, name,
-                    (counter + " + i_i").c_str(),
+                    (counter_str + " + i_i").c_str(),
                     oftype_name_str);
 
                   str_body = mputstrn(str_body, "}\n", 2);
-                  str_body = mputprintf(str_body, "%s += %s.n_elem();\n", counter.c_str(), expr.expr);
+                  str_body = mputprintf(str_body, "%s += %s.n_elem();\n", counter_str.c_str(), expr.expr);
                   Code::free_expr(&expr);
                 }
                 else {
                   str_body = subt->generate_code_init_seof_element(str_body, name,
-                    counter.c_str(), oftype_name_str);
-                  str_body = mputprintf(str_body, "%s++;\n", counter.c_str());
+                    counter_str.c_str(), oftype_name_str);
+                  str_body = mputprintf(str_body, "%s++;\n", counter_str.c_str());
                 }
                   
               }
               // do not consider index_offset in case of permutation indicators
               str_body = mputprintf(str_body, "%s.add_permutation(%s-%lld, %s-%lld-1);\n", name,
-                permutation_start.c_str(), index_offset, counter.c_str(), index_offset);
+                permutation_start.c_str(), index_offset, counter_str.c_str(), index_offset);
               t->set_code_generated();
             } else {
               fixed_part++;
               str_body = t->generate_code_init_seof_element(str_body, name,
-                      counter.c_str(), oftype_name_str);
-              str_body = mputprintf(str_body, "%s++;\n", counter.c_str());
+                      counter_str.c_str(), oftype_name_str);
+              str_body = mputprintf(str_body, "%s++;\n", counter_str.c_str());
             }
           }
           str = mputstr(str, str_preamble);
diff --git a/compiler2/ttcn3/TtcnTemplate.hh b/compiler2/ttcn3/TtcnTemplate.hh
index 8681438994e3ca0b1f8d67a567340dfb819baec1..4fd69e2e8180921b285dbf69b69bcb5fa347b618 100644
--- a/compiler2/ttcn3/TtcnTemplate.hh
+++ b/compiler2/ttcn3/TtcnTemplate.hh
@@ -296,6 +296,14 @@ namespace Ttcn {
      * PERMUTATION_MATCH constructs are also counted. */
     Template *get_listitem_byIndex(size_t n) const;
 
+    /** Converts the template into a named template list, with one element that
+      * has the union type's @default alternative as its name and the original template (cloned)
+      * as its value.
+      * Used when a template of a different type appears in a context, where a template of
+      * the specified union type was expected.
+      * This attempts to use the template as the union's default alternative instead. */
+    void use_default_alternative(Type* p_union_type);
+    
     Template* get_template_refd_last(ReferenceChain *refch=0);
     Template* get_refd_sub_template(Ttcn::FieldOrArrayRefs *subrefs,
                                     bool usedInIsbound,
diff --git a/compiler2/ttcn3/compiler.l b/compiler2/ttcn3/compiler.l
index 56afedbbb9a5950a7c041b69d3f09b0c2897ad67..b4ddd18e95413e6d9ee67e54c17324d9eac4ccd3 100644
--- a/compiler2/ttcn3/compiler.l
+++ b/compiler2/ttcn3/compiler.l
@@ -630,6 +630,7 @@ object {
 "@local"         RETURN(LocalKeyword);
 "@final"         RETURN(FinalKeyword);
 "@abstract"      RETURN(AbstractKeyword);
+"@default"       RETURN(DefaultModifier);
 
   /* special TITAN specific keywords */
 
diff --git a/compiler2/ttcn3/compiler.y b/compiler2/ttcn3/compiler.y
index 9f5c4a18adab05472fbfe0710f7c47bb98a8fc53..7ec431d7893f28df167ebc8edc045dd2619af48b 100644
--- a/compiler2/ttcn3/compiler.y
+++ b/compiler2/ttcn3/compiler.y
@@ -821,6 +821,7 @@ static const string anyname("anytype");
 %token LocalKeyword
 %token FinalKeyword
 %token AbstractKeyword
+%token DefaultModifier
 
 /* TITAN specific keywords */
 %token TitanSpecificTryKeyword
@@ -957,7 +958,7 @@ static const string anyname("anytype");
 
 %type <bool_val> optAliveKeyword optOptionalKeyword
   optErrValueRaw optAllKeyword optDeterministicModifier optRealtimeClause
-  optExtKeyword optFinalModifier optAbstractModifier
+  optExtKeyword optFinalModifier optAbstractModifier optDefaultModifier
 %type <str> FreeText optLanguageSpec PatternChunk PatternChunkList
 %type <uchar_val> Group Plane Row Cell
 %type <id> FieldReference GlobalModuleId
@@ -2634,25 +2635,30 @@ UnionFieldDefList:
 | error { $$ = new CompFieldMap; }
 ;
 
+optDefaultModifier:
+  /* empty */     { $$ = false; }
+| DefaultModifier { $$ = true; }
+;
+
 UnionFieldDef: // 34
-  TypeOrNestedTypeDef IDentifier optArrayDef optSubTypeSpec
+  optDefaultModifier TypeOrNestedTypeDef IDentifier optArrayDef optSubTypeSpec
   {
-    if ($4) {
+    if ($5) {
       /* The subtype constraint belongs to the innermost embedded type of
        * possible nested 'record of' or 'set of' constructs. */
-      Type *t = $1;
+      Type *t = $2;
       while (t->is_seof()) t = t->get_ofType();
-      t->set_parsed_restrictions($4);
+      t->set_parsed_restrictions($5);
     }
-    Type *type = $1;
+    Type *type = $2;
     /* creation of array type(s) if necessary (from right to left) */
-    for (size_t i = $3.nElements; i > 0; i--) {
-      type = new Type(Type::T_ARRAY, type, $3.elements[i - 1], true);
-      type->set_location(*$1);
+    for (size_t i = $4.nElements; i > 0; i--) {
+      type = new Type(Type::T_ARRAY, type, $4.elements[i - 1], true);
+      type->set_location(*$2);
     }
-    Free($3.elements);
-    $$ = new CompField($2, type, false);
-    $$->set_location(infile, @$);
+    Free($4.elements);
+    $$ = new CompField($3, type, false, 0, $1);
+    $$->set_location(infile, $1 ? @1 : @2, @5);
   }
 ;
 
diff --git a/compiler2/vector.hh b/compiler2/vector.hh
index 25017e827222e127258442626d6021fc5f9c5e42..ff992570ab0c4701f676eb128fe9f7189a0b19dd 100644
--- a/compiler2/vector.hh
+++ b/compiler2/vector.hh
@@ -129,6 +129,29 @@ public:
     num_e++;
     e_ptr[0] = elem;
   }
+  
+  /** Inserts the elem to a specified position in the vector. */
+  void insert(T* elem, size_t pos) {
+    if (e_ptr == NULL) {
+      e_ptr = static_cast<T**>(Malloc(initial_size * sizeof(*e_ptr)));
+    }
+    else {
+      size_t max_e = initial_size;
+      while (max_e < num_e) {
+        max_e *= increment_factor;
+      }
+      if (max_e <= num_e) {
+        if (max_e >= max_vector_length / increment_factor) {
+          FATAL_ERROR("vector::insert(): vector index overflow");
+        }
+        e_ptr = static_cast<T**>
+          (Realloc(e_ptr, max_e * increment_factor * sizeof(*e_ptr)));
+      }
+    }
+    memmove(e_ptr + pos + 1, e_ptr + pos, (num_e - pos) * sizeof(*e_ptr));
+    num_e++;
+    e_ptr[pos] = elem;
+  }
 
   /** Returns the <em>n</em>th element. The index of the first element is
    * zero. If no such index, then FATAL_ERROR occurs. */
diff --git a/function_test/Semantic_Analyser/Makefile.semantic b/function_test/Semantic_Analyser/Makefile.semantic
index e36e6ad41ec9a8bde4d211dab3ec5d02801c5be0..f1c85fadf4e7ec6b2ad3bac05acc81c7ab3a1af9 100644
--- a/function_test/Semantic_Analyser/Makefile.semantic
+++ b/function_test/Semantic_Analyser/Makefile.semantic
@@ -16,7 +16,7 @@ include ../../Makefile.personal
 
 SADIRS := ver param template any_from pattern_ref float recof_index \
 port_translation mtc_and_system_clause port_map_connect deterministic invoking_function_from_specific_places \
-json realtime map_param oop
+json realtime map_param oop defaultAlternative
 ifdef RT2
 SADIRS += deprecated erroneous_attributes template_concat
 endif
diff --git a/function_test/Semantic_Analyser/TTCN3_SA_5_TD.script b/function_test/Semantic_Analyser/TTCN3_SA_5_TD.script
index e8f6ef574ddc03e008d1ecf3b166debd1cb4ec09..d2eb3ece9e487c0d7b6adc8dd4bdb0b35bf87285 100644
--- a/function_test/Semantic_Analyser/TTCN3_SA_5_TD.script
+++ b/function_test/Semantic_Analyser/TTCN3_SA_5_TD.script
@@ -4080,12 +4080,9 @@ template boolean b3 := b1 @> 1
 }
 <END_MODULE>
 <RESULT COUNT 2>
-(?im)operand.+?should.+?be.+?string.+?value
-<END_RESULT>
-<RESULT COUNT 2>
 (?im)reference.+?to.+?value.+?expected.+?instead.+?of.+?template
 <END_RESULT>
-<RESULT COUNT 4>
+<RESULT COUNT 2>
 (?is)\berror:
 <END_RESULT>
 <RESULT>
@@ -4726,15 +4723,12 @@ template rtype	r3 := r1 & r2
 }
 <END_MODULE>
 <RESULT LTRT COUNT 2>
-(?im)operand.+?should.+?be.+?string.+?value
-<END_RESULT>
-<RESULT LTRT COUNT 2>
 (?im)reference.+?to.+?value.+?expected.+?instead.+?of.+?template
 <END_RESULT>
 <RESULT FTRT COUNT 2>
 (?im)Templates.+?of.+?type.+?`@Temp.rtype'.+?cannot.+?be.+?concatenated
 <END_RESULT>
-<RESULT LTRT COUNT 4>
+<RESULT LTRT COUNT 2>
 (?is)\berror:
 <END_RESULT>
 <RESULT FTRT COUNT 2>
@@ -4852,12 +4846,9 @@ template utype	u3 := u1 @> 1
 }
 <END_MODULE>
 <RESULT COUNT 2>
-(?im)operand.+?should.+?be.+?string.+?value
-<END_RESULT>
-<RESULT COUNT 2>
 (?im)reference.+?to.+?value.+?expected.+?instead.+?of.+?template
 <END_RESULT>
-<RESULT COUNT 4>
+<RESULT COUNT 2>
 (?is)\berror:
 <END_RESULT>
 <RESULT>
diff --git a/function_test/Semantic_Analyser/defaultAlternative/.gitignore b/function_test/Semantic_Analyser/defaultAlternative/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e2d293255e6d2f314e34950e486a48630d873491
--- /dev/null
+++ b/function_test/Semantic_Analyser/defaultAlternative/.gitignore
@@ -0,0 +1,2 @@
+!Makefile
+!*.ttcn
diff --git a/function_test/Semantic_Analyser/defaultAlternative/Makefile b/function_test/Semantic_Analyser/defaultAlternative/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..064785297138a4348dad364eab61948e5f3053df
--- /dev/null
+++ b/function_test/Semantic_Analyser/defaultAlternative/Makefile
@@ -0,0 +1,12 @@
+##############################################################################
+# Copyright (c) 2000-2020 Ericsson Telecom AB
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+#
+# Contributors:
+#   Baranyi, Botond
+#
+##############################################################################
+include ../common.mk
diff --git a/function_test/Semantic_Analyser/defaultAlternative/defaultAlternative_SE.ttcn b/function_test/Semantic_Analyser/defaultAlternative/defaultAlternative_SE.ttcn
new file mode 100644
index 0000000000000000000000000000000000000000..f75040b76c617c0790393058a298aede1a0457d1
--- /dev/null
+++ b/function_test/Semantic_Analyser/defaultAlternative/defaultAlternative_SE.ttcn
@@ -0,0 +1,37 @@
+/******************************************************************************
+ * Copyright (c) 2000-2020 Ericsson Telecom AB
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+ *
+ * Contributors:
+ *   Baranyi, Botond
+ *
+ ******************************************************************************/
+
+module defaultAlternative_SE { //^In TTCN-3 module//
+
+type union MyDefaultUnionType {
+  @default integer number,
+  charstring string //Field `string' of the default alternative is here//
+}
+
+type union MyDefaultUnionType2 {
+  @default MyDefaultUnionType ageInYears, //Field `ageInYears' of the default alternative is here//
+  integer ageInDays
+}
+
+type union MyUnionTypeWithDefaultErr { //^In type definition//
+  @default //Duplicate union field name `ageInYears'//
+  MyDefaultUnionType2 ageInYears,
+  charstring string //Duplicate union field name `string'//
+}
+
+type union MyUnionTypeWithTwoDefaults { //^In type definition//
+  @default integer number, //The `@default' modifier was already used here//
+  charstring string,
+  @default octetstring bytes //Multiple union fields defined with the `@default' modifier//
+}
+
+}
diff --git a/function_test/Semantic_Analyser/defaultAlternative/t b/function_test/Semantic_Analyser/defaultAlternative/t
new file mode 100755
index 0000000000000000000000000000000000000000..3a4b58ec16cf2f1390a36c7a92f8823e3b94b425
--- /dev/null
+++ b/function_test/Semantic_Analyser/defaultAlternative/t
@@ -0,0 +1,9 @@
+#!/usr/bin/perl
+# note this is called through "perl -w"
+use strict;
+
+my $self = $0;
+$self =~ s!/t!!;
+
+exec('make check --no-print-directory -s -C ' . $self);
+
diff --git a/function_test/Semantic_Analyser/template/TempNoDefaultOrPort_SE.ttcn b/function_test/Semantic_Analyser/template/TempNoDefaultOrPort_SE.ttcn
index 499e6d66227facd56d8f1cf35f388dd911f1ca7e..0171c1ff1aa5f1556fbc2c0e19749861c9b0b588 100644
--- a/function_test/Semantic_Analyser/template/TempNoDefaultOrPort_SE.ttcn
+++ b/function_test/Semantic_Analyser/template/TempNoDefaultOrPort_SE.ttcn
@@ -46,4 +46,4 @@ type record MyRecordDefault { //In type \`\@TempNoDefaultOrPort\_SE\.MyRecordDef
 
 } with {
   extension "anytype MyRecordDefault2" //In field \`MyRecordDefault2\'\://
-}
\ No newline at end of file
+}
diff --git a/regression_test/Makefile b/regression_test/Makefile
index d863ec973f1716889efcaa208e8dac18934b6dc6..2b62cc01d5d255ea551bf3913ec7ad9215678616 100644
--- a/regression_test/Makefile
+++ b/regression_test/Makefile
@@ -50,7 +50,7 @@ customEncoding makefilegen uidChars checkstate hostid templateIstemplatekind \
 selectUnion templateExclusiveRange any_from templatePatternRef indexWithRecofArray \
 connectMapOperTest fuzzy portTranslation ischosen functionSubref done \
 nondeterministicDefaultParam predefFunction2 realtime portTranslationCentralStorage \
-locale oop references unicharstrToCharstr
+locale oop references unicharstrToCharstr defaultAlternative
 
 ifdef DYN
 DIRS += loggerplugin junitlogger 
diff --git a/regression_test/defaultAlternative/.gitignore b/regression_test/defaultAlternative/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..126ab1ca4c4c18dd05205616eff3186ee6390871
--- /dev/null
+++ b/regression_test/defaultAlternative/.gitignore
@@ -0,0 +1,5 @@
+defaultAlternative
+defaultAlternative.exe
+defaultAlternative*.cc
+defaultAlternative*.hh
+defaultAlternative*.log
diff --git a/regression_test/defaultAlternative/Makefile b/regression_test/defaultAlternative/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..fc8e5701d783e5496c838150fce040adf3b73e24
--- /dev/null
+++ b/regression_test/defaultAlternative/Makefile
@@ -0,0 +1,56 @@
+##############################################################################
+# Copyright (c) 2000-2020 Ericsson Telecom AB
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+#
+# Contributors:
+#   Baranyi, Botond
+#
+##############################################################################
+TOPDIR := ..
+include $(TOPDIR)/Makefile.regression
+
+.SUFFIXES: .ttcn .hh
+.PHONY: all clean dep run
+
+TTCN3_LIB = ttcn3$(RT2_SUFFIX)-parallel$(DYNAMIC_SUFFIX)
+
+TTCN3_MODULES = defaultAlternative.ttcn
+
+GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc)
+GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh)
+ifdef CODE_SPLIT
+GENERATED_SOURCES := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), .cc _seq.cc _set.cc  _seqof.cc _setof.cc _union.cc))
+else ifdef SPLIT_TO_SLICES
+POSTFIXES := $(foreach file, $(SPLIT_TO_SLICES), $(addsuffix $(file), _part_))
+POSTFIXES := $(foreach file, $(POSTFIXES), $(addprefix $(file), .cc))
+GENERATED_SOURCES2 := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), $(POSTFIXES)))
+GENERATED_SOURCES += $(GENERATED_SOURCES2)
+endif
+
+OBJECTS = $(GENERATED_SOURCES:.cc=.o)
+
+TARGET = defaultAlternative$(EXESUFFIX)
+
+all: $(TARGET)
+
+$(TARGET): $(GENERATED_SOURCES) $(USER_SOURCES)
+	$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ -L$(TTCN3_DIR)/lib -l$(TTCN3_LIB) -L$(OPENSSL_DIR)/lib -lcrypto $($(PLATFORM)_LIBS)
+
+.ttcn.cc .ttcn.hh:
+	$(TTCN3_COMPILER) $<
+
+clean distclean:
+	-rm -f $(TARGET) $(OBJECTS) $(GENERATED_HEADERS) \
+	$(GENERATED_SOURCES) *.log Makefile.bak
+
+dep: $(GENERATED_SOURCES)
+	makedepend $(CPPFLAGS) $(GENERATED_SOURCES)
+
+run: $(TARGET)
+	ttcn3_start $(TARGET) config.cfg
+
+.NOTPARALLEL:
+
diff --git a/regression_test/defaultAlternative/config.cfg b/regression_test/defaultAlternative/config.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..e9f0745a7b6c56b05c0e6d5b3306ede9dbf5b29d
--- /dev/null
+++ b/regression_test/defaultAlternative/config.cfg
@@ -0,0 +1,18 @@
+###############################################################################
+# Copyright (c) 2000-2020 Ericsson Telecom AB
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+#
+# Contributors:
+#   Baranyi, Botond
+#
+###############################################################################
+[MODULE_PARAMETERS]
+[LOGGING]
+Logfile := "defaultAlternative.log"
+FileMask := LOG_ALL
+ConsoleMask := TTCN_WARNING | TTCN_ERROR | TTCN_TESTCASE | TTCN_STATISTICS
+[EXECUTE]
+defaultAlternative
diff --git a/regression_test/defaultAlternative/defaultAlternative.ttcn b/regression_test/defaultAlternative/defaultAlternative.ttcn
new file mode 100644
index 0000000000000000000000000000000000000000..6cbae29a067cc8d9e307f46a079c560feecabd32
--- /dev/null
+++ b/regression_test/defaultAlternative/defaultAlternative.ttcn
@@ -0,0 +1,800 @@
+/******************************************************************************
+ * Copyright (c) 2000-2020 Ericsson Telecom AB
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+ *
+ * Contributors:
+ *   Baranyi, Botond
+ *
+ ******************************************************************************/
+
+module defaultAlternative {
+
+type record Rec {
+  integer num,
+  charstring str optional
+}
+with {
+  encode "JSON";
+}
+
+type record of integer RecOf;
+
+type enumerated Enum { first (0), second };
+
+type union Uni {
+  integer num,
+  charstring str
+}
+
+type union UniDefInt {
+  @default integer def,
+  charstring str
+}
+
+type union UniDefStr {
+  @default charstring def,
+  integer num
+}
+
+type union UniDefRec {
+  @default Rec def,
+  boolean bool
+}
+
+type union UniDefRecOf {
+  boolean bool,
+  @default RecOf def
+}
+
+type union UniDefUni {
+  boolean bool,
+  @default Uni def
+}
+
+type union UniDefIntEmb {
+  @default UniDefInt def2,
+  octetstring oct
+}
+
+type union UniDefIntDblEmb {
+  @default UniDefIntEmb def3,
+  Rec rec
+}
+
+type union UniWithDefStr {
+  UniDefStr uni,
+  octetstring oct
+}
+
+type union UniDefStrEmbBroken {
+  @default UniWithDefStr def2,
+  boolean bool
+}
+
+type union UniDefBool {
+  @default boolean def,
+  integer num
+}
+
+type union UniDefBit {
+  @default bitstring def,
+  integer num
+}
+
+type union UniDefEnum {
+  @default Enum def
+}
+
+type union UniDefFloat {
+  @default float def
+}
+
+type union UniDefHex {
+  @default hexstring def
+}
+
+type union UniDefOct {
+  @default octetstring def
+}
+
+type union UniDefUstr {
+  @default universal charstring def
+}
+
+type union UniDefVerdict {
+  @default verdicttype def
+}
+
+type union UniDefComp {
+  @default CT def
+}
+
+type port PT message {
+  inout integer
+}
+with { extension "internal" }
+
+type component CT {
+  timer tmr_comp;
+  port PT pt;
+}
+
+type union UniDefDef {
+  @default default def
+}
+
+testcase tc_init_and_assign() runs on CT {
+  var UniDefInt u1 := 3;
+  if (u1.def != 3) {
+    setverdict(fail, "u1: ", u1);
+  }
+  
+  var UniDefStr u2;
+  u2 := "abc";
+  if (u2.def != "abc") {
+    setverdict(fail, "u2: ", u2);
+  }
+
+  var UniDefRec u3 := { num := 4, str := "xy" };
+  if (u3.def != { num := 4, str := "xy" }) {
+    setverdict(fail, "u3: ", u3);
+  }
+  
+  u3.num := 5;
+  if (u3.def != { num := 5, str := "xy" }) {
+    setverdict(fail, "u3 mod: ", u3);
+  }
+  
+  var UniDefRecOf u4 := { 1, 2, 3 };
+  if (u4.def != { 1, 2, 3}) {
+    setverdict(fail, "u4: ", u4);
+  }
+  
+  u4[2] := 4;
+  if (u4.def != { 1, 2, 4}) {
+    setverdict(fail, "u4 mod: ", u4);
+  }
+  
+  var UniDefUni u5 := { str := "def" };
+  if (u5.def.str != "def") {
+    setverdict(fail, "u5: ", u5);
+  }
+  
+  u5.num := 0;
+  if (u5.def.num != 0) {
+    setverdict(fail, "u5 mod: ", u5);
+  }
+
+  var UniDefIntEmb u6 := 2;
+  if (u6.def2.def != 2) {
+    setverdict(fail, "u6: ", u6);
+  }
+  
+  var UniDefIntDblEmb u7 := 1;
+  if (u7.def3.def2.def != 1) {
+    setverdict(fail, "u7: ", u7);
+  }
+  
+  var UniDefStrEmbBroken u8;
+  u8.uni := "ghi";
+  if (u8.def2.uni.def != "ghi") {
+    setverdict(fail, "u8: ", u8);
+  }
+  
+  var UniDefEnum u9 := first;
+  if (u9.def != first) {
+    setverdict(fail, "u9: ", u9);
+  }
+  u9 := second;
+  if (u9.def != second) {
+    setverdict(fail, "u9 mod: ", u9);
+  }
+  
+  var template UniDefInt tu1 := 3;
+  var template UniDefInt tu1_exp := { def := 3 };
+  if (log2str(tu1) != log2str(tu1_exp)) {
+    setverdict(fail, "tu1: ", tu1);
+  }
+  
+  var template UniDefInt tu2 := (0..4);
+  var template UniDefInt tu2_exp := { def := (0..4) };
+  if (log2str(tu2) != log2str(tu2_exp)) {
+    setverdict(fail, "tu2: ", tu2);
+  }
+  
+  var template UniDefIntEmb tu3 := (1, 2, 3, (6..10));
+  var template UniDefIntEmb tu3_exp := (
+    { def2 := { def := 1 } },
+    { def2 := { def := 2 } },
+    { def2 := { def := 3 } },
+    { def2 := { def := (6 .. 10) } }
+  );
+  if (log2str(tu3) != log2str(tu3_exp)) {
+    setverdict(fail, "tu3: ", tu3);
+  }
+  
+  var template UniDefStr tu4 := "abc";
+  var template UniDefStr tu4_exp := { def := "abc" };
+  if (log2str(tu4) != log2str(tu4_exp)) {
+    setverdict(fail, "tu4: ", tu4);
+  }
+  tu4[1] := "z";
+  tu4_exp.def[1] := "z";
+  if (log2str(tu4) != log2str(tu4_exp)) {
+    setverdict(fail, "tu4 mod: ", tu4);
+  }
+  
+  var template UniDefStr tu5;
+  tu5 := pattern "ab?c";
+  var template UniDefStr tu5_exp := { def := pattern "ab?c" };
+  if (log2str(tu5) != log2str(tu5_exp)) {
+    setverdict(fail, "tu5: ", tu5);
+  }
+  
+  var template UniDefRec tu6 := { num := 1, str := "xy" };
+  var template UniDefRec tu6_exp := { def := { num := 1, str := "xy" } };
+  if (log2str(tu6) != log2str(tu6_exp)) {
+    setverdict(fail, "tu6: ", tu6);
+  }
+  tu6.num := -6;
+  tu6_exp.def.num := -6;
+  if (log2str(tu6) != log2str(tu6_exp)) {
+    setverdict(fail, "tu6 mod: ", tu6);
+  }
+  
+  var template UniDefRec tu7 := { 1, "xy" };
+  var template UniDefRec tu7_exp := { def := { 1, "xy" } };
+  if (log2str(tu7) != log2str(tu7_exp)) {
+    setverdict(fail, "tu7: ", tu7);
+  }
+  
+  var template UniDefRecOf tu8 := { 1, 2, 3 };
+  var template UniDefRecOf tu8_exp := { def := { 1, 2, 3 } };
+  if (log2str(tu8) != log2str(tu8_exp)) {
+    setverdict(fail, "tu8: ", tu8);
+  }
+  tu8[1] := 22;
+  tu8_exp.def[1] := 22;
+  if (log2str(tu8) != log2str(tu8_exp)) {
+    setverdict(fail, "tu8 mod: ", tu8);
+  }
+  
+  var template UniDefRecOf tu9 := { [1] := 1, [0] := 0 };
+  var template UniDefRecOf tu9_exp := { def := { [1] := 1, [0] := 0 } };
+  if (log2str(tu9) != log2str(tu9_exp)) {
+    setverdict(fail, "tu9: ", tu9);
+  }
+  
+  var template UniDefUni tu10 := { str := "qwe" };
+  var template UniDefUni tu10_exp := { def := { str := "qwe" } };
+  if (log2str(tu10) != log2str(tu10_exp)) {
+    setverdict(fail, "tu10: ", tu10);
+  }
+  tu10.num := 2;
+  tu10_exp.def.num := 2;
+  if (log2str(tu10) != log2str(tu10_exp)) {
+    setverdict(fail, "tu10 mod: ", tu10);
+  }
+  
+  var template UniDefEnum tu11 := first;
+  var template UniDefEnum tu11_exp := { def := first };
+  if (log2str(tu11) != log2str(tu11_exp)) {
+    setverdict(fail, "tu11: ", tu11);
+  }
+  tu11 := second;
+  tu11_exp.def := second;
+  if (log2str(tu11) != log2str(tu11_exp)) {
+    setverdict(fail, "tu11 mod: ", tu11);
+  }
+  setverdict(pass);
+}
+
+testcase tc_ref() runs on CT {
+  var UniDefInt u1 := 1;
+  var integer i1 := u1;
+  if (i1 != 1) {
+    setverdict(fail, "i1: ", i1);
+  }
+  
+  var UniDefRec u2 := { num := 4, str := "xy" };
+  var charstring cs1 := u2.str;
+  if (cs1 != "xy") {
+    setverdict(fail, "cs1: ", cs1);
+  }
+  
+  var UniDefRecOf u3 := { 1, 2, 3 };
+  var integer i2 := u3[1];
+  if (i2 != 2) {
+    setverdict(fail, "i2: ", i2);
+  }
+  
+  var charstring cs2 := "abc";
+  var UniDefStr u4 := cs2;
+  if (u4.def != "abc") {
+    setverdict(fail, "u4: ", u4);
+  }
+  
+  var UniDefIntEmb u5 := u1;
+  if (u5.def2.def != 1) {
+    setverdict(fail, "u5: ", u5);
+  }
+  
+  var UniDefStrEmbBroken u6 := { uni := cs2 };
+  if (u6.def2.uni.def != "abc") {
+    setverdict(fail, "u6: ", u6);
+  }
+  
+  var template UniDefRecOf tu1 := { 1, 2, 3 };
+  var template integer ti1 := (0, all from tu1);
+  var template integer ti1_exp := (0, all from tu1.def);
+  if (log2str(ti1) != log2str(ti1_exp)) {
+    setverdict(fail, "ti1: ", ti1);
+  }
+  /*template UniDefRecOf tu2 := { 1, 2, 3 }; TODO
+  template integer ti2 := (0, all from tu2);
+  template integer ti2_exp := (0, all from tu2.def);
+  if (log2str(ti2) != log2str(ti2_exp)) {
+    setverdict(fail, "ti2: ", ti2);
+  }
+  var template UniDefInt tu3 := (0, all from tu1);
+  var template UniDefInt tu3_exp := (0, all from tu1.def);
+  if (log2str(tu3) != log2str(tu3_exp)) {
+    setverdict(fail, "tu3: ", tu3);
+  }*/
+  var template RecOf tro1 := { 0, permutation(all from tu1) };
+  var template RecOf tro1_exp := { 0, permutation(all from tu1.def) };
+  if (log2str(tro1) != log2str(tro1_exp)) {
+    setverdict(fail, "tro1: ", tro1);
+  }
+  setverdict(pass);
+}
+
+testcase tc_expr() runs on CT {
+  var UniDefInt u1 := 2;
+  var integer i1 := u1 + 1;
+  if (i1 != 3) {
+    setverdict(fail, "i1: ", i1);
+  }
+  
+  var UniDefInt u2 := 3;
+  var UniDefInt u3 := ((+u1 - -u2) * (u2 + -1)) / (5 rem u2 + u2 mod 4);
+  if (u3.def != 2) {
+    setverdict(fail, "u3: ", u3);
+  }
+  
+  var UniDefStr u4 := "xy";
+  var charstring cs1 := u4 & "a" & (u4 & u4) & "b" & u4;
+  if (cs1 != "xyaxyxybxy") {
+    setverdict(fail, "cs1: ", cs1);
+  }
+  
+  var UniDefRecOf u5 := { 1, 2, 3 };
+  var RecOf ro1 := u5 & { 0 } & (u5 & u5) & { 6 } & u5;
+  if (ro1 != { 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 6, 1, 2, 3}) {
+    setverdict(fail, "ro1: ", ro1);
+  }
+  
+  var integer i2 := 4;
+  var UniDefIntEmb u6 := 4;
+  if (not i2 == u6) {
+    setverdict(fail, "ref not equal");
+  }
+  if (u6 == u2) {
+    setverdict(fail, "ref equal");
+  }
+  if (i2 == u6 - 1) {
+    setverdict(fail, "expr not equal");
+  }
+  if (not u6 == u2 + 1) {
+    setverdict(fail, "ref equal");
+  }
+  if (i2 < u6) {
+    setverdict(fail, "less than");
+  }
+  if (u2 > u6) {
+    setverdict(fail, "greater than");
+  }
+  if (u6 <= u2) {
+    setverdict(fail, "less or equal");
+  }
+  if (u2 >= u6) {
+    setverdict(fail, "greater or equal");
+  }
+  
+  var UniDefBool u7 := true;
+  if (not u7) {
+    setverdict(fail, "not u7");
+  }
+  if (u7 and false) {
+    setverdict(fail, "and u7");
+  }
+  if (not (false or u7)) {
+    setverdict(fail, "or u7");
+  }
+  if (true xor u7) {
+    setverdict(fail, "xor u7");
+  }
+  
+  var UniDefBit u8 := '1100'B;
+  var bitstring bs1 := (((not4b u8) xor4b u8) and4b u8) or4b u8;
+  if (bs1 != '1100'B) {
+    setverdict(fail, "bs1: ", bs1);
+  }
+  
+  var bitstring bs2 := u8 << 2;
+  if (bs2 != '0000'B) {
+    setverdict(fail, "bs2: ", bs2);
+  }
+  var UniDefBit u9 := u8 >> u2;
+  if (u9.def != '0001'B) {
+    setverdict(fail, "u9: ", u9);
+  }
+  var bitstring bs3 := u8 <@ (u2 - 1);
+  if (bs3 != '0011'B) {
+    setverdict(fail, "bs3: ", bs3);
+  }
+  var UniDefBit u10 := u8 @> 1;
+  if (u10.def != '0110'B) {
+    setverdict(fail, "u10: ", u10);
+  }
+  var RecOf ro2 := u5 <@ 1;
+  if (ro2 != { 2, 3, 1 }) {
+    setverdict(fail, "ro2: ", ro2);
+  }
+  var RecOf ro3 := u5 @> 1;
+  if (ro3 != { 3, 1, 2 }) {
+    setverdict(fail, "ro3: ", ro3);
+  }
+  setverdict(pass);
+}
+
+testcase tc_predef_func() runs on CT {
+  var UniDefBit u1 := '1010'B;
+  var hexstring hs1 := bit2hex(u1);
+  if (hs1 != 'A'H) {
+    setverdict(fail, "hs1: ", hs1);
+  }
+  var octetstring os1 := bit2oct(u1);
+  if (os1 != '0A'O) {
+    setverdict(fail, "os1: ", os1);
+  }
+  var charstring cs1 := bit2str(u1);
+  if (cs1 != "1010") {
+    setverdict(fail, "cs1: ", cs1);
+  }
+  var integer i1 := bit2int(u1);
+  if (i1 != 10) {
+    setverdict(fail, "i1: ", i1);
+  }
+  
+  var UniDefStr u2 := "4";
+  var integer i2 := char2int(u2);
+  if (i2 != 52) {
+    setverdict(fail, "i2: ", i2);
+  }
+  var octetstring os2 := char2oct(u2);
+  if (os2 != '34'O) {
+    setverdict(fail, "os2: ", os2);
+  }
+  var integer i3 := str2int(u2);
+  if (i3 != 4) {
+    setverdict(fail, "i3: ", i3);
+  }
+  var float f1 := str2float(u2);
+  if (f1 != 4.0) {
+    setverdict(fail, "f1: ", f1);
+  }
+  var UniDefStr u3 := "10";
+  var bitstring bs1 := str2bit(u3);
+  if (bs1 != '10'B) {
+    setverdict(fail, "bs1: ", bs1);
+  }
+  var hexstring hs2 := str2hex(u2);
+  if (hs2 != '4'H) {
+    setverdict(fail, "hs2: ", hs2);
+  }
+  var octetstring os3 := str2oct(u3);
+  if (os3 != '10'O) {
+    setverdict(fail, "os3: ", os3);
+  }
+  
+  var UniDefEnum u4 := { def := first };
+  var integer i4 := enum2int(u4);
+  if (i4 != 0) {
+    setverdict(fail, "i4: ", i4);
+  }
+  
+  var UniDefFloat u5 := 3.0;
+  var integer i5 := float2int(u5);
+  if (i5 != 3) {
+    setverdict(fail, "i5: ", i5);
+  }
+  var charstring cs2 := float2str(u5);
+  if (cs2 != "3.000000") {
+    setverdict(fail, "cs2: ", cs2);
+  }
+  
+  var float f2 := rnd(u5);
+  
+  var UniDefHex u6 := '20'H;
+  var bitstring bs2 := hex2bit(u6);
+  if (bs2 != '00100000'B) {
+    setverdict(fail, "bs2: ", bs2);
+  }
+  var octetstring os4 := hex2oct(u6);
+  if (os4 != '20'O) {
+    setverdict(fail, "os4: ", os4);
+  }
+  var charstring cs3 := hex2str(u6);
+  if (cs3 != "20") {
+    setverdict(fail, "cs3: ", cs3);
+  }
+  var integer i6 := hex2int(u6);
+  if (i6 != 32) {
+    setverdict(fail, "i6: ", i6);
+  }
+  
+  var UniDefInt u7 := 65;
+  var charstring cs4 := int2char(u7);
+  if (cs4 != "A") {
+    setverdict(fail, "cs4: ", cs4);
+  }
+  var universal charstring us1 := int2unichar(u7);
+  if (us1 != "A") {
+    setverdict(fail, "us1: ", us1);
+  }
+  var float f3 := int2float(u7);
+  if (f3 != 65.0) {
+    setverdict(fail, "f3: ", f3);
+  }
+  var charstring cs5 := int2str(u7);
+  if (cs5 != "65") {
+    setverdict(fail, "cs5: ", cs4);
+  }
+  var bitstring bs3 := int2bit(u7, u7 / 8);
+  if (bs3 != '01000001'B) {
+    setverdict(fail, "bs3: ", bs3);
+  }
+  var hexstring hs3 := int2hex(u7, u7 / 30);
+  if (hs3 != '41'H) {
+    setverdict(fail, "hs3: ", hs3);
+  }
+  var octetstring os5 := int2oct(u7, u7 / 50);
+  if (os5 != '41'O) {
+    setverdict(fail, "os5: ", os5);
+  }
+  
+  var UniDefOct u8 := '20'O;
+  var bitstring bs4 := oct2bit(u8);
+  if (bs4 != '00100000'B) {
+    setverdict(fail, "bs4: ", bs4);
+  }
+  var hexstring hs4 := oct2hex(u8);
+  if (hs4 != '20'H) {
+    setverdict(fail, "hs4: ", hs4);
+  }
+  var charstring cs6 := oct2str(u8);
+  if (cs6 != "20") {
+    setverdict(fail, "cs6: ", cs6);
+  }
+  var integer i7 := oct2int(u8);
+  if (i7 != 32) {
+    setverdict(fail, "i7: ", i7);
+  }
+  var charstring cs7 := oct2char(u8);
+  if (cs7 != " ") {
+    setverdict(fail, "cs7: ", cs7);
+  }
+  
+  var UniDefUstr u9 := "a";
+  var integer i8 := unichar2int(u9);
+  if (i8 != 97) {
+    setverdict(fail, "i8: ", i8);
+  }
+  var charstring cs8 := unichar2char(u9);
+  if (cs8 != "a") {
+    setverdict(fail, "cs8: ", cs8);
+  }
+  
+  var UniDefStr u10 := "AnyValue";
+  var template integer t := ?;
+  if (not istemplatekind(t, u10)) {
+    setverdict(fail, "istemplatekind");
+  }
+  
+  var template UniDefStr u_str := "something";
+  var UniDefInt u_idx := 4;
+  var UniDefInt u_len := 3;
+  var UniDefStr u_substr := substr(u_str, u_idx, u_len);
+  if (u_substr.def != "thi") {
+    setverdict(fail, "substr: ", u_str);
+  }
+  
+  var template UniDefStr u_input := " date: 2001-10-20; msgno: 17; exp ";
+  var UniDefStr u_pattern := "[ \\t]#(,)date: [\\d\\-]#(,);[ \\t]#(,)msgno: (\\d#(1,3));[ \\t]#(,)(exp[ \\t]#(,))#(0,1)";
+  var UniDefInt u_groupno := 0;
+  var UniDefStr u_regexp := regexp(u_input, u_pattern, u_groupno);
+  if (u_regexp.def != "17") {
+    setverdict(fail, "regexp: ", u_regexp);
+  }
+  
+  var UniDefInt u_lengthof := lengthof(u_str);
+  if (u_lengthof.def != 9) {
+    setverdict(fail, "lengthof: ", u_lengthof);
+  }
+  
+  var UniDefRec u_rec := { num := 6, str := omit };
+  var UniDefInt u_sizeof := sizeof(u_rec);
+  if (u_sizeof.def != 1) {
+    setverdict(fail, "sizeof: ", u_sizeof);
+  }
+  var template UniDefRec u_rec_t := { num := 6, str := omit };
+  var UniDefInt u_sizeof2 := sizeof(u_rec_t);
+  if (u_sizeof2.def != 1) {
+    setverdict(fail, "sizeof temp: ", u_sizeof2);
+  }
+  
+  var template UniDefInt u_temp := (0..5);
+  var UniDefInt u_val := 3;
+  var template integer i_temp := (0..5);
+  var integer i_val := 3;
+  if (not match(i_val, u_temp)) {
+    setverdict(fail, "match int with union");
+  }
+  if (not match(u_val, i_temp)) {
+    setverdict(fail, "match union with int");
+  }
+  if (not match(u_val, u_temp)) {
+    setverdict(fail, "match union with union");
+  }
+  
+  var template UniDefStr u_str2 := "My name is JJ";
+  var UniDefInt u_idx2 := 11;
+  var UniDefInt u_len2 := 1;
+  var template UniDefStr u_repl := "xx";
+  var UniDefStr u_replace := replace(u_str2, u_idx2, u_len2, u_repl);
+  if (u_replace.def != "My name is xxJ") {
+    setverdict(fail, "replace: ", u_replace);
+  }
+  
+  var UniDefUni u_uni := { num := 6 };
+  if (not ischosen(u_uni.num)) {
+    setverdict(fail, "ischosen");
+  }
+  setverdict(pass);
+}
+
+testcase tc_encdec() runs on CT {
+  var Rec val := { num := 3, str := "abc" };
+  var UniDefStr str_enc := "UTF-8";
+  var UniDefUstr enc_info := "";
+  var UniDefUstr dyn_enc := "JSON";
+  var UniDefUstr buf := encvalue_unichar(val, str_enc, enc_info, dyn_enc);
+  if (buf.def != "{\"num\":3,\"str\":\"abc\"}") {
+    setverdict(fail, "encoded value: ", buf);
+  }
+  var Rec dec_val;
+  var UniDefInt res := decvalue_unichar(buf, dec_val, str_enc, enc_info, dyn_enc);
+  if (res.def != 0) {
+    setverdict(fail, "decoding result: ", res);
+  }
+  if (dec_val != val) {
+    setverdict(fail, "decoded value: ", dec_val);
+  }
+  setverdict(pass);
+}
+
+function f_behavior() runs on CT {
+}
+
+testcase tc_comp_and_port() runs on CT {
+  var UniDefComp u1 := CT.create;
+  
+  if (u1.running) {
+    setverdict(fail, "u1 running");
+  }
+  
+  if (not u1.alive) {
+    setverdict(fail, "u1 alive");
+  }
+  
+  var UniDefStr u2 := "Started";
+  if (not pt.checkstate(u2)) {
+    setverdict(fail, "checkstate");
+  }
+  if (not any port.checkstate(u2)) {
+    setverdict(fail, "any checkstate");
+  }
+  if (not all port.checkstate(u2)) {
+    setverdict(fail, "all checkstate");
+  }
+  
+  u1.start(f_behavior());
+  u1.stop;
+  u1.killed;
+  
+  setverdict(pass);
+}
+
+altstep as() runs on CT {
+  [] tmr_comp.timeout { setverdict(fail, "altstep is still active"); }
+}
+
+testcase tc_default_altstep() runs on CT {
+  timer tmr_local;
+  var UniDefDef u_def := activate(as());
+  deactivate(u_def);
+  tmr_comp.start(0.1);
+  tmr_local.start(2.0);
+  alt {
+    [] tmr_local.timeout { setverdict(pass); }
+  }
+}
+
+function f_func() return integer {
+  var UniDefInt x := 3;
+  return x;
+}
+
+type record RecEnc {
+  integer f
+}
+with {
+  encode "XML";
+  encode "JSON";
+}
+
+testcase tc_statements() runs on CT {
+  var UniDefInt ret_val := f_func();
+  if (ret_val.def != 3) {
+    setverdict(fail, "return value: ", ret_val);
+  }
+  
+  var UniDefBool u_bool := false;
+  while (u_bool) {
+    setverdict(fail, "while");
+    break;
+  }
+  
+  var UniDefStr u_text := "32";
+  var integer i;
+  string2ttcn(u_text, i);
+  if (i != 32) {
+    setverdict(fail, "string2ttcn: ", i);
+  }
+  var UniDefStr u_text_res := ttcn2string(i);
+  if (u_text_res.def != "32") {
+    setverdict(fail, "ttcn2string: ", u_text_res);
+  }
+  
+  var UniDefInt u_int := 1;
+  var UniDefEnum u_enum;
+  int2enum(u_int, u_enum);
+  if (u_enum.def != second) {
+    setverdict(fail, "int2enum: ", u_enum);
+  }
+  
+  var UniDefUstr u_enc := "JSON";
+  self.setencode(RecEnc, u_enc);
+  setverdict(pass);
+}
+
+testcase tc_setverdict() runs on CT {
+  var UniDefVerdict u_verdict := pass;
+  setverdict(u_verdict);
+}
+
+control {
+  execute(tc_init_and_assign());
+  execute(tc_ref());
+  execute(tc_expr());
+  execute(tc_predef_func());
+  execute(tc_comp_and_port());
+  execute(tc_statements());
+  execute(tc_setverdict());
+}
+
+}