diff --git a/compiler2/Setting.hh b/compiler2/Setting.hh
index e59ce8cb8fe9e7cc444b704cea2c6dc706535c7a..5eb2da254089d87d7b6b862d0d00a2b500d26fe3 100644
--- a/compiler2/Setting.hh
+++ b/compiler2/Setting.hh
@@ -448,9 +448,11 @@ public:
       CS_INIT_COMP, /**< Initialized with the component entities (i.e. when
                      * the component type is known). Example: initial value
 		     * for component variables, default duration for timers. */
-      CS_INLINE /**< Initialized immediately at the place of definition.
-                 * Applicable to local definitions only. Example: initial
-		 * value for a local variable. */
+      CS_INLINE, /**< Initialized immediately at the place of definition.
+                  * Applicable to local definitions only. Example: initial
+                  * value for a local variable. */
+      CS_INIT_CLASS /**< Initialized at the beginning of a class's constructor.
+                     * Example: class members */
     };
   private:
     /** A prefix that shall be inserted before the genname when initializing
diff --git a/compiler2/Type.hh b/compiler2/Type.hh
index 37f2e3cac3a54b780e1a1a8fad082b69a0a3edaf..49acabed9d9ef092e0398371f71169c5a5eeefd4 100644
--- a/compiler2/Type.hh
+++ b/compiler2/Type.hh
@@ -48,7 +48,8 @@ enum namedbool { INCOMPLETE_NOT_ALLOWED = 0, INCOMPLETE_ALLOWED = 1, WARNING_FOR
   ANY_OR_OMIT_NOT_ALLOWED = 0, ANY_OR_OMIT_ALLOWED = 5,
   NOT_IMPLICIT_OMIT = 0, IMPLICIT_OMIT = 6,
   NOT_STR_ELEM = 0, IS_STR_ELEM = 7,
-  ISBOUND = 8, ISPRESENT = 9, ISCHOSEN = 10, ISVALUE = 11
+  ISBOUND = 8, ISPRESENT = 9, ISCHOSEN = 10, ISVALUE = 11,
+  NOT_CLASS_MEMBER_INIT = 0, CLASS_MEMBER_INIT = 12
 };
 
 namespace Asn {
@@ -952,11 +953,13 @@ namespace Common {
       expected_value_t expected_value, namedbool incomplete_allowed,
       namedbool omit_allowed, namedbool sub_chk,
       namedbool implicit_omit = NOT_IMPLICIT_OMIT,
-      namedbool str_elem = NOT_STR_ELEM);
+      namedbool str_elem = NOT_STR_ELEM,
+      namedbool class_member_init = NOT_CLASS_MEMBER_INIT);
     /** Checks the given referenced value */
     bool chk_this_refd_value(Value *value, Common::Assignment *lhs,
       expected_value_t expected_value, ReferenceChain *refch=0,
-      namedbool str_elem = NOT_STR_ELEM);
+      namedbool str_elem = NOT_STR_ELEM,
+      namedbool class_member_init = NOT_CLASS_MEMBER_INIT);
     /** Checks the given invocation */
     void chk_this_invoked_value(Value *value, Common::Assignment *lhs,
       expected_value_t expected_value);
@@ -980,19 +983,24 @@ namespace Common {
       expected_value_t expected_value, namedbool incomplete_allowed,
       namedbool omit_allowed, namedbool sub_chk,
       namedbool implicit_omit = NOT_IMPLICIT_OMIT,
-      namedbool str_elem = NOT_STR_ELEM);
+      namedbool str_elem = NOT_STR_ELEM,
+      namedbool class_member_init = NOT_CLASS_MEMBER_INIT);
     bool chk_this_value_Se(Value *value, Common::Assignment *lhs,
       expected_value_t expected_value, namedbool incomplete_allowed,
-      namedbool implicit_omit = NOT_IMPLICIT_OMIT);
+      namedbool implicit_omit = NOT_IMPLICIT_OMIT,
+      namedbool class_member_init = NOT_CLASS_MEMBER_INIT);
     bool chk_this_value_Se_T(Value *value, Common::Assignment *lhs,
       expected_value_t expected_value, namedbool incomplete_allowed,
-      namedbool implicit_omit = NOT_IMPLICIT_OMIT);
+      namedbool implicit_omit = NOT_IMPLICIT_OMIT,
+      namedbool class_member_init = NOT_CLASS_MEMBER_INIT);
     bool chk_this_value_Seq_T(Value *value, Common::Assignment *lhs,
       expected_value_t expected_value, namedbool incomplete_allowed,
-      namedbool implicit_omit = NOT_IMPLICIT_OMIT);
+      namedbool implicit_omit = NOT_IMPLICIT_OMIT,
+      namedbool class_member_init = NOT_CLASS_MEMBER_INIT);
     bool chk_this_value_Set_T(Value *value, Common::Assignment *lhs,
       expected_value_t expected_value, namedbool incomplete_allowed,
-      namedbool implicit_omit = NOT_IMPLICIT_OMIT);
+      namedbool implicit_omit = NOT_IMPLICIT_OMIT,
+      namedbool class_member_init = NOT_CLASS_MEMBER_INIT);
     bool chk_this_value_Se_A(Value *value, Common::Assignment *lhs,
       expected_value_t expected_value, namedbool implicit_omit);
     bool chk_this_value_Seq_A(Value *value, Common::Assignment *lhs,
@@ -1001,14 +1009,16 @@ namespace Common {
       expected_value_t expected_value, namedbool implicit_omit);
     bool chk_this_value_SeOf(Value *value, Common::Assignment *lhs,
       expected_value_t expected_value, namedbool incomplete_allowed,
-      namedbool implicit_omit = NOT_IMPLICIT_OMIT);
+      namedbool implicit_omit = NOT_IMPLICIT_OMIT,
+      namedbool class_member_init = NOT_CLASS_MEMBER_INIT);
     void chk_this_value_Verdict(Value *value);
     void chk_this_value_Default(Value *value);
     bool chk_this_value_Array(Value *value, Common::Assignment *lhs,
       expected_value_t expected_value, namedbool incomplete_allowed,
-      namedbool implicit_omit);
+      namedbool implicit_omit, namedbool class_member_init = NOT_CLASS_MEMBER_INIT);
     bool chk_this_value_Signature(Value *value, Common::Assignment *lhs,
-      expected_value_t expected_value, namedbool incomplete_allowed);
+      expected_value_t expected_value, namedbool incomplete_allowed,
+      namedbool class_member_init = NOT_CLASS_MEMBER_INIT);
     void chk_this_value_Component(Value *value);
     void chk_this_value_FAT(Value *value);
     void chk_this_value_class(Value* value);
@@ -1025,19 +1035,19 @@ namespace Common {
     bool chk_this_template_ref_pard(Ttcn::Reference* ref_pard, Common::Assignment* lhs);
     bool chk_this_template_generic(Template *t, namedbool incomplete_allowed,
      namedbool allow_omit, namedbool allow_any_or_omit, namedbool sub_chk,
-     namedbool implicit_omit, Common::Assignment *lhs);
+     namedbool implicit_omit, namedbool class_member_init, Common::Assignment *lhs);
     /** Checks if a template's type contains default or port field somehow.*/
     void chk_this_template_incorrect_field();
   private:
-    bool chk_this_refd_template(Template *t, Common::Assignment *lhs);
+    bool chk_this_refd_template(Template *t, namedbool class_member_init, Common::Assignment *lhs);
     void chk_this_template_length_restriction(Template *t);
     bool chk_this_template_concat_operand(Template* t, namedbool implicit_omit,
-      Common::Assignment *lhs);
+      namedbool class_member_init, Common::Assignment *lhs);
     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);
+      namedbool implicit_omit, namedbool class_member_init, Common::Assignment *lhs);
     bool chk_this_template_Str(Template *t, namedbool implicit_omit,
-      Common::Assignment *lhs);
+      namedbool class_member_init, Common::Assignment *lhs);
     /** Checks whether \a v is a correct range boundary for this type.
      * Applicable to the following types: integer, float, charstring,
      * universal charstring.
@@ -1054,19 +1064,19 @@ namespace Common {
     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);
+      namedbool implicit_omit, namedbool class_member_init, Common::Assignment *lhs);
     bool chk_this_template_Seq(Template *t, namedbool incomplete_allowed,
-      namedbool implicit_omit, Common::Assignment *lhs);
+      namedbool implicit_omit, namedbool class_member_init, Common::Assignment *lhs);
     bool chk_this_template_Set(Template *t, namedbool incomplete_allowed,
-      namedbool implicit_omit, Common::Assignment *lhs);
+      namedbool implicit_omit, namedbool class_member_init, Common::Assignment *lhs);
     bool chk_this_template_SeqOf(Template *t, namedbool incomplete_allowed,
-      namedbool implicit_omit, Common::Assignment *lhs);
+      namedbool implicit_omit, namedbool class_member_init, Common::Assignment *lhs);
     bool chk_this_template_SetOf(Template *t, namedbool incomplete_allowed,
-      namedbool implicit_omit, Common::Assignment *lhs);
+      namedbool implicit_omit, namedbool class_member_init, Common::Assignment *lhs);
     bool chk_this_template_array(Template *t, namedbool incomplete_allowed,
-      namedbool implicit_omit, Common::Assignment *lhs);
+      namedbool implicit_omit, namedbool class_member_init, Common::Assignment *lhs);
     void chk_this_template_Fat(Template *t);
-    void chk_this_template_Signature(Template *t, namedbool incomplete_allowed);
+    void chk_this_template_Signature(Template *t, namedbool incomplete_allowed, namedbool class_member_init);
   public:
     /** Check whether there is an enum item with the given name.
      *
diff --git a/compiler2/Type_chk.cc b/compiler2/Type_chk.cc
index 740a12a0c58cc9744008d128dd9f049052262222..ce9393795d38a0dc0954fb0f0110013902b4abf0 100644
--- a/compiler2/Type_chk.cc
+++ b/compiler2/Type_chk.cc
@@ -3998,7 +3998,8 @@ void Type::chk_this_value_ref(Value *value)
 
 bool Type::chk_this_value(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
                           namedbool incomplete_allowed, namedbool omit_allowed,
-                          namedbool sub_chk, namedbool implicit_omit, namedbool is_str_elem)
+                          namedbool sub_chk, namedbool implicit_omit, namedbool is_str_elem,
+                          namedbool class_member_init)
 {
   bool self_ref = false;
   chk();
@@ -4015,12 +4016,12 @@ bool Type::chk_this_value(Value *value, Common::Assignment *lhs, expected_value_
   case Value::V_ERROR:
     return false;
   case Value::V_REFD:
-    return chk_this_refd_value(value, lhs, expected_value, 0, is_str_elem);
+    return chk_this_refd_value(value, lhs, expected_value, 0, is_str_elem, class_member_init);
   case Value::V_INVOKE:
     chk_this_invoked_value(value, lhs, expected_value);
     return false; // assumes no self-reference in invoke
   case Value::V_EXPR:
-    if (lhs) self_ref = value->chk_expr_self_ref(lhs);
+    self_ref = value->chk_expr_self_ref(lhs, class_member_init);
     // no break
   case Value::V_MACRO:
     if (value->is_unfoldable(0, expected_value)) {
@@ -4031,7 +4032,7 @@ bool Type::chk_this_value(Value *value, Common::Assignment *lhs, expected_value_
           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);
+            incomplete_allowed, omit_allowed, sub_chk, implicit_omit, is_str_elem, class_member_init);
           value->use_default_alternative(this);
           return self_ref;
         }
@@ -4118,23 +4119,23 @@ bool Type::chk_this_value(Value *value, Common::Assignment *lhs, expected_value_
   case T_OPENTYPE:
   case T_ANYTYPE:
     self_ref = chk_this_value_Choice(value, lhs, expected_value, omit_allowed,
-      sub_chk, incomplete_allowed, implicit_omit, is_str_elem);
+      sub_chk, incomplete_allowed, implicit_omit, is_str_elem, class_member_init);
     break;
   case T_SEQ_T:
   case T_SET_T:
   case T_SEQ_A:
   case T_SET_A:
     self_ref = chk_this_value_Se(value, lhs, expected_value, incomplete_allowed,
-      implicit_omit);
+      implicit_omit, class_member_init);
     break;
   case T_SEQOF:
   case T_SETOF:
     self_ref = chk_this_value_SeOf(value, lhs, expected_value, incomplete_allowed,
-      implicit_omit);
+      implicit_omit, class_member_init);
     break;
   case T_REFD:
     self_ref = get_type_refd()->chk_this_value(value, lhs, expected_value,
-      incomplete_allowed, omit_allowed, NO_SUB_CHK, implicit_omit, is_str_elem);
+      incomplete_allowed, omit_allowed, NO_SUB_CHK, implicit_omit, is_str_elem, class_member_init);
     break;
   case T_UNRESTRICTEDSTRING:
   case T_OCFT:
@@ -4144,7 +4145,7 @@ bool Type::chk_this_value(Value *value, Common::Assignment *lhs, expected_value_
   case T_SELTYPE:
   case T_ADDRESS:
     self_ref = get_type_refd()->chk_this_value(value, lhs, expected_value,
-      incomplete_allowed, omit_allowed, NO_SUB_CHK, NOT_IMPLICIT_OMIT, is_str_elem);
+      incomplete_allowed, omit_allowed, NO_SUB_CHK, NOT_IMPLICIT_OMIT, is_str_elem, class_member_init);
     break;
   case T_VERDICT:
     chk_this_value_Verdict(value);
@@ -4153,14 +4154,14 @@ bool Type::chk_this_value(Value *value, Common::Assignment *lhs, expected_value_
     chk_this_value_Default(value);
     break;
   case T_ARRAY:
-    self_ref = chk_this_value_Array(value, lhs, expected_value, incomplete_allowed, implicit_omit);
+    self_ref = chk_this_value_Array(value, lhs, expected_value, incomplete_allowed, implicit_omit, class_member_init);
     break;
   case T_PORT:
     // Remain silent. The error has already been reported in the definition
     // that the value belongs to.
     break;
   case T_SIGNATURE:
-    self_ref = chk_this_value_Signature(value, lhs, expected_value, incomplete_allowed);
+    self_ref = chk_this_value_Signature(value, lhs, expected_value, incomplete_allowed, class_member_init);
     break;
   case T_COMPONENT:
     chk_this_value_Component(value);
@@ -4184,7 +4185,7 @@ bool Type::chk_this_value(Value *value, Common::Assignment *lhs, expected_value_
 }
 
 bool Type::chk_this_refd_value(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
-                               ReferenceChain* refch, namedbool str_elem)
+                               ReferenceChain* refch, namedbool str_elem, namedbool class_member_init)
 {
   Reference *ref = value->get_reference();
   Assignment *ass = ref->get_refd_assignment();
@@ -4206,10 +4207,15 @@ bool Type::chk_this_refd_value(Value *value, Common::Assignment *lhs, expected_v
     return self_ref;
   case Assignment::A_CONST:
     if (expected_value == EXPECTED_CONSTANT &&
-        ass->get_Value()->is_unfoldable(NULL, expected_value)) {
+        (ass->get_Value() == NULL || ass->get_Value()->is_unfoldable(NULL, expected_value))) {
       value->error("Referenced constant value cannot be evaluated at compile-time");
       error_flag = true;
     }
+    else if (class_member_init && ass->get_Value() == NULL) {
+      value->error("Reference to uninitialized constant `%s' in class member initialization",
+        ass->get_id().get_dispname().c_str());
+      error_flag = true;
+    }
     else {
       is_const = true;
     }
@@ -4253,6 +4259,13 @@ bool Type::chk_this_refd_value(Value *value, Common::Assignment *lhs, expected_v
     }
     // else fall through
   case Assignment::A_VAR:
+    if (ass->get_asstype() == Assignment::A_VAR &&
+        class_member_init && ass->get_Value() == NULL) {
+      value->error("Reference to uninitialized variable `%s' in class member initialization",
+        ass->get_id().get_dispname().c_str());
+      error_flag = true;
+    }
+    // else fall through
   case Assignment::A_EXCEPTION:
   case Assignment::A_PAR_VAL:
   case Assignment::A_PAR_VAL_IN:
@@ -4388,7 +4401,7 @@ bool Type::chk_this_refd_value(Value *value, Common::Assignment *lhs, expected_v
             "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);
+          return chk_this_refd_value(value, lhs, expected_value, refch, str_elem, class_member_init);
         }
         CompField* def_alt = get_default_alternative();
         if (def_alt != NULL) {
@@ -4396,7 +4409,7 @@ bool Type::chk_this_refd_value(Value *value, Common::Assignment *lhs, expected_v
           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);
+            expected_value, refch, str_elem, class_member_init);
           value->use_default_alternative(this);
           return self_ref;
         }
@@ -4995,7 +5008,8 @@ 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 omit_allowed, namedbool sub_chk,
-  namedbool incomplete_allowed, namedbool implicit_omit, namedbool str_elem)
+  namedbool incomplete_allowed, namedbool implicit_omit, namedbool str_elem,
+  namedbool class_member_init)
 {
   bool self_ref = false;
   CompField* def_alt = get_default_alternative();
@@ -5006,7 +5020,7 @@ bool Type::chk_this_value_Choice(Value *value, Common::Assignment *lhs,
         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);
+          incomplete_allowed, omit_allowed, sub_chk, implicit_omit, str_elem, class_member_init);
         value->use_default_alternative(this);
         return self_ref;
       }
@@ -5022,7 +5036,7 @@ bool Type::chk_this_value_Choice(Value *value, Common::Assignment *lhs,
         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);
+          incomplete_allowed, omit_allowed, sub_chk, implicit_omit, str_elem, class_member_init);
         value->use_default_alternative(this);
         return self_ref;
       }
@@ -5042,7 +5056,7 @@ bool Type::chk_this_value_Choice(Value *value, Common::Assignment *lhs,
         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);
+          incomplete_allowed, omit_allowed, sub_chk, implicit_omit, str_elem, class_member_init);
         value->use_default_alternative(this);
         return self_ref;
       }
@@ -5071,7 +5085,7 @@ bool Type::chk_this_value_Choice(Value *value, Common::Assignment *lhs,
     alt_value->set_my_governor(alt_type);
     alt_type->chk_this_value_ref(alt_value);
     self_ref |= alt_type->chk_this_value(alt_value, lhs, expected_value,
-      incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
+      incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit, class_member_init);
     if (alt_value->get_valuetype() == Value::V_NOTUSED) {
       value->set_valuetype(Value::V_NOTUSED);
     }
@@ -5081,7 +5095,7 @@ bool Type::chk_this_value_Choice(Value *value, Common::Assignment *lhs,
       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);
+        incomplete_allowed, omit_allowed, sub_chk, implicit_omit, str_elem, class_member_init);
       value->use_default_alternative(this);
       return self_ref;
     }
@@ -5096,27 +5110,27 @@ bool Type::chk_this_value_Choice(Value *value, Common::Assignment *lhs,
 }
 
 bool Type::chk_this_value_Se(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
-  namedbool incomplete_allowed, namedbool implicit_omit)
+  namedbool incomplete_allowed, namedbool implicit_omit, namedbool class_member_init)
 {
   if (value->is_asn1())
     return chk_this_value_Se_A(value, lhs, expected_value, implicit_omit);
   else
     return chk_this_value_Se_T(value, lhs, expected_value, incomplete_allowed,
-                                                               implicit_omit);
+      implicit_omit, class_member_init);
 }
 
 bool Type::chk_this_value_Se_T(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
-                               namedbool incomplete_allowed, namedbool implicit_omit)
+                               namedbool incomplete_allowed, namedbool implicit_omit, namedbool class_member_init)
 {
   switch (value->get_valuetype()) {
   case Value::V_SEQ:
     if (typetype == T_SET_A || typetype == T_SET_T) {
       value->set_valuetype(Value::V_SET);
       return chk_this_value_Set_T(value, lhs, expected_value, incomplete_allowed,
-                           implicit_omit);
+                           implicit_omit, class_member_init);
     } else {
       return chk_this_value_Seq_T(value, lhs, expected_value, incomplete_allowed,
-                           implicit_omit);
+                           implicit_omit, class_member_init);
     }
     break;
   case Value::V_SEQOF:
@@ -5146,7 +5160,7 @@ bool Type::chk_this_value_Se_T(Value *value, Common::Assignment *lhs, expected_v
       } else {
         value->set_valuetype(Value::V_SEQ);
         return chk_this_value_Seq_T(value, lhs, expected_value, incomplete_allowed,
-                             implicit_omit);
+                             implicit_omit, class_member_init);
       }
     }
     break;
@@ -5161,7 +5175,7 @@ bool Type::chk_this_value_Se_T(Value *value, Common::Assignment *lhs, expected_v
 }
 
 bool Type::chk_this_value_Seq_T(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
-  namedbool incomplete_allowed, namedbool implicit_omit)
+  namedbool incomplete_allowed, namedbool implicit_omit, namedbool class_member_init)
 {
   bool self_ref = false;
   map<string, NamedValue> comp_map;
@@ -5240,7 +5254,8 @@ bool Type::chk_this_value_Seq_T(Value *value, Common::Assignment *lhs, expected_
       value_dispname_str);
     type->chk_this_value_ref(comp_value);
     self_ref |= type->chk_this_value(comp_value, lhs, expected_value, incomplete_allowed,
-      cf->get_is_optional() ? OMIT_ALLOWED : OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
+      cf->get_is_optional() ? OMIT_ALLOWED : OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit,
+      NOT_STR_ELEM, class_member_init);
     if (comp_value->get_valuetype() != Value::V_NOTUSED) {
       is_empty = false;
     }
@@ -5274,7 +5289,7 @@ bool Type::chk_this_value_Seq_T(Value *value, Common::Assignment *lhs, expected_
 }
 
 bool Type::chk_this_value_Set_T(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
-  namedbool incomplete_allowed, namedbool implicit_omit)
+  namedbool incomplete_allowed, namedbool implicit_omit, namedbool class_member_init)
 {
   bool self_ref = false;
   map<string, NamedValue> comp_map;
@@ -5311,7 +5326,8 @@ bool Type::chk_this_value_Set_T(Value *value, Common::Assignment *lhs, expected_
       value_dispname_str);
     type->chk_this_value_ref(comp_value);
     self_ref |= type->chk_this_value(comp_value, lhs, expected_value, incomplete_allowed,
-      cf->get_is_optional() ? OMIT_ALLOWED : OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
+      cf->get_is_optional() ? OMIT_ALLOWED : OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit,
+      NOT_STR_ELEM, class_member_init);
     if (comp_value->get_valuetype() != Value::V_NOTUSED) {
       is_empty = false;
     }
@@ -5487,7 +5503,7 @@ bool Type::chk_this_value_Set_A(Value *value, Common::Assignment *lhs, expected_
 }
 
 bool Type::chk_this_value_SeOf(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
-  namedbool incomplete_allowed, namedbool implicit_omit)
+  namedbool incomplete_allowed, namedbool implicit_omit, namedbool class_member_init)
 {
   bool self_ref = false;
   const char *valuetypename;
@@ -5523,7 +5539,8 @@ bool Type::chk_this_value_SeOf(Value *value, Common::Assignment *lhs, expected_v
         } else {
           u.seof.ofType->chk_this_value_ref(v_comp);
           self_ref |= u.seof.ofType->chk_this_value(v_comp, lhs, expected_value,
-            incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
+            incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit,
+            NOT_STR_ELEM, class_member_init);
         }
       }
     } else {
@@ -5579,7 +5596,7 @@ bool Type::chk_this_value_SeOf(Value *value, Common::Assignment *lhs, expected_v
         val->set_my_governor(u.seof.ofType);
         u.seof.ofType->chk_this_value_ref(val);
         self_ref |= u.seof.ofType->chk_this_value(val, lhs, expected_value,
-          incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK);
+          incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK, NOT_STR_ELEM, class_member_init);
       }
       if (check_holes) {
         if ((size_t)max_index != index_map.size() - 1) {
@@ -5631,7 +5648,7 @@ void Type::chk_this_value_Default(Value *value)
 }
 
 bool Type::chk_this_value_Array(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
-  namedbool incomplete_allowed, namedbool implicit_omit)
+  namedbool incomplete_allowed, namedbool implicit_omit, namedbool class_member_init)
 {
   bool self_ref = false;
   switch (value->get_valuetype()) {
@@ -5668,7 +5685,7 @@ bool Type::chk_this_value_Array(Value *value, Common::Assignment *lhs, expected_
           u.array.element_type->chk_this_value_ref(v_comp);
           self_ref |= u.array.element_type->chk_this_value(v_comp, lhs,
             expected_value, incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK,
-            implicit_omit);
+            implicit_omit, NOT_STR_ELEM, class_member_init);
         }
       }
     } else {
@@ -5718,7 +5735,8 @@ bool Type::chk_this_value_Array(Value *value, Common::Assignment *lhs, expected_
         val->set_my_governor(u.array.element_type);
         u.array.element_type->chk_this_value_ref(val);
         self_ref |= u.array.element_type->chk_this_value(val, lhs, expected_value,
-          incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
+          incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit, NOT_STR_ELEM,
+          class_member_init);
       }
       if (check_holes) {
         if (index_map.size() < array_size) {
@@ -5745,7 +5763,7 @@ bool Type::chk_this_value_Array(Value *value, Common::Assignment *lhs, expected_
 
 bool Type::chk_this_value_Signature(Value *value, Common::Assignment *lhs,
                                     expected_value_t expected_value,
-                                    namedbool incomplete_allowed)
+                                    namedbool incomplete_allowed, namedbool class_member_init)
 {
   bool self_ref = false;
   switch(value->get_valuetype()) {
@@ -5816,7 +5834,8 @@ bool Type::chk_this_value_Signature(Value *value, Common::Assignment *lhs,
       type->chk_this_value_ref(comp_value);
       self_ref |= type->chk_this_value(comp_value, lhs, expected_value,
         INCOMPLETE_NOT_ALLOWED,
-        cf->get_is_optional() ? OMIT_ALLOWED : OMIT_NOT_ALLOWED, SUB_CHK);
+        cf->get_is_optional() ? OMIT_ALLOWED : OMIT_NOT_ALLOWED, SUB_CHK,
+        NOT_IMPLICIT_OMIT, NOT_STR_ELEM, class_member_init);
     }
     if (INCOMPLETE_NOT_ALLOWED == incomplete_allowed) {
       for (size_t i = 0; i < u.signature.parameters->get_nof_in_params(); i++) {
@@ -6496,7 +6515,7 @@ void Type::chk_this_template_incorrect_field() {
 
 bool Type::chk_this_template_generic(Template *t, namedbool incomplete_allowed,
   namedbool allow_omit, namedbool allow_any_or_omit, namedbool sub_chk,
-  namedbool implicit_omit, Common::Assignment *lhs)
+  namedbool implicit_omit, namedbool class_member_init, Common::Assignment *lhs)
 {
   bool self_ref = false;
   t->chk_concat_double_length_res();
@@ -6534,7 +6553,7 @@ bool Type::chk_this_template_generic(Template *t, namedbool incomplete_allowed,
       if (!ass) break; // probably erroneous
       //warning("asstype %d", ass->get_asstype());
 
-      switch (ass->get_asstype()) {
+      switch (ass->get_asstype()) { // todo class_member_init
       case Assignment::A_VAR:
       case Assignment::A_EXCEPTION:
       case Assignment::A_PAR_VAL_IN:
@@ -6587,7 +6606,8 @@ bool Type::chk_this_template_generic(Template *t, namedbool incomplete_allowed,
       chk_this_template_ref(t_comp);
       self_ref |= chk_this_template_generic(t_comp, INCOMPLETE_NOT_ALLOWED,
         (omit_in_value_list && temptype != Ttcn::Template::CONJUNCTION_MATCH) ?
-        allow_omit : OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, sub_chk, implicit_omit, lhs);
+        allow_omit : OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, sub_chk, implicit_omit,
+        class_member_init, lhs);
       if(temptype==Ttcn::Template::COMPLEMENTED_LIST &&
          t_comp->get_template_refd_last()->get_templatetype() ==
          Ttcn::Template::ANY_OR_OMIT)
@@ -6599,7 +6619,7 @@ bool Type::chk_this_template_generic(Template *t, namedbool incomplete_allowed,
     Value *v = t->get_specific_value();
     v->set_my_governor(this);
     self_ref |= chk_this_value(v, lhs, EXPECTED_TEMPLATE, incomplete_allowed,
-      allow_omit, SUB_CHK);
+      allow_omit, SUB_CHK, NOT_IMPLICIT_OMIT, NOT_STR_ELEM, class_member_init);
     break; }
   case Ttcn::Template::TEMPLATE_INVOKE: {
     t->chk_invoke();
@@ -6614,7 +6634,7 @@ bool Type::chk_this_template_generic(Template *t, namedbool incomplete_allowed,
     }
     break; }
   case Ttcn::Template::TEMPLATE_REFD:
-    self_ref = chk_this_refd_template(t, lhs);
+    self_ref = chk_this_refd_template(t, class_member_init, lhs);
     break;
   case Ttcn::Template::TEMPLATE_CONCAT:
     {
@@ -6626,11 +6646,11 @@ bool Type::chk_this_template_generic(Template *t, namedbool incomplete_allowed,
       Template* t_right = t->get_concat_operand(false);
       {
         Error_Context cntxt2(t, "In first operand");
-        self_ref |= chk_this_template_concat_operand(t_left, implicit_omit, lhs);
+        self_ref |= chk_this_template_concat_operand(t_left, implicit_omit, class_member_init, lhs);
       }
       {
         Error_Context cntxt2(t, "In second operand");
-        self_ref |= chk_this_template_concat_operand(t_right, implicit_omit, lhs);
+        self_ref |= chk_this_template_concat_operand(t_right, implicit_omit, class_member_init, lhs);
       }
       if (t_left->get_templatetype() == Ttcn::Template::TEMPLATE_ERROR ||
           t_right->get_templatetype() == Ttcn::Template::TEMPLATE_ERROR) {
@@ -6639,8 +6659,8 @@ bool Type::chk_this_template_generic(Template *t, namedbool incomplete_allowed,
     }
     break;
   case Ttcn::Template::IMPLICATION_MATCH:
-    t->get_precondition()->chk(this);
-    t->get_implied_template()->chk(this);
+    t->get_precondition()->chk(this, class_member_init);
+    t->get_implied_template()->chk(this, class_member_init);
     break;
   case Ttcn::Template::DYNAMIC_MATCH: {
     Ttcn::FormalPar* matching_fp = new Ttcn::FormalPar(Assignment::A_PAR_VAL_IN, clone(),
@@ -6667,7 +6687,7 @@ bool Type::chk_this_template_generic(Template *t, namedbool incomplete_allowed,
     break; }
   default:
     self_ref = chk_this_template(t, incomplete_allowed, allow_omit, allow_any_or_omit,
-      sub_chk, implicit_omit, lhs);
+      sub_chk, implicit_omit, class_member_init, lhs);
     break;
   }
   if (t->get_length_restriction()) chk_this_template_length_restriction(t);
@@ -6681,7 +6701,7 @@ bool Type::chk_this_template_generic(Template *t, namedbool incomplete_allowed,
   return self_ref;
 }
 
-bool Type::chk_this_refd_template(Template *t, Common::Assignment *lhs)
+bool Type::chk_this_refd_template(Template *t, namedbool class_member_init, Common::Assignment *lhs)
 {
   if (t->get_templatetype() != Template::TEMPLATE_REFD) return false;
   Reference *ref = t->get_reference();
@@ -6730,11 +6750,26 @@ bool Type::chk_this_refd_template(Template *t, Common::Assignment *lhs)
       if (info.needs_conversion()) t->set_needs_conversion();
     }
   }
+  if (class_member_init) {
+    switch (ass->get_asstype()) {
+    case Assignment::A_TEMPLATE:
+    case Assignment::A_VAR_TEMPLATE:
+      if (ass->get_Template() == NULL) {
+        t->error("Reference to uninitialized template%s `%s' in class member initialization",
+          ass->get_asstype() == Assignment::A_VAR_TEMPLATE ? " variable" : "",
+          ass->get_id().get_dispname().c_str());
+        t->set_templatetype(Ttcn::Template::TEMPLATE_ERROR);
+      }
+      break;
+    default:
+      break;
+    }
+  }
   return (lhs == ass);
 }
 
 bool Type::chk_this_template_concat_operand(Template* t, namedbool implicit_omit,
-                                            Common::Assignment *lhs)
+                                            namedbool class_member_init, Common::Assignment *lhs)
 {
   Type* governor = t->get_expr_governor(EXPECTED_TEMPLATE);
   if (governor == NULL) {
@@ -6748,7 +6783,7 @@ bool Type::chk_this_template_concat_operand(Template* t, namedbool implicit_omit
   }
   t->set_my_governor(governor);
   bool self_ref = governor->chk_this_template_generic(t, INCOMPLETE_NOT_ALLOWED,
-    OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, NO_SUB_CHK, implicit_omit, lhs);
+    OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, NO_SUB_CHK, implicit_omit, class_member_init, lhs);
   Template* t_last = t->get_template_refd_last();
   if (t->get_templatetype() == Ttcn::Template::TEMPLATE_ERROR ||
       t_last->get_templatetype() == Ttcn::Template::TEMPLATE_ERROR) {
@@ -6819,7 +6854,7 @@ bool Type::chk_this_template_concat_operand(Template* t, namedbool implicit_omit
 
 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)
+                             namedbool implicit_omit, namedbool class_member_init, Common::Assignment *lhs)
 {
   bool self_ref = false;
   Type *t_last = get_type_refd_last();
@@ -6858,7 +6893,7 @@ bool Type::chk_this_template(Template *t, namedbool incomplete_allowed,
   case T_UTCTIME:
   case T_GENERALIZEDTIME:
   case T_OBJECTDESCRIPTOR:
-    self_ref = t_last->chk_this_template_Str(t, implicit_omit, lhs);
+    self_ref = t_last->chk_this_template_Str(t, implicit_omit, class_member_init, lhs);
     break;
   case T_INT:
   case T_INT_A:
@@ -6874,31 +6909,36 @@ bool Type::chk_this_template(Template *t, namedbool incomplete_allowed,
   case T_OPENTYPE:
   case T_ANYTYPE:
     self_ref = t_last->chk_this_template_Choice(t, incomplete_allowed, allow_omit,
-      allow_any_or_omit, sub_chk, implicit_omit, lhs);
+      allow_any_or_omit, sub_chk, implicit_omit, class_member_init, lhs);
     break;
   case T_SEQ_A:
   case T_SEQ_T:
-    self_ref = t_last->chk_this_template_Seq(t, incomplete_allowed, implicit_omit, lhs);
+    self_ref = t_last->chk_this_template_Seq(t, incomplete_allowed, implicit_omit,
+      class_member_init, lhs);
     break;
   case T_SET_A:
   case T_SET_T:
-    self_ref = t_last->chk_this_template_Set(t, incomplete_allowed, implicit_omit, lhs);
+    self_ref = t_last->chk_this_template_Set(t, incomplete_allowed, implicit_omit,
+      class_member_init, lhs);
     break;
   case T_SEQOF:
-    self_ref = t_last->chk_this_template_SeqOf(t, incomplete_allowed, implicit_omit, lhs);
+    self_ref = t_last->chk_this_template_SeqOf(t, incomplete_allowed, implicit_omit,
+      class_member_init, lhs);
     break;
   case T_SETOF:
-    self_ref = t_last->chk_this_template_SetOf(t, incomplete_allowed, implicit_omit, lhs);
+    self_ref = t_last->chk_this_template_SetOf(t, incomplete_allowed, implicit_omit,
+      class_member_init, lhs);
     break;
   case T_ARRAY:
-    self_ref = t_last->chk_this_template_array(t, incomplete_allowed, implicit_omit, lhs);
+    self_ref = t_last->chk_this_template_array(t, incomplete_allowed, implicit_omit,
+      class_member_init, lhs);
     break;
   case T_PORT:
     t->error("Template cannot be defined for port type `%s'",
       get_fullname().c_str());
     break;
   case T_SIGNATURE:
-    t_last->chk_this_template_Signature(t, incomplete_allowed);
+    t_last->chk_this_template_Signature(t, incomplete_allowed, class_member_init);
     break;
   case T_FUNCTION:
   case T_ALTSTEP:
@@ -6912,7 +6952,7 @@ bool Type::chk_this_template(Template *t, namedbool incomplete_allowed,
 }
 
 bool Type::chk_this_template_Str(Template *t, namedbool implicit_omit,
-                                 Common::Assignment *lhs)
+                                 namedbool class_member_init, Common::Assignment *lhs)
 {
   bool self_ref = false;
   typetype_t tt = get_typetype_ttcn3(typetype);
@@ -6952,7 +6992,7 @@ bool Type::chk_this_template_Str(Template *t, namedbool implicit_omit,
     if (tt == T_CSTR) {
       Ttcn::PatternString *pstr = t->get_cstr_pattern();
       Error_Context cntxt(t, "In character string pattern");
-      pstr->chk_refs();
+      pstr->chk_refs(EXPECTED_DYNAMIC_VALUE, class_member_init);
       pstr->join_strings();
       if (!pstr->has_refs()) pstr->chk_pattern();
       break;
@@ -6970,7 +7010,7 @@ bool Type::chk_this_template_Str(Template *t, namedbool implicit_omit,
     if (tt == T_USTR) {
       Ttcn::PatternString *pstr = t->get_ustr_pattern();
       Error_Context cntxt(t, "In universal string pattern");
-      pstr->chk_refs();
+      pstr->chk_refs(EXPECTED_DYNAMIC_VALUE, class_member_init);
       pstr->join_strings();
       if (!pstr->has_refs()) pstr->chk_pattern();
     } else report_error = true;
@@ -6991,7 +7031,7 @@ bool Type::chk_this_template_Str(Template *t, namedbool implicit_omit,
       self_ref = target_type->chk_this_template_generic(
         target->get_Template(), (target->get_DerivedRef() != NULL) ?
         INCOMPLETE_ALLOWED : INCOMPLETE_NOT_ALLOWED,
-        OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, implicit_omit, lhs);
+        OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, implicit_omit, class_member_init, lhs);
       Type* coding_type = legacy_codec_handling ?
         target_type->get_type_refd_last() : target_type;
       coding_type->chk_coding(false, t->get_my_scope()->get_scope_mod());
@@ -7163,7 +7203,7 @@ 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)
+  namedbool implicit_omit, namedbool class_member_init, Common::Assignment *lhs)
 {
   bool self_ref = false;
   CompField* def_alt = get_default_alternative();
@@ -7175,7 +7215,7 @@ bool Type::chk_this_template_Choice(Template *t, namedbool incomplete_allowed,
       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);
+        allow_any_or_omit, sub_chk, implicit_omit, class_member_init, lhs);
       t->use_default_alternative(this);
       return self_ref;
     }
@@ -7211,7 +7251,7 @@ bool Type::chk_this_template_Choice(Template *t, namedbool incomplete_allowed,
         Ttcn::Template::C_MAY_INCOMPLETE;
       self_ref |= field_type->chk_this_template_generic(nt_templ,
         (incompl_ok ? incomplete_allowed : INCOMPLETE_NOT_ALLOWED),
-        OMIT_NOT_ALLOWED, ANY_OR_OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit, lhs);
+        OMIT_NOT_ALLOWED, ANY_OR_OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit, class_member_init, lhs);
     }
     break;}
   default:
@@ -7219,7 +7259,7 @@ bool Type::chk_this_template_Choice(Template *t, namedbool incomplete_allowed,
       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);
+        allow_any_or_omit, sub_chk, implicit_omit, class_member_init, lhs);
       t->use_default_alternative(this);
       return self_ref;
     }
@@ -7234,7 +7274,7 @@ bool Type::chk_this_template_Choice(Template *t, namedbool incomplete_allowed,
 }
 
 bool Type::chk_this_template_Seq(Template *t, namedbool incomplete_allowed,
-  namedbool implicit_omit, Common::Assignment *lhs)
+  namedbool implicit_omit, namedbool class_member_init, Common::Assignment *lhs)
 {
   bool self_ref = false;
   size_t n_type_comps = get_nof_comps();
@@ -7315,7 +7355,7 @@ bool Type::chk_this_template_Seq(Template *t, namedbool incomplete_allowed,
       self_ref |= type->chk_this_template_generic(comp_t, incomplete_allowed,
         (is_optional ? OMIT_ALLOWED : OMIT_NOT_ALLOWED),
         (is_optional ? ANY_OR_OMIT_ALLOWED : ANY_OR_OMIT_NOT_ALLOWED),
-        SUB_CHK, implicit_omit, lhs);
+        SUB_CHK, implicit_omit, class_member_init, lhs);
     }
     if (INCOMPLETE_ALLOWED != incomplete_allowed  || IMPLICIT_OMIT == implicit_omit) {
       // check missing fields
@@ -7351,7 +7391,8 @@ bool Type::chk_this_template_Seq(Template *t, namedbool incomplete_allowed,
 }
 
 bool Type::chk_this_template_Set(Template *t,
-  namedbool incomplete_allowed, namedbool implicit_omit, Common::Assignment *lhs)
+  namedbool incomplete_allowed, namedbool implicit_omit,
+  namedbool class_member_init, Common::Assignment *lhs)
 {
   bool self_ref = false;
   size_t n_type_comps = get_nof_comps();
@@ -7399,7 +7440,7 @@ bool Type::chk_this_template_Set(Template *t,
       self_ref |= type->chk_this_template_generic(comp_t, incomplete_allowed,
         (is_optional ? OMIT_ALLOWED : OMIT_NOT_ALLOWED),
         (is_optional ? ANY_OR_OMIT_ALLOWED : ANY_OR_OMIT_NOT_ALLOWED),
-        SUB_CHK, implicit_omit, lhs);
+        SUB_CHK, implicit_omit, class_member_init, lhs);
     }
     if (INCOMPLETE_ALLOWED != incomplete_allowed || IMPLICIT_OMIT == implicit_omit) {
       // check missing fields
@@ -7435,7 +7476,7 @@ bool Type::chk_this_template_Set(Template *t,
 }
 
 bool Type::chk_this_template_SeqOf(Template *t, namedbool incomplete_allowed,
-  namedbool implicit_omit, Common::Assignment *lhs)
+  namedbool implicit_omit, namedbool class_member_init, Common::Assignment *lhs)
 {
   bool self_ref = false;
   switch(t->get_templatetype()) {
@@ -7454,7 +7495,7 @@ bool Type::chk_this_template_SeqOf(Template *t, namedbool incomplete_allowed,
       // the elements of permutation must be always complete
       self_ref |= u.seof.ofType->chk_this_template_generic(t_comp,
         INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK,
-        NOT_IMPLICIT_OMIT, lhs);
+        NOT_IMPLICIT_OMIT, class_member_init, lhs);
     }
     break; }
   case Ttcn::Template::TEMPLATE_LIST: {
@@ -7484,7 +7525,7 @@ bool Type::chk_this_template_SeqOf(Template *t, namedbool incomplete_allowed,
         // the templates within the permutation always have to be complete
         self_ref |= chk_this_template_generic(t_comp, INCOMPLETE_NOT_ALLOWED,
           OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK,
-          implicit_omit, lhs);
+          implicit_omit, class_member_init, lhs);
         break;
       case Ttcn::Template::TEMPLATE_NOTUSED:
         if (c == Ttcn::Template::C_MUST_COMPLETE) {
@@ -7502,7 +7543,7 @@ bool Type::chk_this_template_SeqOf(Template *t, namedbool incomplete_allowed,
           (c == Ttcn::Template::C_PARTIAL && i < nof_base_comps);
         self_ref |= u.seof.ofType->chk_this_template_generic(t_comp,
           (embedded_modified ? incomplete_allowed : INCOMPLETE_NOT_ALLOWED),
-          OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, implicit_omit, lhs);
+          OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, implicit_omit, class_member_init, lhs);
         break;
       }
     }
@@ -7548,7 +7589,7 @@ bool Type::chk_this_template_SeqOf(Template *t, namedbool incomplete_allowed,
       u.seof.ofType->chk_this_template_ref(it_comp);
       self_ref |= u.seof.ofType->chk_this_template_generic(it_comp,
         INCOMPLETE_ALLOWED, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED,
-        SUB_CHK, implicit_omit, lhs);
+        SUB_CHK, implicit_omit, class_member_init, lhs);
     }
     for (size_t i = 0; i < index_map.size(); i++)
       delete index_map.get_nth_elem(i);
@@ -7563,7 +7604,7 @@ bool Type::chk_this_template_SeqOf(Template *t, namedbool incomplete_allowed,
 }
 
 bool Type::chk_this_template_SetOf(Template *t, namedbool incomplete_allowed,
-  namedbool implicit_omit, Common::Assignment *lhs)
+  namedbool implicit_omit, namedbool class_member_init, Common::Assignment *lhs)
 {
   bool self_ref = false;
   Ttcn::Template::templatetype_t temptype = t->get_templatetype();
@@ -7586,7 +7627,7 @@ bool Type::chk_this_template_SetOf(Template *t, namedbool incomplete_allowed,
       // the elements of sets must be always complete
       self_ref |= u.seof.ofType->chk_this_template_generic(t_comp,
         INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED,
-        SUB_CHK, implicit_omit, lhs);
+        SUB_CHK, implicit_omit, class_member_init, lhs);
       if (t_comp->get_template_refd_last()->get_templatetype() ==
           Ttcn::Template::ANY_OR_OMIT) {
         if (temptype == Ttcn::Template::SUPERSET_MATCH)
@@ -7638,7 +7679,7 @@ bool Type::chk_this_template_SetOf(Template *t, namedbool incomplete_allowed,
           (c == Ttcn::Template::C_PARTIAL && i < nof_base_comps);
         self_ref |= u.seof.ofType->chk_this_template_generic(t_comp,
           (embedded_modified ? incomplete_allowed : INCOMPLETE_NOT_ALLOWED),
-          OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, implicit_omit, lhs);
+          OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, implicit_omit, class_member_init, lhs);
         break;
       }
     }
@@ -7682,7 +7723,7 @@ bool Type::chk_this_template_SetOf(Template *t, namedbool incomplete_allowed,
       u.seof.ofType->chk_this_template_ref(it_comp);
       self_ref |= u.seof.ofType->chk_this_template_generic(it_comp,
         INCOMPLETE_ALLOWED, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED,
-        SUB_CHK, implicit_omit, lhs);
+        SUB_CHK, implicit_omit, class_member_init, lhs);
     }
     for (size_t i = 0; i < index_map.size(); i++)
       delete index_map.get_nth_elem(i);
@@ -7697,7 +7738,8 @@ bool Type::chk_this_template_SetOf(Template *t, namedbool incomplete_allowed,
 }
 
 bool Type::chk_this_template_array(Template *t, namedbool incomplete_allowed,
-                                   namedbool implicit_omit, Common::Assignment *lhs)
+                                   namedbool implicit_omit, namedbool class_member_init,
+                                   Common::Assignment *lhs)
 {
   bool self_ref = false;
   switch (t->get_templatetype()) {
@@ -7716,7 +7758,7 @@ bool Type::chk_this_template_array(Template *t, namedbool incomplete_allowed,
       // the elements of permutation must be always complete
       self_ref |= u.array.element_type->chk_this_template_generic(t_comp,
         INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK,
-        NOT_IMPLICIT_OMIT, lhs);
+        NOT_IMPLICIT_OMIT, class_member_init, lhs);
     }
     break; }
   case Ttcn::Template::TEMPLATE_LIST: {
@@ -7759,7 +7801,7 @@ bool Type::chk_this_template_array(Template *t, namedbool incomplete_allowed,
           // the templates within the permutation always have to be complete
           self_ref |= chk_this_template_generic(t_comp, INCOMPLETE_NOT_ALLOWED,
             OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK,
-            implicit_omit, lhs);
+            implicit_omit, class_member_init, lhs);
           break;
         case Ttcn::Template::TEMPLATE_NOTUSED:
           if (INCOMPLETE_NOT_ALLOWED == incomplete_allowed)
@@ -7771,7 +7813,8 @@ bool Type::chk_this_template_array(Template *t, namedbool incomplete_allowed,
           break;
         default:
             self_ref |= u.array.element_type->chk_this_template_generic(t_comp,
-            incomplete_allowed, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, implicit_omit, lhs);
+              incomplete_allowed, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK,
+              implicit_omit, class_member_init, lhs);
           break;
       }
     }
@@ -7812,7 +7855,8 @@ bool Type::chk_this_template_array(Template *t, namedbool incomplete_allowed,
       it_comp->set_my_governor(u.array.element_type);
       u.array.element_type->chk_this_template_ref(it_comp);
       self_ref |= u.array.element_type->chk_this_template_generic(it_comp,
-        incomplete_allowed, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, implicit_omit, lhs);
+        incomplete_allowed, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK,
+        implicit_omit, class_member_init, lhs);
     }
     for (size_t i = 0; i < index_map.size(); i++)
       delete index_map.get_nth_elem(i);
@@ -7834,7 +7878,8 @@ void Type::chk_this_template_Fat(Template *t)
     "allowed for type `%s'", get_typename().c_str());
 }
 
-void Type::chk_this_template_Signature(Template *t, namedbool incomplete_allowed)
+void Type::chk_this_template_Signature(Template *t, namedbool incomplete_allowed,
+                                       namedbool class_member_init)
 {
   bool self_ref = false;
   size_t n_type_params = get_nof_comps();
@@ -7888,7 +7933,7 @@ void Type::chk_this_template_Signature(Template *t, namedbool incomplete_allowed
       type->chk_this_template_ref(comp_t);
       self_ref |= type->chk_this_template_generic(comp_t, incomplete_allowed,
         OMIT_NOT_ALLOWED, ANY_OR_OMIT_NOT_ALLOWED,
-        SUB_CHK, NOT_IMPLICIT_OMIT, NULL);
+        SUB_CHK, NOT_IMPLICIT_OMIT, class_member_init, NULL);
     }
     if(incomplete_allowed != INCOMPLETE_ALLOWED) {
       SignatureParam *first_undef_in = NULL,
diff --git a/compiler2/Value.cc b/compiler2/Value.cc
index 54af76a944f7aa0fa052626c6679db7804490a04..f15cf586ab0bcee1701171025ea42e83cb05be83 100644
--- a/compiler2/Value.cc
+++ b/compiler2/Value.cc
@@ -10307,6 +10307,8 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
             }
             if (refch->add(get_fullname())) {
               if (ass->get_my_scope()->get_parent_scope()->is_class_scope()) {
+                // class members are considered unfoldable, because their initial
+                // values can be changed in the constructor
                 u.ref.refd_last = this;
               }
               else {
@@ -12059,7 +12061,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
     } // switch
   }
 
-  bool Value::chk_expr_self_ref_templ(Ttcn::Template *t, Common::Assignment *lhs)
+  bool Value::chk_expr_self_ref_templ(Ttcn::Template *t, Common::Assignment *lhs, namedbool class_member_init)
   {
     bool self_ref = false;
     switch (t->get_templatetype()) {
@@ -12067,15 +12069,17 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
       Value *v = t->get_specific_value();
       self_ref |= v->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)
         ->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
-          INCOMPLETE_NOT_ALLOWED, OMIT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT, NOT_STR_ELEM);
+          INCOMPLETE_NOT_ALLOWED, OMIT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT, NOT_STR_ELEM, class_member_init);
       break; }
     case Ttcn::Template::TEMPLATE_REFD: {
-      Ttcn::Reference *refb = t->get_reference();
-      Common::Assignment *ass = refb->get_refd_assignment();
-      self_ref |= (ass == lhs);
+      if (lhs != NULL) {
+        Ttcn::Reference *refb = t->get_reference();
+        Common::Assignment *ass = refb->get_refd_assignment();
+        self_ref |= (ass == lhs);
+      }
       break; }
     case Ttcn::Template::ALL_FROM:
-      self_ref |= chk_expr_self_ref_templ(t->get_all_from(), lhs);
+      self_ref |= chk_expr_self_ref_templ(t->get_all_from(), lhs, class_member_init);
       break;
     case Ttcn::Template::TEMPLATE_LIST:
     case Ttcn::Template::SUPERSET_MATCH:
@@ -12085,7 +12089,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
     case Ttcn::Template::VALUE_LIST: {
       size_t num = t->get_nof_comps();
       for (size_t i = 0; i < num; ++i) {
-        self_ref |= chk_expr_self_ref_templ(t->get_temp_byIndex(i), lhs);
+        self_ref |= chk_expr_self_ref_templ(t->get_temp_byIndex(i), lhs, class_member_init);
       }
       break; }
 // not yet clear whether we should use this or the above for TEMPLATE_LIST
@@ -12099,22 +12103,22 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
       size_t nnt = t->get_nof_comps();
       for (size_t i=0; i < nnt; ++i) {
         Ttcn::NamedTemplate *nt = t->get_namedtemp_byIndex(i);
-        self_ref |= chk_expr_self_ref_templ(nt->get_template(), lhs);
+        self_ref |= chk_expr_self_ref_templ(nt->get_template(), lhs, class_member_init);
       }
       break; }
     case Ttcn::Template::INDEXED_TEMPLATE_LIST: {
       size_t nnt = t->get_nof_comps();
       for (size_t i=0; i < nnt; ++i) {
         Ttcn::IndexedTemplate *it = t->get_indexedtemp_byIndex(i);
-        self_ref |= chk_expr_self_ref_templ(it->get_template(), lhs);
+        self_ref |= chk_expr_self_ref_templ(it->get_template(), lhs, class_member_init);
       }
       break; }
     case Ttcn::Template::VALUE_RANGE: {
       Ttcn::ValueRange *vr = t->get_value_range();
       Common::Value *v = vr->get_min_v();
-      if (v) self_ref |= chk_expr_self_ref_val(v, lhs);
+      if (v) self_ref |= chk_expr_self_ref_val(v, lhs, class_member_init);
       v = vr->get_max_v();
-      if (v) self_ref |= chk_expr_self_ref_val(v, lhs);
+      if (v) self_ref |= chk_expr_self_ref_val(v, lhs, class_member_init);
       break; }
     case Ttcn::Template::CSTR_PATTERN:
     case Ttcn::Template::USTR_PATTERN: {
@@ -12134,14 +12138,14 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
     case Ttcn::Template::TEMPLATE_INVOKE:
       break; // assume self-ref can't happen
     case Ttcn::Template::DECODE_MATCH:
-      self_ref |= chk_expr_self_ref_templ(t->get_decode_target()->get_Template(), lhs);
+      self_ref |= chk_expr_self_ref_templ(t->get_decode_target()->get_Template(), lhs, class_member_init);
       break;
     case Ttcn::Template::TEMPLATE_ERROR:
       //FATAL_ERROR("Value::chk_expr_self_ref_templ()");
       break;
     case Ttcn::Template::TEMPLATE_CONCAT:
-      self_ref |= chk_expr_self_ref_templ(t->get_concat_operand(true), lhs);
-      self_ref |= chk_expr_self_ref_templ(t->get_concat_operand(false), lhs);
+      self_ref |= chk_expr_self_ref_templ(t->get_concat_operand(true), lhs, class_member_init);
+      self_ref |= chk_expr_self_ref_templ(t->get_concat_operand(false), lhs, class_member_init);
       break;
 //    default:
 //      FATAL_ERROR("todo ttype %d", t->get_templatetype());
@@ -12150,7 +12154,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
     return self_ref;
   }
 
-  bool Value::chk_expr_self_ref_val(Common::Value *v, Common::Assignment *lhs)
+  bool Value::chk_expr_self_ref_val(Common::Value *v, Common::Assignment *lhs, namedbool class_member_init)
   {
     Common::Type *gov = v->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
     namedbool is_str_elem = NOT_STR_ELEM;
@@ -12163,13 +12167,12 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
     }
     return gov->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
       INCOMPLETE_NOT_ALLOWED, OMIT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT,
-      is_str_elem);
+      is_str_elem, class_member_init);
   }
 
-  bool Value::chk_expr_self_ref(Common::Assignment *lhs)
+  bool Value::chk_expr_self_ref(Common::Assignment *lhs, namedbool class_member_init)
   {
     if (valuetype != V_EXPR) FATAL_ERROR("Value::chk_expr_self_ref");
-    if (!lhs) FATAL_ERROR("no lhs!");
     bool self_ref = false;
     switch (u.expr.v_optype) {
     case OPTYPE_RND: // -
@@ -12192,7 +12195,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
       break; // nothing to do
 
     case OPTYPE_MATCH: // v1 t2
-      self_ref |= chk_expr_self_ref_templ(u.expr.t2->get_Template(), lhs);
+      self_ref |= chk_expr_self_ref_templ(u.expr.t2->get_Template(), lhs, class_member_init);
       // no break
     case OPTYPE_UNARYPLUS: // v1
     case OPTYPE_UNARYMINUS: // v1
@@ -12236,18 +12239,18 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
     case OPTYPE_GET_STRINGENCODING:
     case OPTYPE_DECODE_BASE64:
     case OPTYPE_REMOVE_BOM:
-      self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
+      self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs, class_member_init);
       break;
     case OPTYPE_COMP_RUNNING: // v1 [r2] b4
     case OPTYPE_COMP_ALIVE: // v1 [r2] b4
-      self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
-      if (u.expr.r2 != NULL) {
+      self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs, class_member_init);
+      if (u.expr.r2 != NULL && lhs != NULL) {
         Common::Assignment *ass = u.expr.r2->get_refd_assignment();
         self_ref |= (ass == lhs);
       }
       break;
     case OPTYPE_HOSTID: // [v1]
-      if (u.expr.v1) self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
+      if (u.expr.v1) self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs, class_member_init);
       break;
     case OPTYPE_ADD: // v1 v2
     case OPTYPE_SUBTRACT: // v1 v2
@@ -12275,45 +12278,45 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
     case OPTYPE_INT2BIT: // v1 v2
     case OPTYPE_INT2HEX: // v1 v2
     case OPTYPE_INT2OCT: // v1 v2
-      self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
-      self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
+      self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs, class_member_init);
+      self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs, class_member_init);
       break;
     case OPTYPE_UNICHAR2OCT: // v1 [v2]
     case OPTYPE_OCT2UNICHAR:
     case OPTYPE_ENCODE_BASE64:
-      self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
-      if (u.expr.v2) self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
+      self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs, class_member_init);
+      if (u.expr.v2) self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs, class_member_init);
       break;
     case OPTYPE_DECOMP: // v1 v2 v3
-      self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
-      self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
-      self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
+      self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs, class_member_init);
+      self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs, class_member_init);
+      self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs, class_member_init);
       break;
 
     case OPTYPE_REPLACE: // ti1 v2 v3 ti4
-      self_ref |= chk_expr_self_ref_templ(u.expr.ti4->get_Template(), lhs);
+      self_ref |= chk_expr_self_ref_templ(u.expr.ti4->get_Template(), lhs, class_member_init);
       // no break
     case OPTYPE_SUBSTR: // ti1 v2 v3
     case OPTYPE_ENCODE: // ti1 [v2] [v3]
-      self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
+      self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs, class_member_init);
       if (u.expr.v2 != NULL) {
-        self_ref |= chk_expr_self_ref_val  (u.expr.v2, lhs);
+        self_ref |= chk_expr_self_ref_val  (u.expr.v2, lhs, class_member_init);
       }
       if (u.expr.v3 != NULL) {
-        self_ref |= chk_expr_self_ref_val  (u.expr.v3, lhs);
+        self_ref |= chk_expr_self_ref_val  (u.expr.v3, lhs, class_member_init);
       }
       break;
 
     case OPTYPE_REGEXP: // ti1 t2 v3
-      self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
-      self_ref |= chk_expr_self_ref_templ(u.expr.t2 ->get_Template(), lhs);
+      self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs, class_member_init);
+      self_ref |= chk_expr_self_ref_templ(u.expr.t2 ->get_Template(), lhs, class_member_init);
       break;
     case OPTYPE_VALUEOF: // ti1 [subrefs2]
       if (u.expr.subrefs2 != NULL) {
         for (size_t i = 0; i < u.expr.subrefs2->get_nof_refs(); ++i) {
           Ttcn::FieldOrArrayRef* subref = u.expr.subrefs2->get_ref(i);
           if (subref->get_type() == Ttcn::FieldOrArrayRef::ARRAY_REF) {
-            self_ref |= chk_expr_self_ref_val(subref->get_val(), lhs);
+            self_ref |= chk_expr_self_ref_val(subref->get_val(), lhs, class_member_init);
           }
         }
       }
@@ -12321,31 +12324,33 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
     case OPTYPE_LENGTHOF: // ti1
     case OPTYPE_SIZEOF: // ti1
     case OPTYPE_TTCN2STRING:
-      self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
+      self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs, class_member_init);
       break;
     case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2] [v3] [v4]
-      self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
+      self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs, class_member_init);
       if (u.expr.v2 != NULL) {
-        self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
+        self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs, class_member_init);
       }
       if (u.expr.v3 != NULL) {
-        self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
+        self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs, class_member_init);
       }
       if (u.expr.v4 != NULL) {
-        self_ref |= chk_expr_self_ref_val(u.expr.v4, lhs);
+        self_ref |= chk_expr_self_ref_val(u.expr.v4, lhs, class_member_init);
       }
       break;
     case OPTYPE_DECVALUE_UNICHAR: { // r1 r2 [v3] [v4] [v5]
-      Common::Assignment *ass = u.expr.r2->get_refd_assignment();
-      self_ref |= (ass == lhs);
+      if (lhs != NULL) {
+        Common::Assignment *ass = u.expr.r2->get_refd_assignment();
+        self_ref |= (ass == lhs);
+      }
       if (u.expr.v3 != NULL) {
-        self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
+        self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs, class_member_init);
       }
       if (u.expr.v4 != NULL) {
-        self_ref |= chk_expr_self_ref_val(u.expr.v4, lhs);
+        self_ref |= chk_expr_self_ref_val(u.expr.v4, lhs, class_member_init);
       }
       if (u.expr.v5 != NULL) {
-        self_ref |= chk_expr_self_ref_val(u.expr.v5, lhs);
+        self_ref |= chk_expr_self_ref_val(u.expr.v5, lhs, class_member_init);
       }
       goto label_r1;
       break; }
@@ -12373,19 +12378,21 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
 
         case Ttcn::LogArgument::L_VAL:
         case Ttcn::LogArgument::L_MATCH:
-          self_ref |= chk_expr_self_ref_val(la->get_val(), lhs);
+          self_ref |= chk_expr_self_ref_val(la->get_val(), lhs, class_member_init);
           break;
 
         case Ttcn::LogArgument::L_REF: {
-          Ttcn::Reference *ref = la->get_ref();
-          Common::Assignment *ass = ref->get_refd_assignment();
-          self_ref |= (ass == lhs);
+          if (lhs != NULL) {
+            Ttcn::Reference *ref = la->get_ref();
+            Common::Assignment *ass = ref->get_refd_assignment();
+            self_ref |= (ass == lhs);
+          }
           break; }
 
         case Ttcn::LogArgument::L_TI: {
           Ttcn::TemplateInstance *ti = la->get_ti();
           Ttcn::Template *t = ti->get_Template();
-          self_ref |= chk_expr_self_ref_templ(t, lhs);
+          self_ref |= chk_expr_self_ref_templ(t, lhs, class_member_init);
           break; }
 
           // no default please
@@ -12394,32 +12401,38 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
       break; }
 
     case OPTYPE_DECODE: { // r1 r2
-      Common::Assignment *ass = u.expr.r2->get_refd_assignment();
-      self_ref |= (ass == lhs);
+      if (lhs != NULL) {
+        Common::Assignment *ass = u.expr.r2->get_refd_assignment();
+        self_ref |= (ass == lhs);
+      }
       if (u.expr.v3 != NULL) {
-        self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
+        self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs, class_member_init);
       }
       if (u.expr.v4 != NULL) {
-        self_ref |= chk_expr_self_ref_val(u.expr.v4, lhs);
+        self_ref |= chk_expr_self_ref_val(u.expr.v4, lhs, class_member_init);
       }
       goto label_r1; }
     case OPTYPE_EXECUTE:       // r1 [v2]
       if (u.expr.v2) {
-        self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
+        self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs, class_member_init);
       }
       label_r1:
       // no break
     case OPTYPE_TMR_READ: {     // r1
-      Common::Assignment *ass = u.expr.r1->get_refd_assignment();
-      self_ref |= (ass == lhs);
+      if (lhs != NULL) {
+        Common::Assignment *ass = u.expr.r1->get_refd_assignment();
+        self_ref |= (ass == lhs);
+      }
       break; }
     case OPTYPE_UNDEF_RUNNING: { // r1 [r2] b4
-      if (u.expr.r2 != NULL) {
-        Common::Assignment *ass2 = u.expr.r2->get_refd_assignment();
-        self_ref |= (ass2 == lhs);
+      if (lhs != NULL) {
+        if (u.expr.r2 != NULL) {
+          Common::Assignment *ass2 = u.expr.r2->get_refd_assignment();
+          self_ref |= (ass2 == lhs);
+        }
+        Common::Assignment *ass = u.expr.r1->get_refd_assignment();
+        self_ref |= (ass == lhs);
       }
-      Common::Assignment *ass = u.expr.r1->get_refd_assignment();
-      self_ref |= (ass == lhs);
       break; }
     
     case OPTYPE_ISCHOSEN_T: // t1 i2
@@ -12429,25 +12442,27 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
       Ttcn::Template *t;
       if (u.expr.v_optype == OPTYPE_ISCHOSEN_T) t = u.expr.t1;
       else t = u.expr.ti1->get_Template();
-      self_ref |= chk_expr_self_ref_templ(t, lhs);
+      self_ref |= chk_expr_self_ref_templ(t, lhs, class_member_init);
       break; }
     case OPTYPE_ISTEMPLATEKIND: // ti1 v2
-      self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
-      self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
+      self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs, class_member_init);
+      self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs, class_member_init);
       break;
     case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
       if (u.expr.v3) {
-        self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
+        self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs, class_member_init);
       }
       // no break
     case OPTYPE_ACTIVATE_REFD: // v1 t_list2
-      self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
+      self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs, class_member_init);
       // TODO t_list2
       break;
     case OPTYPE_OF_CLASS:
     case OPTYPE_CLASS_CASTING: {
-      Common::Assignment *ass = u.expr.r2->get_refd_assignment();
-      self_ref |= (ass == lhs);
+      if (lhs != NULL) {
+        Common::Assignment *ass = u.expr.r2->get_refd_assignment();
+        self_ref |= (ass == lhs);
+      }
       break; }
 
     case NUMBER_OF_OPTYPES: // can never happen
@@ -15969,6 +15984,15 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
   {
     Value *v = get_value_refd_last();
     if (v == this) {
+      Assignment* refd_ass = u.ref.ref->get_refd_assignment();
+      if ((refd_ass->get_asstype() == Assignment::A_CONST ||
+           refd_ass->get_asstype() == Assignment::A_VAR) &&
+          refd_ass->get_my_scope()->get_parent_scope()->is_class_scope()) {
+        Value* v2 = refd_ass->get_Value();
+        if (v2 != NULL && needs_init_precede(v2)) {
+          str = v2->generate_code_init(str, v2->get_lhs_name().c_str());
+        }
+      }
       // the referred value is not available at compile time
       // the code generation is based on the reference
       if (use_runtime_2 && TypeConv::needs_conv_refd(v)) {
diff --git a/compiler2/Value.hh b/compiler2/Value.hh
index 3698d4c1c4bdcd91f76112bd84e1afa74fb68309..1a920e9d6d81b3c374006137577b91c5f2f16519 100644
--- a/compiler2/Value.hh
+++ b/compiler2/Value.hh
@@ -849,12 +849,12 @@ namespace Common {
     /** Check that the value (a V_EXPR) - being used as the RHS - refers to
      *  the LHS of the assignment.
      *  @return true if self-assignment*/
-    bool chk_expr_self_ref(Common::Assignment *lhs);
+    bool chk_expr_self_ref(Common::Assignment *lhs, namedbool class_member_init);
 
     virtual string create_stringRepr();
   private:
-    static bool chk_expr_self_ref_templ(Ttcn::Template *t, Common::Assignment *lhs);
-    static bool chk_expr_self_ref_val  (Common::Value  *v, Common::Assignment *lhs);
+    static bool chk_expr_self_ref_templ(Ttcn::Template *t, Common::Assignment *lhs, namedbool class_member_init);
+    static bool chk_expr_self_ref_val  (Common::Value  *v, Common::Assignment *lhs, namedbool class_member_init);
     string create_stringRepr_unary(const char *operator_str);
     string create_stringRepr_infix(const char *operator_str);
     string create_stringRepr_predef1(const char *function_name);
diff --git a/compiler2/ttcn3/AST_ttcn3.cc b/compiler2/ttcn3/AST_ttcn3.cc
index 723cba45e9394879bef0de188ffec925501122c7..1fa5e499c47e5e915fb34dbaa803d0eac5a40ed9 100644
--- a/compiler2/ttcn3/AST_ttcn3.cc
+++ b/compiler2/ttcn3/AST_ttcn3.cc
@@ -4037,7 +4037,7 @@ namespace Ttcn {
   Def_Const::Def_Const(Identifier *p_id, Type *p_type, Value *p_value)
     : Definition(A_CONST, p_id)
   {
-    if (!p_type || !p_value) FATAL_ERROR("Ttcn::Def_Const::Def_Const()");
+    if (!p_type) FATAL_ERROR("Ttcn::Def_Const::Def_Const()");
     type=p_type;
     type->set_ownertype(Type::OT_CONST_DEF, this);
     value=p_value;
@@ -4059,14 +4059,18 @@ namespace Ttcn {
   {
     Definition::set_fullname(p_fullname);
     type->set_fullname(p_fullname + ".<type>");
-    value->set_fullname(p_fullname);
+    if (value != NULL) {
+      value->set_fullname(p_fullname);
+    }
   }
 
   void Def_Const::set_my_scope(Scope *p_scope)
   {
     Definition::set_my_scope(p_scope);
     type->set_my_scope(p_scope);
-    value->set_my_scope(p_scope);
+    if (value != NULL) {
+      value->set_my_scope(p_scope);
+    }
   }
 
   Setting *Def_Const::get_Setting()
@@ -4101,8 +4105,14 @@ namespace Ttcn {
       id->get_dispname().c_str());
     type->set_genname(_T_, get_genname());
     type->chk();
-    value->set_my_governor(type);
-    type->chk_this_value_ref(value);
+
+    if (value != NULL) {
+      value->set_my_governor(type);
+      type->chk_this_value_ref(value);
+    }
+    else if (!my_scope->is_class_scope()) {
+      error("Missing initial value");
+    }
     checked=true;
     if (w_attrib_path) {
       w_attrib_path->chk_global_attrib(true);
@@ -4134,23 +4144,26 @@ namespace Ttcn {
         t->get_typename().c_str());
       break;
     default:
-      value_under_check = true;
+      if (value != NULL) {
+        value_under_check = true;
+        namedbool class_member_init = my_scope->is_class_scope() ?
+          CLASS_MEMBER_INIT : NOT_CLASS_MEMBER_INIT;
         type->chk_this_value(value, 0, Type::EXPECTED_STATIC_VALUE, WARNING_FOR_INCOMPLETE,
-        OMIT_NOT_ALLOWED, SUB_CHK, has_implicit_omit_attr());
-      value_under_check = false;
-      erroneous_attrs = chk_erroneous_attr(w_attrib_path, type, get_my_scope(),
-        get_fullname(), false);
-      if (erroneous_attrs) value->add_err_descr(NULL, erroneous_attrs->get_err_descr());
-    {
-      ReferenceChain refch(type, "While checking embedded recursions");
-      value->chk_recursions(refch);
-    }
+          OMIT_NOT_ALLOWED, SUB_CHK, has_implicit_omit_attr(), NOT_STR_ELEM, class_member_init);
+        value_under_check = false;
+        erroneous_attrs = chk_erroneous_attr(w_attrib_path, type, get_my_scope(),
+          get_fullname(), false);
+        if (erroneous_attrs) value->add_err_descr(NULL, erroneous_attrs->get_err_descr());
+        ReferenceChain refch(type, "While checking embedded recursions");
+        value->chk_recursions(refch);
+      }
       break;
     }
-    if (!semantic_check_only) {
+    if (!semantic_check_only && value != NULL) {
       value->set_genname_prefix("const_");
       value->set_genname_recursive(get_genname());
-      value->set_code_section(GovernedSimple::CS_PRE_INIT);
+      value->set_code_section(my_scope->is_class_scope() ?
+        GovernedSimple::CS_INIT_CLASS : GovernedSimple::CS_PRE_INIT);
     }
   }
 
@@ -4167,7 +4180,9 @@ namespace Ttcn {
       return false;
     }
     Def_Const *p_def_const = dynamic_cast<Def_Const*>(p_def);
-    if (!p_def_const) FATAL_ERROR("Def_Const::chk_identical()");
+    if (p_def_const == NULL || value == NULL || p_def_const->value == NULL) {
+      FATAL_ERROR("Def_Const::chk_identical()");
+    }
     if (!type->is_identical(p_def_const->type)) {
       const char *dispname_str = id->get_dispname().c_str();
       type->error("Local constant `%s' has type `%s', but the constant "
@@ -4193,15 +4208,20 @@ namespace Ttcn {
     const_def cdef;
     Code::init_cdef(&cdef);
     bool in_class = my_scope->is_class_scope();
-    type->generate_code_object(&cdef, value, in_class);
-    if (value->is_unfoldable()) {
-    cdef.post = update_location_object(cdef.post);
-    cdef.post = value->generate_code_init(cdef.post,
-      value->get_lhs_name().c_str());
-    } else {
-    cdef.init = update_location_object(cdef.init);
-    cdef.init = value->generate_code_init(cdef.init,
-      value->get_lhs_name().c_str());
+    if (value != NULL) {
+      type->generate_code_object(&cdef, value, in_class);
+      if (value->is_unfoldable()) {
+      cdef.post = update_location_object(cdef.post);
+      cdef.post = value->generate_code_init(cdef.post,
+        value->get_lhs_name().c_str());
+      } else {
+      cdef.init = update_location_object(cdef.init);
+      cdef.init = value->generate_code_init(cdef.init,
+        value->get_lhs_name().c_str());
+      }
+    }
+    else {
+      type->generate_code_object(&cdef, my_scope, get_genname(), "const_", false, false, true);
     }
     Code::merge_cdef(target, &cdef, in_class);
     Code::free_cdef(&cdef);
@@ -4214,6 +4234,9 @@ namespace Ttcn {
 
   char *Def_Const::generate_code_str(char *str)
   {
+    if (value == NULL) {
+      FATAL_ERROR("Def_Const::generate_code_str");
+    }
     const string& t_genname = get_genname();
     const char *genname_str = t_genname.c_str();
     if (value->has_single_expr()) {
@@ -4237,6 +4260,9 @@ namespace Ttcn {
 
   void Def_Const::ilt_generate_code(ILT *ilt)
   {
+    if (value == NULL) {
+      FATAL_ERROR("Def_Const::ilt_generate_code");
+    }
     const string& t_genname = get_genname();
     const char *genname_str = t_genname.c_str();
     char*& def=ilt->get_out_def();
@@ -4257,7 +4283,9 @@ namespace Ttcn {
   {
     DEBUG(level, "Constant: %s @%p", id->get_dispname().c_str(), static_cast<const void*>(this));
     type->dump(level + 1);
-    value->dump(level + 1);
+    if (value != NULL) {
+      value->dump(level + 1);
+    }
   }
 
   // =================================
@@ -4649,7 +4677,9 @@ namespace Ttcn {
         type->chk_this_template_ref(def_template);
         checked = true;
         type->chk_this_template_generic(def_template, INCOMPLETE_ALLOWED,
-          OMIT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, IMPLICIT_OMIT == has_implicit_omit_attr() ? IMPLICIT_OMIT : NOT_IMPLICIT_OMIT, 0);
+          OMIT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK,
+          IMPLICIT_OMIT == has_implicit_omit_attr() ? IMPLICIT_OMIT : NOT_IMPLICIT_OMIT,
+          NOT_CLASS_MEMBER_INIT, 0);
         type->chk_this_template_incorrect_field();
         if (!semantic_check_only) {
           def_template->set_genname_prefix("modulepar_");
@@ -4733,7 +4763,7 @@ namespace Ttcn {
     body(p_body), template_restriction(p_template_restriction),
     gen_restriction_check(false)
   {
-    if (!p_type || !p_body) FATAL_ERROR("Ttcn::Def_Template::Def_Template()");
+    if (!p_type) FATAL_ERROR("Ttcn::Def_Template::Def_Template()");
     type->set_ownertype(Type::OT_TEMPLATE_DEF, this);
     if (fp_list) fp_list->set_my_def(this);
   }
@@ -4758,7 +4788,9 @@ namespace Ttcn {
     if (fp_list) fp_list->set_fullname(p_fullname + ".<formal_par_list>");
     if (derived_ref)
       derived_ref->set_fullname(p_fullname + ".<derived_reference>");
-    body->set_fullname(p_fullname);
+    if (body != NULL) {
+      body->set_fullname(p_fullname);
+    }
   }
 
   void Def_Template::set_my_scope(Scope *p_scope)
@@ -4771,8 +4803,12 @@ namespace Ttcn {
     if (derived_ref) derived_ref->set_my_scope(&bridgeScope);
     if (fp_list) {
       fp_list->set_my_scope(&bridgeScope);
-      body->set_my_scope(fp_list);
-    } else body->set_my_scope(&bridgeScope);
+      if (body != NULL) {
+        body->set_my_scope(fp_list);
+      }
+    } else if (body != NULL) {
+      body->set_my_scope(&bridgeScope);
+    }
   }
 
   Setting *Def_Template::get_Setting()
@@ -4827,21 +4863,29 @@ namespace Ttcn {
       fp_list->chk(asstype);
       if (local_scope) error("Parameterized local template `%s' not supported",
         id->get_dispname().c_str());
-      body->set_formalparlist(fp_list);
+      if (body != NULL) {
+        body->set_formalparlist(fp_list);
+      }
     }
 
     // Merge the elements of "all from" into the list
-    body->flatten(false);
+    if (body != NULL) {
+      body->flatten(false);
 
-    body->set_my_governor(type);
+      body->set_my_governor(type);
+
+      if (body->get_templatetype() == Template::CSTR_PATTERN &&
+        type->get_type_refd_last()->get_typetype() == Type::T_USTR) {
+        body->set_templatetype(Template::USTR_PATTERN);
+        body->get_ustr_pattern()->set_pattern_type(PatternString::USTR_PATTERN);
+      }
 
-    if (body->get_templatetype() == Template::CSTR_PATTERN &&
-      type->get_type_refd_last()->get_typetype() == Type::T_USTR) {
-      body->set_templatetype(Template::USTR_PATTERN);
-      body->get_ustr_pattern()->set_pattern_type(PatternString::USTR_PATTERN);
+      type->chk_this_template_ref(body);
+    }
+    else if (!my_scope->is_class_scope()) {
+      error("Missing template body");
     }
 
-    type->chk_this_template_ref(body);
     Type *t = type->get_type_refd_last();
     if (t->get_typetype() == Type::T_PORT) {
       error("Template cannot be defined for port type `%s'",
@@ -4851,66 +4895,74 @@ namespace Ttcn {
       error("Template cannot be defined for class type `%s'",
         t->get_typename().c_str());
     }
+    type->chk_this_template_incorrect_field();
     chk_modified();
     chk_recursive_derivation();
-    type->chk_this_template_generic(body,
-      derived_ref != NULL ? INCOMPLETE_ALLOWED : WARNING_FOR_INCOMPLETE,
-      OMIT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK,
-      IMPLICIT_OMIT == has_implicit_omit_attr() ? IMPLICIT_OMIT : NOT_IMPLICIT_OMIT, 0);
-    type->chk_this_template_incorrect_field();
-    erroneous_attrs = chk_erroneous_attr(w_attrib_path, type, get_my_scope(),
-      get_fullname(), false);
-    if (erroneous_attrs) body->add_err_descr(NULL, erroneous_attrs->get_err_descr());
 
-    {
-      ReferenceChain refch(type, "While checking embedded recursions");
-      body->chk_recursions(refch);
-    }
-    if (template_restriction!=TR_NONE) {
-      Error_Context ec(this, "While checking template restriction `%s'",
-                       Template::get_restriction_name(template_restriction));
-      gen_restriction_check =
-        body->chk_restriction("template definition", template_restriction, body);
-      if (fp_list && template_restriction!=TR_PRESENT) {
-        size_t nof_fps = fp_list->get_nof_fps();
-        for (size_t i=0; i<nof_fps; i++) {
-          FormalPar* fp = fp_list->get_fp_byIndex(i);
-          // if formal par is not template then skip restriction checking,
-          // templates can have only `in' parameters
-          if (fp->get_asstype()!=A_PAR_TEMPL_IN) continue;
-          template_restriction_t fp_tr = fp->get_template_restriction();
-          switch (template_restriction) {
-          case TR_VALUE:
-          case TR_OMIT:
-            switch (fp_tr) {
+    if (body != NULL) {
+      namedbool class_member_init = my_scope->is_class_scope() ?
+        CLASS_MEMBER_INIT : NOT_CLASS_MEMBER_INIT;
+      type->chk_this_template_generic(body,
+        derived_ref != NULL ? INCOMPLETE_ALLOWED : WARNING_FOR_INCOMPLETE,
+        OMIT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK,
+        IMPLICIT_OMIT == has_implicit_omit_attr() ? IMPLICIT_OMIT : NOT_IMPLICIT_OMIT,
+        class_member_init, 0);
+      erroneous_attrs = chk_erroneous_attr(w_attrib_path, type, get_my_scope(),
+        get_fullname(), false);
+      if (erroneous_attrs) body->add_err_descr(NULL, erroneous_attrs->get_err_descr());
+      {
+        ReferenceChain refch(type, "While checking embedded recursions");
+        body->chk_recursions(refch);
+      }
+
+      if (template_restriction!=TR_NONE) {
+        Error_Context ec(this, "While checking template restriction `%s'",
+                         Template::get_restriction_name(template_restriction));
+        gen_restriction_check =
+          body->chk_restriction("template definition", template_restriction, body);
+        if (fp_list && template_restriction!=TR_PRESENT) {
+          size_t nof_fps = fp_list->get_nof_fps();
+          for (size_t i=0; i<nof_fps; i++) {
+            FormalPar* fp = fp_list->get_fp_byIndex(i);
+            // if formal par is not template then skip restriction checking,
+            // templates can have only `in' parameters
+            if (fp->get_asstype()!=A_PAR_TEMPL_IN) continue;
+            template_restriction_t fp_tr = fp->get_template_restriction();
+            switch (template_restriction) {
             case TR_VALUE:
             case TR_OMIT:
-              // allowed
-              break;
-            case TR_PRESENT:
-              fp->error("Formal parameter with template restriction `%s' "
-                "not allowed here", Template::get_restriction_name(fp_tr));
-              break;
-            case TR_NONE:
-              fp->error("Formal parameter without template restriction "
-                "not allowed here");
+              switch (fp_tr) {
+              case TR_VALUE:
+              case TR_OMIT:
+                // allowed
+                break;
+              case TR_PRESENT:
+                fp->error("Formal parameter with template restriction `%s' "
+                  "not allowed here", Template::get_restriction_name(fp_tr));
+                break;
+              case TR_NONE:
+                fp->error("Formal parameter without template restriction "
+                  "not allowed here");
+                break;
+              default:
+                FATAL_ERROR("Ttcn::Def_Template::chk()");
+              }
               break;
             default:
               FATAL_ERROR("Ttcn::Def_Template::chk()");
             }
-            break;
-          default:
-            FATAL_ERROR("Ttcn::Def_Template::chk()");
           }
         }
       }
-    }
-    if (!semantic_check_only) {
-      if (fp_list) fp_list->set_genname(t_genname);
-      body->set_genname_prefix("template_");
-      body->set_genname_recursive(t_genname);
-      body->set_code_section(fp_list ? GovernedSimple::CS_INLINE :
-        GovernedSimple::CS_POST_INIT);
+
+      if (!semantic_check_only) {
+        if (fp_list) fp_list->set_genname(t_genname);
+        body->set_genname_prefix("template_");
+        body->set_genname_recursive(t_genname);
+        body->set_code_section(fp_list ? GovernedSimple::CS_INLINE :
+          (my_scope->is_class_scope() ?
+          GovernedSimple::CS_INIT_CLASS : GovernedSimple::CS_POST_INIT));
+      }
     }
 
   }
@@ -4974,7 +5026,9 @@ namespace Ttcn {
       return;
     }
     base_template = dynamic_cast<Def_Template*>(ass);
-    if (!base_template) FATAL_ERROR("Def_Template::chk_modified()");
+    if (base_template == NULL || body == NULL) {
+      FATAL_ERROR("Def_Template::chk_modified()");
+    }
     Type *base_type = base_template->get_Type();
     TypeCompatInfo info_base(my_scope->get_scope_mod(), type, base_type, true,
                              false, true);
@@ -5091,7 +5145,7 @@ namespace Ttcn {
   void Def_Template::generate_code(output_struct *target, bool)
   {
     type->generate_code(target);
-    if (body->get_err_descr() != NULL && body->get_err_descr()->has_descr(NULL)) {
+    if (body != NULL && body->get_err_descr() != NULL && body->get_err_descr()->has_descr(NULL)) {
         target->functions.post_init = body->get_err_descr()->generate_code_init_str(
           NULL, target->functions.post_init, body->get_lhs_name());
     }
@@ -5188,56 +5242,61 @@ namespace Ttcn {
       const_def cdef;
       Code::init_cdef(&cdef);
       bool in_class = my_scope->is_class_scope();
-      type->generate_code_object(&cdef, body, in_class);
-      cdef.init = update_location_object(cdef.init);
-      if (base_template) {
-        // modified template
-        if (base_template->my_scope->get_scope_mod_gen() ==
-            my_scope->get_scope_mod_gen()) {
-          // if the base template is in the same module its body has to be
-          // initialized first
-          cdef.init = base_template->body->generate_code_init(cdef.init,
-            base_template->body->get_lhs_name().c_str());
+      if (body != NULL) {
+        type->generate_code_object(&cdef, body, in_class);
+        cdef.init = update_location_object(cdef.init);
+        if (base_template) {
+          // modified template
+          if (base_template->my_scope->get_scope_mod_gen() ==
+              my_scope->get_scope_mod_gen()) {
+            // if the base template is in the same module its body has to be
+            // initialized first
+            cdef.init = base_template->body->generate_code_init(cdef.init,
+              base_template->body->get_lhs_name().c_str());
+          }
+          if (use_runtime_2 && body->get_needs_conversion()) {
+            Type *body_type = body->get_my_governor()->get_type_refd_last();
+            Type *base_type = base_template->body->get_my_governor()
+              ->get_type_refd_last();
+            if (!body_type || !base_type)
+              FATAL_ERROR("Def_Template::generate_code()");
+            const string& tmp_id = body->get_temporary_id();
+            const char *tmp_id_str = tmp_id.c_str();
+            // base template initialization
+            cdef.init = mputprintf(cdef.init,
+              "%s %s;\n"
+              "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
+              "and `%s' are not compatible at run-time\");\n"
+              "%s = %s;\n",
+              body_type->get_genname_template(my_scope).c_str(), tmp_id_str,
+              TypeConv::get_conv_func(base_type, body_type, my_scope
+              ->get_scope_mod()).c_str(), tmp_id_str, base_template
+              ->get_genname_from_scope(my_scope).c_str(), base_type
+              ->get_typename().c_str(), body_type->get_typename().c_str(),
+              body->get_lhs_name().c_str(), tmp_id_str);
+          } else {
+            cdef.init = mputprintf(cdef.init, "%s = %s;\n",
+              body->get_lhs_name().c_str(),
+              base_template->get_genname_from_scope(my_scope).c_str());
+          }
         }
-        if (use_runtime_2 && body->get_needs_conversion()) {
-          Type *body_type = body->get_my_governor()->get_type_refd_last();
-          Type *base_type = base_template->body->get_my_governor()
-            ->get_type_refd_last();
-          if (!body_type || !base_type)
-            FATAL_ERROR("Def_Template::generate_code()");
-          const string& tmp_id = body->get_temporary_id();
-          const char *tmp_id_str = tmp_id.c_str();
-          // base template initialization
-          cdef.init = mputprintf(cdef.init,
-            "%s %s;\n"
-            "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
-            "and `%s' are not compatible at run-time\");\n"
-            "%s = %s;\n",
-            body_type->get_genname_template(my_scope).c_str(), tmp_id_str,
-            TypeConv::get_conv_func(base_type, body_type, my_scope
-            ->get_scope_mod()).c_str(), tmp_id_str, base_template
-            ->get_genname_from_scope(my_scope).c_str(), base_type
-            ->get_typename().c_str(), body_type->get_typename().c_str(),
-            body->get_lhs_name().c_str(), tmp_id_str);
-        } else {
-          cdef.init = mputprintf(cdef.init, "%s = %s;\n",
-            body->get_lhs_name().c_str(),
-            base_template->get_genname_from_scope(my_scope).c_str());
+        if (use_runtime_2 && TypeConv::needs_conv_refd(body))
+          cdef.init = TypeConv::gen_conv_code_refd(cdef.init,
+            body->get_lhs_name().c_str(), body);
+        else
+          cdef.init = body->generate_code_init(cdef.init,
+            body->get_lhs_name().c_str());
+        if (template_restriction != TR_NONE && gen_restriction_check)
+          cdef.init = Template::generate_restriction_check_code(cdef.init,
+            body->get_lhs_name().c_str(), template_restriction);
+        if (body->get_err_descr() != NULL && body->get_err_descr()->has_descr(NULL)) {
+          cdef.init = mputprintf(cdef.init, "%s.set_err_descr(&%s_%lu_err_descr);\n",
+            body->get_lhs_name().c_str(), body->get_lhs_name().c_str(),
+            static_cast<unsigned long>( body->get_err_descr()->get_descr_index(NULL) ));
         }
       }
-      if (use_runtime_2 && TypeConv::needs_conv_refd(body))
-        cdef.init = TypeConv::gen_conv_code_refd(cdef.init,
-          body->get_lhs_name().c_str(), body);
-      else
-        cdef.init = body->generate_code_init(cdef.init,
-          body->get_lhs_name().c_str());
-      if (template_restriction != TR_NONE && gen_restriction_check)
-        cdef.init = Template::generate_restriction_check_code(cdef.init,
-          body->get_lhs_name().c_str(), template_restriction);
-      if (body->get_err_descr() != NULL && body->get_err_descr()->has_descr(NULL)) {
-        cdef.init = mputprintf(cdef.init, "%s.set_err_descr(&%s_%lu_err_descr);\n",
-          body->get_lhs_name().c_str(), body->get_lhs_name().c_str(),
-          static_cast<unsigned long>( body->get_err_descr()->get_descr_index(NULL) ));
+      else { // no template body
+        type->generate_code_object(&cdef, my_scope, get_genname(), "template_", true, false, true);
       }
       char*& header = in_class ? target->header.class_defs : target->header.global_vars;
       header = mputstr(header, cdef.decl);
@@ -5255,6 +5314,9 @@ namespace Ttcn {
 
   char *Def_Template::generate_code_str(char *str)
   {
+    if (body == NULL) {
+      FATAL_ERROR("Def_Template::generate_code_str");
+    }
     if (fp_list) {
       const char *dispname_str = id->get_dispname().c_str();
       NOTSUPP("Code generation for parameterized local template `%s'",
@@ -5322,6 +5384,9 @@ namespace Ttcn {
 
   void Def_Template::ilt_generate_code(ILT *ilt)
   {
+    if (body == NULL) {
+      FATAL_ERROR("Def_Template::ilt_generate_code");
+    }
     char*& def=ilt->get_out_def();
     char*& init=ilt->get_out_branches();
     if (fp_list) {
@@ -5361,7 +5426,9 @@ namespace Ttcn {
       DEBUG(level + 1, "restriction: %s",
         Template::get_restriction_name(template_restriction));
     type->dump(level + 1);
-    body->dump(level + 1);
+    if (body != NULL) {
+      body->dump(level + 1);
+    }
   }
 
   // =================================
@@ -5407,6 +5474,22 @@ namespace Ttcn {
     return type;
   }
 
+  Value* Def_Var::get_Value()
+  {
+    chk();
+    return initial_value;
+  }
+
+  Value* Def_Var::steal_Value()
+  {
+    if (!checked) {
+      FATAL_ERROR("Def_Var::steal_Value");
+    }
+    Value* ret_val = initial_value;
+    initial_value = NULL;
+    return ret_val;
+  }
+
   void Def_Var::chk()
   {
     if(checked) return;
@@ -5435,12 +5518,16 @@ namespace Ttcn {
     if (initial_value) {
       initial_value->set_my_governor(type);
       type->chk_this_value_ref(initial_value);
+      namedbool class_member_init = my_scope->is_class_scope() ?
+        CLASS_MEMBER_INIT : NOT_CLASS_MEMBER_INIT;
       type->chk_this_value(initial_value, this, is_local() ?
         Type::EXPECTED_DYNAMIC_VALUE : Type::EXPECTED_STATIC_VALUE,
-        INCOMPLETE_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
+        INCOMPLETE_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK, NOT_IMPLICIT_OMIT,
+        NOT_STR_ELEM, class_member_init);
       if (!semantic_check_only) {
         initial_value->set_genname_recursive(get_genname());
-        initial_value->set_code_section(GovernedSimple::CS_INLINE);
+        initial_value->set_code_section(my_scope->is_class_scope() ?
+          GovernedSimple::CS_INIT_CLASS : GovernedSimple::CS_INLINE);
       }
     }
       break;
@@ -5656,6 +5743,22 @@ namespace Ttcn {
     return type;
   }
 
+  Template* Def_Var_Template::get_Template()
+  {
+    chk();
+    return initial_value;
+  }
+
+  Template* Def_Var_Template::steal_Template()
+  {
+    if (!checked) {
+      FATAL_ERROR("Def_Var_Template::steal_Template");
+    }
+    Template* ret_val = initial_value;
+    initial_value = NULL;
+    return ret_val;
+  }
+
   void Def_Var_Template::chk()
   {
     if(checked) return;
@@ -5686,15 +5789,18 @@ namespace Ttcn {
       }
 
       type->chk_this_template_ref(initial_value);
+      namedbool class_member_init = my_scope->is_class_scope() ?
+        CLASS_MEMBER_INIT : NOT_CLASS_MEMBER_INIT;
       type->chk_this_template_generic(initial_value, INCOMPLETE_ALLOWED,
-        OMIT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, IMPLICIT_OMIT, 0);
+        OMIT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, IMPLICIT_OMIT, class_member_init, 0);
       gen_restriction_check =
         initial_value->chk_restriction("template variable definition",
                                        template_restriction, initial_value);
       type->chk_this_template_incorrect_field();
       if (!semantic_check_only) {
         initial_value->set_genname_recursive(get_genname());
-        initial_value->set_code_section(GovernedSimple::CS_INLINE);
+        initial_value->set_code_section(my_scope->is_class_scope() ?
+          GovernedSimple::CS_INIT_CLASS : GovernedSimple::CS_INLINE);
       }
     }
     if (w_attrib_path) {
@@ -7032,7 +7138,6 @@ namespace Ttcn {
         " in clause 16.1.4 of the TTCN-3 core language standard (ES 201 873-1)",
         id->get_dispname().c_str());
     }
-    ClassTypeBody* my_class = my_scope->get_scope_class();
 
     // `runs on' clause and `port' clause are mutually exclusive
     if (runs_on_ref && port_ref) {
@@ -9116,6 +9221,10 @@ namespace Ttcn {
     delete fp_list;
     delete base_call;
     delete block;
+    for (size_t i = 0; i < uninit_members.size(); ++i) {
+      delete uninit_members.get_nth_elem(i);
+    }
+    uninit_members.clear();
   }
   
   Def_Constructor* Def_Constructor::clone() const
@@ -9157,6 +9266,11 @@ namespace Ttcn {
     return fp_list;
   }
   
+  void Def_Constructor::add_uninit_member(const Identifier* p_member_id, bool p_is_template)
+  {
+    uninit_members.add(p_member_id, new bool(p_is_template));
+  }
+
   void Def_Constructor::chk()
   {
     if (checked) {
@@ -9238,6 +9352,16 @@ namespace Ttcn {
       target->temp.constructor_block = fp_list->generate_shadow_objects(
         target->temp.constructor_block);
       target->temp.constructor_block = mputstr(target->temp.constructor_block, block_gen_str);
+
+      for (size_t i = 0; i < uninit_members.size(); ++i) {
+        const Identifier* member_id = uninit_members.get_nth_key(i);
+        bool is_template = *uninit_members.get_nth_elem(i);
+        target->temp.constructor_block = mputprintf(target->temp.constructor_block,
+          "if (!%s.is_bound()) TTCN_error(\"%s member `%s' is not initialized "
+          "by the end of the constructor's execution.\");\n",
+          member_id->get_name().c_str(), is_template ? "Template" : "Constant",
+          member_id->get_dispname().c_str());
+      }
     }
     Free(block_gen_str);
   }
diff --git a/compiler2/ttcn3/AST_ttcn3.hh b/compiler2/ttcn3/AST_ttcn3.hh
index f74b68f6ee91d734d0f4968211b8a2f0f74c0a0a..820da52e48f82cbdc773360bd8d1582ed5ff6a9d 100644
--- a/compiler2/ttcn3/AST_ttcn3.hh
+++ b/compiler2/ttcn3/AST_ttcn3.hh
@@ -1184,6 +1184,8 @@ namespace Ttcn {
     virtual void set_fullname(const string& p_fullname);
     virtual void set_my_scope(Scope *p_scope);
     virtual Type *get_Type();
+    virtual Value* get_Value();
+    virtual Value* steal_Value();
     virtual void chk();
     virtual bool chk_identical(Definition *p_def);
     virtual void generate_code(output_struct *target, bool clean_up = false);
@@ -1237,6 +1239,8 @@ namespace Ttcn {
     virtual void set_fullname(const string& p_fullname);
     virtual void set_my_scope(Scope *p_scope);
     virtual Type *get_Type();
+    virtual Template* get_Template();
+    virtual Template* steal_Template();
     virtual void chk();
     virtual bool chk_identical(Definition *p_def);
     virtual void generate_code(output_struct *target, bool clean_up = false);
@@ -1791,6 +1795,9 @@ namespace Ttcn {
     
     NameBridgingScope bridgeScope;
     
+    /** IDs of members that need to be initialized by the end of the constructor's execution */
+    map<const Identifier*, bool> uninit_members;
+
     /// Copy constructor disabled
     Def_Constructor(const Def_Constructor& p);
     /// %Assignment disabled
@@ -1804,6 +1811,7 @@ namespace Ttcn {
     virtual void set_my_scope(Scope* p_scope);
     virtual FormalParList* get_FormalParList();
     virtual Reference* get_base_call() const { return base_call; }
+    virtual void add_uninit_member(const Identifier* p_member_id, bool p_is_template);
     virtual void chk();
     virtual void generate_code(output_struct *target, bool clean_up = false);
     virtual void set_parent_path(WithAttribPath* p_path);
diff --git a/compiler2/ttcn3/PatternString.cc b/compiler2/ttcn3/PatternString.cc
index bf5ce0590cab52fa5a921b876dae830f44985a27..032919cbe4a9560eae3da1f845eb277078e8b1a6 100644
--- a/compiler2/ttcn3/PatternString.cc
+++ b/compiler2/ttcn3/PatternString.cc
@@ -50,7 +50,8 @@ namespace Ttcn {
     ps_elem_t* clone() const;
     void set_fullname(const string& p_fullname);
     void set_my_scope(Scope *p_scope);
-    void chk_ref(PatternString::pstr_type_t pstr_type, Type::expected_value_t expected_value);
+    void chk_ref(PatternString::pstr_type_t pstr_type, Type::expected_value_t expected_value,
+      namedbool class_member_init);
     void set_code_section(GovernedSimple::code_section_t p_code_section);
   };
 
@@ -128,7 +129,8 @@ namespace Ttcn {
     } // switch kind
   }
 
-  void PatternString::ps_elem_t::chk_ref(PatternString::pstr_type_t pstr_type, Type::expected_value_t expected_value)
+  void PatternString::ps_elem_t::chk_ref(PatternString::pstr_type_t pstr_type, Type::expected_value_t expected_value,
+                                         namedbool class_member_init)
   {
     if (kind != PSE_REF) FATAL_ERROR("PatternString::ps_elem_t::chk_ref()");
     Value* v = 0;
@@ -181,7 +183,7 @@ namespace Ttcn {
       Template* templ = ass->get_Template();
       refcheckertype->chk_this_template_ref(templ);
       refcheckertype->chk_this_template_generic(templ, INCOMPLETE_ALLOWED,
-        OMIT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, NOT_IMPLICIT_OMIT, 0);
+        OMIT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, NOT_IMPLICIT_OMIT, class_member_init, 0);
       switch (templ->get_templatetype()) {
       case Template::SPECIFIC_VALUE:
         v_last = templ->get_specific_value();
@@ -234,7 +236,8 @@ namespace Ttcn {
       v->set_my_scope(ref->get_my_scope());
       v->set_location(*ref);
       refcheckertype->chk_this_value(v, 0, expected_value,
-        INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
+        INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK,
+        NOT_IMPLICIT_OMIT, NOT_STR_ELEM, class_member_init);
       v_last = v->get_value_refd_last();
     }
     }
@@ -403,7 +406,7 @@ namespace Ttcn {
     return false;
   }
 
-  void PatternString::chk_refs(Type::expected_value_t expected_value)
+  void PatternString::chk_refs(Type::expected_value_t expected_value, namedbool class_member_init)
   {
     for(size_t i=0; i<elems.size(); i++) {
       ps_elem_t *pse=elems[i];
@@ -414,7 +417,7 @@ namespace Ttcn {
         /* actually, not supported */
         break;
       case ps_elem_t::PSE_REF:
-        pse->chk_ref(pattern_type, expected_value);
+        pse->chk_ref(pattern_type, expected_value, class_member_init);
         break;
       } // switch kind
     } // for
diff --git a/compiler2/ttcn3/PatternString.hh b/compiler2/ttcn3/PatternString.hh
index 7ac9dda0bc76794e93939a6e5c5ec007c8579f61..ba1903f9252bd7ff0160ec0118800549c0d84bfb 100644
--- a/compiler2/ttcn3/PatternString.hh
+++ b/compiler2/ttcn3/PatternString.hh
@@ -78,7 +78,8 @@ namespace Ttcn {
     /** Returns whether the pattern contains embedded references */
     bool has_refs() const;
     /** Checks the embedded referenced values */
-    void chk_refs(Type::expected_value_t expected_value=Type::EXPECTED_DYNAMIC_VALUE);
+    void chk_refs(Type::expected_value_t expected_value=Type::EXPECTED_DYNAMIC_VALUE,
+      namedbool class_member_init = NOT_CLASS_MEMBER_INIT);
     void chk_recursions(ReferenceChain& refch);
     /** Checks the pattern by translating it to POSIX regexp */
     void chk_pattern();
diff --git a/compiler2/ttcn3/Statement.cc b/compiler2/ttcn3/Statement.cc
index 830c41368161e44ab066692be99d5d8f5f24bbb4..5e097921cf750f12de6468f8ac9e6afc49fa3d67 100644
--- a/compiler2/ttcn3/Statement.cc
+++ b/compiler2/ttcn3/Statement.cc
@@ -4088,7 +4088,7 @@ error:
 	returnexpr.t->set_my_governor(return_type);
 	return_type->chk_this_template_ref(returnexpr.t);
 	return_type->chk_this_template_generic(returnexpr.t, INCOMPLETE_NOT_ALLOWED,
-	  OMIT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, NOT_IMPLICIT_OMIT, 0);
+	  OMIT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, NOT_IMPLICIT_OMIT, NOT_CLASS_MEMBER_INIT, 0);
         Def_Function_Base* dfb = dynamic_cast<Def_Function_Base*>(my_def);
         if (!dfb) FATAL_ERROR("Statement::chk_return()");
         returnexpr.gen_restriction_check =
@@ -9784,7 +9784,7 @@ error:
     self_ref |= type->chk_this_template_generic(templ, INCOMPLETE_ALLOWED,
       (type->get_parent_type() != NULL && !type->is_optional_field()) ?
       OMIT_NOT_ALLOWED : OMIT_ALLOWED,
-      ANY_OR_OMIT_ALLOWED, SUB_CHK, NOT_IMPLICIT_OMIT, lhs);
+      ANY_OR_OMIT_ALLOWED, SUB_CHK, NOT_IMPLICIT_OMIT, NOT_CLASS_MEMBER_INIT, lhs);
     chk_template_restriction();
     return;
   error:
diff --git a/compiler2/ttcn3/TtcnTemplate.cc b/compiler2/ttcn3/TtcnTemplate.cc
index d56c2a1dd394301943f8c10dfd18b53552e270d4..01ffcefd04c2c8d031c97168a6af9b337af2af9c 100644
--- a/compiler2/ttcn3/TtcnTemplate.cc
+++ b/compiler2/ttcn3/TtcnTemplate.cc
@@ -1613,8 +1613,11 @@ namespace Ttcn {
         // escape from invalid recursion loops
         if (templatetype != TEMPLATE_REFD) return this;
         if (!t_ass) FATAL_ERROR("Template::get_template_refd_last()");
-        if (t_ass->get_asstype() != Common::Assignment::A_TEMPLATE) {
+        if (t_ass->get_asstype() != Common::Assignment::A_TEMPLATE ||
+            t_ass->get_my_scope()->get_parent_scope()->is_class_scope()) {
           // return this if the reference does not point to a template
+          // (also, class members are considered unfoldable, because their initial
+          // values can be changed in the constructor)
           u.ref.refd_last = this;
           return u.ref.refd_last;
         }
@@ -1961,7 +1964,8 @@ namespace Ttcn {
     if (u.ref.refd) return u.ref.refd;
     Common::Assignment *ass = u.ref.ref->get_refd_assignment();
     if (!ass) FATAL_ERROR("Template::get_template_refd()");
-    if(ass->get_asstype() == Common::Assignment::A_TEMPLATE) {
+    if (ass->get_asstype() == Common::Assignment::A_TEMPLATE &&
+        ass->get_Template() != NULL) {
       FieldOrArrayRefs *subrefs = u.ref.ref->get_subrefs();
       Template *asst = ass->get_Template();
       Template *t   = asst->get_refd_sub_template(
@@ -3896,7 +3900,7 @@ end:
       str = mputprintf(str, "%s%s = %s;\n", preamble.c_str(), name, expr.c_str());
       break; }
     case SPECIFIC_VALUE:
-      if (get_code_section() == CS_POST_INIT)
+      if (get_code_section() == CS_POST_INIT || get_code_section() == CS_INIT_CLASS)
         str = u.specific_value->rearrange_init_code(str, my_scope->get_scope_mod_gen());
       str = u.specific_value->generate_code_init(str, name);
       break;
@@ -4063,10 +4067,12 @@ end:
       expression_struct expr;
       Code::init_expr(&expr);
       bool use_ref_for_codegen = true;
-      if (get_code_section() == CS_POST_INIT) {
+      if (get_code_section() == CS_POST_INIT || get_code_section() == CS_INIT_CLASS) {
         // the referencing template is a part of a non-parameterized template
         Common::Assignment *ass = u.ref.ref->get_refd_assignment();
-        if (ass->get_asstype() == Common::Assignment::A_TEMPLATE) {
+        if (ass->get_asstype() == Common::Assignment::A_TEMPLATE ||
+            (get_code_section() == CS_INIT_CLASS &&
+             ass->get_asstype() == Common::Assignment::A_VAR_TEMPLATE)) {
           // the reference points to (a field of) a template
           if (ass->get_FormalParList()) {
             // the referred template is parameterized
@@ -4166,7 +4172,9 @@ end:
          *  - the referenced definition is not a template
          *  - the referenced template is parameterized or
          *  - the referenced template is in different module */
-        if (ass->get_asstype() == Common::Assignment::A_TEMPLATE &&
+        if ((ass->get_asstype() == Common::Assignment::A_TEMPLATE ||
+             (ass->get_asstype() == Common::Assignment::A_VAR_TEMPLATE &&
+              ass->get_my_scope()->is_class_scope())) &&
           ass->get_FormalParList() == 0 &&
           ass->get_my_scope()->get_scope_mod_gen() ==
             my_scope->get_scope_mod_gen()) {
@@ -6019,7 +6027,7 @@ compile_time:
     return template_body->get_expr_governor(exp_val);
   }
 
-  void TemplateInstance::chk(Type *governor)
+  void TemplateInstance::chk(Type *governor, namedbool class_member_init)
   {
     if (!governor) FATAL_ERROR("TemplateInstance::chk()");
     if (template_body->get_templatetype() == Template::IMPLICATION_MATCH) {
@@ -6044,7 +6052,7 @@ compile_time:
     governor->chk_this_template_ref(template_body);
     governor->chk_this_template_generic(template_body,
       (derived_reference != 0 ? INCOMPLETE_ALLOWED : INCOMPLETE_NOT_ALLOWED),
-      OMIT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, NOT_IMPLICIT_OMIT, 0);
+      OMIT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, NOT_IMPLICIT_OMIT, class_member_init, 0);
   }
 
   Type *TemplateInstance::chk_Type(Type *governor)
diff --git a/compiler2/ttcn3/TtcnTemplate.hh b/compiler2/ttcn3/TtcnTemplate.hh
index 20b1857d3c63123c473e83b64c02d0ffc8476e61..8086b596c25fea47569eb04db9928d269b5d7666 100644
--- a/compiler2/ttcn3/TtcnTemplate.hh
+++ b/compiler2/ttcn3/TtcnTemplate.hh
@@ -626,7 +626,7 @@ namespace Ttcn {
     Type *get_expr_governor(Type::expected_value_t exp_val);
 
     /** Checks the entire template instance against \a governor. */
-    void chk(Type *governor);
+    void chk(Type *governor, namedbool class_member_init = NOT_CLASS_MEMBER_INIT);
     /** Checks the member \a type (if present) against \a governor.
      *  Returns the type that shall be considered in further checks. */
     Type *chk_Type(Type *governor);
diff --git a/compiler2/ttcn3/Ttcnstuff.cc b/compiler2/ttcn3/Ttcnstuff.cc
index 53b32fc3c4e5236d710d40d126634f96aa237b62..a9c5e8ae9900c823c9e0d5dfca1ab95c2c6fb529 100644
--- a/compiler2/ttcn3/Ttcnstuff.cc
+++ b/compiler2/ttcn3/Ttcnstuff.cc
@@ -3845,35 +3845,62 @@ namespace Ttcn {
       if (!external) {
         block = new StatementBlock();
         for (size_t i = 0; i < members->get_nof_asss(); ++i) {
-          // note: the Definitions class rearranges its element alphabetically;
+          // note: the Definitions class rearranges its elements alphabetically;
           // here the members must be accessed in their original order
           Common::Assignment* member = members->get_ass_byIndex(i, false);
           bool is_template = false;
+          TemplateInstance* def_val = NULL;
           switch (member->get_asstype()) {
+          case Common::Assignment::A_CONST:
+            if (member->get_Value() != NULL) {
+              continue; // the constant has already been initialized at its definition
+            }
+            break;
           case Common::Assignment::A_TEMPLATE:
+            if (member->get_Template() != NULL) {
+              continue; // the template has already been initialized at its definition
+            }
+            is_template = true;
+            break;
+          case Common::Assignment::A_VAR:
+            if (member->get_Value() != NULL) {
+              // set the variable's initial value as the constructor parameter's default value
+              Def_Var* var_member = dynamic_cast<Def_Var*>(member);
+              if (var_member == NULL) {
+                FATAL_ERROR("ClassTypeBody::chk - Def_Var cast");
+              }
+              def_val = new TemplateInstance(NULL, NULL, new Template(var_member->steal_Value()));
+            }
+            break;
           case Common::Assignment::A_VAR_TEMPLATE:
             is_template = true;
-            // no break
-          case Common::Assignment::A_CONST:
-          case Common::Assignment::A_VAR: {
-            // add a formal parameter for this member
-            Common::Identifier* id = member->get_id().clone();
-            FormalPar* fp = new FormalPar(is_template ?
-              Common::Assignment::A_PAR_TEMPL_IN : Common::Assignment::A_PAR_VAL_IN,
-              member->get_Type()->clone(), id, NULL);
-            fp_list->add_fp(fp);
-            // add a statement, that assigns the parameter's value to the member
-            Reference* ref_lhs = new Reference(NULL, id->clone(), Ref_simple::REF_THIS);
-            Reference* ref_rhs = new Reference(NULL, id->clone());
-            Common::Value* val_rhs = new Value(Common::Value::V_REFD, ref_rhs);
-            Template* temp_rhs = new Template(val_rhs);
-            Assignment* par_ass = new Assignment(ref_lhs, temp_rhs);
-            Statement* stmt = new Statement(Statement::S_ASSIGNMENT, par_ass);
-            block->add_stmt(stmt);
-            break; }
+            if (member->get_Template() != NULL) {
+              // set the template variable's initial value as the constructor parameter's default value
+              Def_Var_Template* var_temp_member = dynamic_cast<Def_Var_Template*>(member);
+              if (var_temp_member == NULL) {
+                FATAL_ERROR("ClassTypeBody::chk - Def_Var_Template cast");
+              }
+              def_val = new TemplateInstance(NULL, NULL, var_temp_member->steal_Template());
+            }
+            break;
           default:
+            continue;
             break;
           }
+          // add a formal parameter for this member if we've gotten this far
+          Common::Identifier* id = member->get_id().clone();
+          FormalPar* fp = new FormalPar(is_template ?
+            Common::Assignment::A_PAR_TEMPL_IN : Common::Assignment::A_PAR_VAL_IN,
+            member->get_Type()->clone(), id, def_val);
+          fp_list->add_fp(fp);
+          // add a statement, that assigns the parameter's value to the member
+          Reference* ref_lhs = new Reference(NULL, id->clone(), Ref_simple::REF_THIS);
+          Reference* ref_rhs = new Reference(NULL, id->clone());
+          Common::Value* val_rhs = new Value(Common::Value::V_REFD, ref_rhs);
+          Template* temp_rhs = new Template(val_rhs);
+          Assignment* par_ass = new Assignment(ref_lhs, temp_rhs);
+          Statement* stmt = new Statement(Statement::S_ASSIGNMENT, par_ass);
+          block->add_stmt(stmt);
         }
       }
       constructor = new Def_Constructor(fp_list, base_call, block);
@@ -3883,6 +3910,29 @@ namespace Ttcn {
       default_constructor = true;
     }
 
+    if (constructor != NULL && !default_constructor && !name_clash && !trait) {
+      // make sure constants and templates are initialized
+      for (size_t i = 0; i < members->get_nof_asss(); ++i) {
+        Common::Assignment* member = members->get_ass_byIndex(i, false);
+        bool needs_init_check = false;
+        bool is_template = false;
+        switch (member->get_asstype()) {
+        case Common::Assignment::A_CONST:
+          needs_init_check = member->get_Value() == NULL;
+          break;
+        case Common::Assignment::A_TEMPLATE:
+          needs_init_check = member->get_Template() == NULL;
+          is_template = true;
+          break;
+        default:
+          break;
+        }
+        if (needs_init_check) {
+          constructor->add_uninit_member(&member->get_id(), is_template);
+        }
+      }
+    }
+
     if (finally_block != NULL) {
       Error_Context cntxt(finally_block, "In class destructor");
       finally_block->chk();
diff --git a/compiler2/ttcn3/compiler.y b/compiler2/ttcn3/compiler.y
index 4719104158dd8befd6b65aef49ba677a19423d52..497705f0b25b64873f72db4be05ddc266335a814 100644
--- a/compiler2/ttcn3/compiler.y
+++ b/compiler2/ttcn3/compiler.y
@@ -2015,12 +2015,12 @@ DynamicMatch
 %left '*' '/' ModKeyword RemKeyword
 %left UnarySign
 
-%expect 92
+%expect 93
 
 %start GrammarRoot
 
 /*
-XXX Source of conflicts (92 S/R):
+XXX Source of conflicts (93 S/R):
 
 1.) 13 conflicts in one state
 The Expression after 'return' keyword is optional in ReturnStatement.
@@ -2028,7 +2028,7 @@ For 13 tokens the parser cannot decide whether the token is a part of
 the return expression (shift) or it is the beginning of the next statement
 (reduce).
 
-2.) 14 distinct states, each with one conflict caused by token '['
+2.) 15 distinct states, each with one conflict caused by token '['
 The local definitions in altsteps can be followed immediately by the guard
 expression. When the parser sees the '[' token it cannot decide whether it
 belongs to the local definition as array dimension or array subreference
@@ -2048,6 +2048,7 @@ The situations are the following:
 - var t v := this.function(...) <here> [
 - var t v := super.function(...) <here> [
 - var t v := value<subrefs> <here> [
+- const t c <here> [
 
 3.) 1 conflict
 The sequence identifier.objid can be either the beginning of a module name
@@ -3926,6 +3927,13 @@ SingleConstDef: // 90
     $$.initial_value = $4;
     $$.yyloc = @$;
   }
+| IDentifier optArrayDef
+  {
+    $$.id = $1;
+    $$.arrays = $2;
+    $$.initial_value = NULL;
+    $$.yyloc = @$;
+  }
 ;
 
 FunctionTypeDef:
@@ -3975,6 +3983,11 @@ TemplateDef: // 93
     $$ = new Def_Template($2, $4.name, $4.type, $4.fp_list, $5, $7);
     $$->set_location(infile, @$);
   }
+| TemplateKeyword optTemplateRestriction optLazyOrFuzzyModifier BaseTemplate
+  {
+    $$ = new Def_Template($2, $4.name, $4.type, $4.fp_list, NULL, NULL);
+    $$->set_location(infile, @$);
+  }
 ;
 
 BaseTemplate: // 94
@@ -4003,7 +4016,7 @@ DerivedDef: // 97
 ;
 
 optTemplateFormalParList:
-  /* empty */ optError { $$ = 0; }
+  /* empty */ { $$ = 0; }
 | '(' TemplateFormalParList optError ')'
   {
     $$ = $2;
diff --git a/function_test/Semantic_Analyser/oop/oop_SE.ttcn b/function_test/Semantic_Analyser/oop/oop_SE.ttcn
index c133753a5e662e744a3d2e558b3e27d55b367753..53dabb26a3de7ebc029cec07a9e131f5679b9463 100644
--- a/function_test/Semantic_Analyser/oop/oop_SE.ttcn
+++ b/function_test/Semantic_Analyser/oop/oop_SE.ttcn
@@ -492,7 +492,7 @@ type class C46 extends object { }
 
 
 type class C47 {
-  const integer m1 := 3;
+  const integer m1;
   public function m2() return boolean { return true; }
   function m3(in integer p) return charstring { return int2str(p); }
   function @final m4() { }
@@ -748,6 +748,24 @@ function f_traits_good() runs on CT_RunsOn2 {
   log(v_t7.f(3));
 }
 
+type class C60 {//^In type definition//
+  private const integer a := b;
+  private const integer b := 3;
+  private var integer c := f(); //^In variable definition// //Reference to a static value was expected instead of the return value of function `@oop_SE.C60.f'//
+  private const integer d := (1 - d); //^In constant definition// //^In the operands of operation// //Circular reference in constant definition//
+  private const integer e;
+  private const integer g := e + 1; //^In constant definition// //Reference to uninitialized constant `e' in class member initialization//
+  private var Rec h := { num := e, str := "q" }; //^In variable definition// //^In value for record field// //Reference to uninitialized constant `e' in class member initialization//
+  private template integer i;
+  private template integer j := i; //^In template definition// //Reference to uninitialized template `i' in class member initialization//
+  private var template Rec k := { e, h.str }; //^In template variable definition// //^In template for record field// //Reference to uninitialized constant `e' in class member initialization//
+  private var template integer l;
+  private template integer m := (1, l); //^In template definition// //^In list item// //Reference to uninitialized template variable `l' in class member initialization//
+  private var charstring n;
+  private var template charstring o := pattern "ab?{n}"; //^In template variable definition// //^In character string pattern// //Reference to uninitialized variable `n' in class member initialization//
+  public function f() return integer { return 10; }
+}
+
 
 control { //^In control part//
   var C11 x := C11.create; //^In variable definition// //A definition without `runs on' clause cannot create a value of class type `@oop_SE.C11', which runs on component type `@oop_SE.CT_RunsOn'// //Cannot create value of class type `@oop_SE.C11', which has an `mtc' clause, in the control part.// //Cannot create value of class type `@oop_SE.C11', which has a `system' clause, in the control part.//
diff --git a/regression_test/oop/Makefile b/regression_test/oop/Makefile
index a0b4ad72474c3d45e9abf493fea15800ae5a71ae..bb3758ec580c7d9f2187a94ae6d2e5ce6621d09c 100644
--- a/regression_test/oop/Makefile
+++ b/regression_test/oop/Makefile
@@ -17,7 +17,7 @@ include $(TOPDIR)/Makefile.regression
 
 TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX)
 
-TTCN3_MODULES = oop.ttcn exceptions.ttcn
+TTCN3_MODULES = oop.ttcn exceptions.ttcn oop2.ttcn
 
 USER_SOURCES = ext.cc
 
diff --git a/regression_test/oop/oop.cfg b/regression_test/oop/oop.cfg
index e7e4a8c825cfc1af10eaf01723fbb6a32be13c1c..22f81ef085df51cba790becfa97df8b2d97c949e 100644
--- a/regression_test/oop/oop.cfg
+++ b/regression_test/oop/oop.cfg
@@ -23,3 +23,4 @@ LogEntityName := Yes
 [EXECUTE]
 oop.control
 exceptions.control
+oop2.control
diff --git a/regression_test/oop/oop.ttcn b/regression_test/oop/oop.ttcn
index 75f21adb6c86e66fa76e63713b861b7280aa9bbf..bca21d5a4737edb4c82c984a0a7dd26da4777556 100644
--- a/regression_test/oop/oop.ttcn
+++ b/regression_test/oop/oop.ttcn
@@ -176,8 +176,8 @@ type class SubClass extends BaseClass {
 }
 
 type class @final FinalClass extends SubClass {
-  private const integer m_final_const := 1;
-  private template charstring m_final_temp := ? length (1..4);
+  private const integer m_final_const;
+  private template charstring m_final_temp;
   private var float m_final_var := 1.0;
   private var template octetstring m_final_var_temp := ''O;
   
diff --git a/regression_test/oop/oop2.ttcn b/regression_test/oop/oop2.ttcn
new file mode 100644
index 0000000000000000000000000000000000000000..ec3450ba03ffc076b8f50e1c65de0b8f1754c8bf
--- /dev/null
+++ b/regression_test/oop/oop2.ttcn
@@ -0,0 +1,223 @@
+/******************************************************************************
+ * Copyright (c) 2000-2021 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 oop2 {
+
+type component CT {}
+
+type class C1 {
+  private const integer m_const1;
+  private const integer m_const2 := 4;
+  private template integer m_temp1;
+  private template integer m_temp2 := (0..10);
+  private var integer m_var1;
+  private var integer m_var2 := 10;
+  private var template integer m_var_temp1;
+  private var template integer m_var_temp2 := (1, 2, 4, 8);
+  
+  public function test_members() {
+    if (m_const1 != 3) {
+      setverdict(fail, "m_const1 = ", m_const1);
+    }
+    if (m_const2 != 4) {
+      setverdict(fail, "m_const2 = ", m_const2);
+    }
+    if (log2str(m_temp1) != "?") {
+      setverdict(fail, "m_temp1 = ", m_temp1);
+    }
+    if (log2str(m_temp2) != "(0 .. 10)") {
+      setverdict(fail, "m_temp2 = ", m_temp2);
+    }
+    if (m_var1 != -1) {
+      setverdict(fail, "m_var1 = ", m_var1);
+    }
+    if (m_var2 != -2) {
+      setverdict(fail, "m_var2 = ", m_var2);
+    }
+    if (log2str(m_var_temp1) != "(0 .. infinity)") {
+      setverdict(fail, "m_var_temp1 = ", m_var_temp1);
+    }
+    if (log2str(m_var_temp2) != "(1, 2, 4, 8)") {
+      setverdict(fail, "m_var_temp2 = ", m_var_temp2);
+    }
+  }
+}
+
+testcase tc_constructor_default() runs on CT {
+  var C1 x := C1.create(3, ?, -1, -2, (0..infinity), -);
+  x.test_members();
+  setverdict(pass);
+}
+
+
+type class C2 {
+  private const integer m_const1;
+  private const integer m_const2 := 4;
+  private template integer m_temp1;
+  private template integer m_temp2 := (0..10);
+  private var integer m_var1;
+  private var integer m_var2 := 10;
+  private var template integer m_var_temp1;
+  private var template integer m_var_temp2 := (1, 2, 4, 8);
+  
+  create() {
+    m_const1 := 1;
+    m_temp1 := ?;
+  }
+  
+  public function test_members() {
+    if (m_const1 != 1) {
+      setverdict(fail, "m_const1 = ", m_const1);
+    }
+    if (m_const2 != 4) {
+      setverdict(fail, "m_const2 = ", m_const2);
+    }
+    if (log2str(m_temp1) != "?") {
+      setverdict(fail, "m_temp1 = ", m_temp1);
+    }
+    if (log2str(m_temp2) != "(0 .. 10)") {
+      setverdict(fail, "m_temp2 = ", m_temp2);
+    }
+    if (isbound(m_var1)) {
+      setverdict(fail, "m_var1 = ", m_var1);
+    }
+    if (m_var2 != 10) {
+      setverdict(fail, "m_var2 = ", m_var2);
+    }
+    if (isbound(m_var_temp1)) {
+      setverdict(fail, "m_var_temp1 = ", m_var_temp1);
+    }
+    if (log2str(m_var_temp2) != "(1, 2, 4, 8)") {
+      setverdict(fail, "m_var_temp2 = ", m_var_temp2);
+    }
+  }
+}
+
+testcase tc_constructor_init() runs on CT {
+  var C2 x := C2.create;
+  x.test_members();
+  setverdict(pass);
+}
+
+
+type class C3 {
+  private const integer m_const1;
+  private const integer m_const2 := 4;
+  private template integer m_temp1;
+  private template integer m_temp2 := (0..10);
+  private var integer m_var1;
+  private var integer m_var2 := 10;
+  private var template integer m_var_temp1;
+  private var template integer m_var_temp2 := (1, 2, 4, 8);
+  
+  create() {
+    m_temp1 := ?;
+  }
+}
+
+testcase tc_constructor_uninit_const() runs on CT {
+  @try {
+    var C3 x := C3.create;
+    setverdict(fail, "Error expected.");
+  }
+  @catch (msg) {
+    var template charstring exp := pattern "*Constant member `m_const1' is not initialized by the end of the constructor's execution.";
+    if (match(msg, exp)) {
+      setverdict(pass);
+    }
+    else {
+      setverdict(fail, "Invalid error: ", msg);
+    }
+  }
+}
+
+
+type class C4 {
+  private const integer m_const1;
+  private const integer m_const2 := 4;
+  private template integer m_temp1;
+  private template integer m_temp2 := (0..10);
+  private var integer m_var1;
+  private var integer m_var2 := 10;
+  private var template integer m_var_temp1;
+  private var template integer m_var_temp2 := (1, 2, 4, 8);
+  
+  create() {
+    m_const1 := 1;
+  }
+}
+
+testcase tc_constructor_uninit_temp() runs on CT {
+  @try {
+    var C4 x := C4.create;
+    setverdict(fail, "Error expected.");
+  }
+  @catch (msg) {
+    var template charstring exp := pattern "*Template member `m_temp1' is not initialized by the end of the constructor's execution.";
+    if (match(msg, exp)) {
+      setverdict(pass);
+    }
+    else {
+      setverdict(fail, "Invalid error: ", msg);
+    }
+  }
+}
+
+
+type record Rec {
+  integer num,
+  charstring str
+}
+
+type class C5 {
+  private const integer c1 := c2;
+  private const integer c2 := 3;
+  private template integer t1 := (t2, c3);
+  private template integer t2 := (1..4);
+  private const integer c3 := 9;
+  private var Rec v1 := { c4, "x" };
+  private const integer c4 := 10;
+  private var template Rec vt1 := { num := vt2, str := v3 };
+  private var template integer vt2 := (0..100);
+  private var charstring v3 := "y";
+  
+  create() {
+    if (c1 != 3) {
+      setverdict(fail, "c1 = ", c1);
+    }
+    template integer t1_exp := ((1..4), 9);
+    if (log2str(t1) != log2str(t1_exp)) {
+      setverdict(fail, "t1 = ", t1);
+    }
+    if (v1 != { 10, "x" }) {
+      setverdict(fail, "v1 = ", v1);
+    }
+    template Rec vt1_exp := { num := (0..100), str := "y" };
+    if (log2str(vt1) != log2str(vt1_exp)) {
+      setverdict(fail, "vt1 = ", vt1);
+    }
+  }
+}
+
+testcase tc_member_init_rearrange() runs on CT {
+  var C5 x := C5.create; // the actual tests are in the constructor
+  setverdict(pass);
+}
+
+control {
+  execute(tc_constructor_default());
+  execute(tc_constructor_init());
+  execute(tc_constructor_uninit_const());
+  execute(tc_constructor_uninit_temp());
+  execute(tc_member_init_rearrange());
+}
+
+}