diff --git a/gcc/cobol/UAT/Makefile b/gcc/cobol/UAT/Makefile
index 6c8da16d87845a00a7fa641e616100806554bc4d..aa1aff10298df8416a15649b04fabd50f3fd1e1b 100644
--- a/gcc/cobol/UAT/Makefile
+++ b/gcc/cobol/UAT/Makefile
@@ -25,11 +25,16 @@ FAILSUITE_AT_FILES=$(wildcard ./failsuite.src/*.at)
 SKIPSUITE_AT_FILES=$(wildcard ./skipsuite.src/*.at)
 BUGSUITE_AT_FILES=$(wildcard ./bugsuite.src/*.at)
 
+vis:
+	echo FAILURE.bad: $(FAILURE.bad)
+	echo FAILSUITE_OK_FILES: $(FAILSUITE_OK_FILES)
+
 testsuite: atlocal $(TESTSUITE_AT_FILES) testsuite.at
 	autom4te --language=autotest -I $@.src -o $@ $@.at
 
-failsuite: atlocal $(FAILSUITE_AT_FILES) failsuite.at
-	autom4te --language=autotest -I $@.src -o $@ $@.at
+failsuite: atlocal $(FAILSUITE_OK_FILES) failsuite.at
+	autom4te --language=autotest -I $@.src -o $@ \
+		$@.at $(addprefix failsuite.src/,typedef.at)
 
 skipsuite: atlocal $(SKIPSUITE_AT_FILES) skipsuite.at
 	autom4te --language=autotest -I $@.src -o $@ $@.at
diff --git a/gcc/cobol/UAT/failsuite.src/typedef.at b/gcc/cobol/UAT/failsuite.src/typedef.at
index 9e5ae500b387255c294239ffb4efe54d958a36d8..7a5908973b257f8f1e5d748008d3d5f9cf1dfa5f 100644
--- a/gcc/cobol/UAT/failsuite.src/typedef.at
+++ b/gcc/cobol/UAT/failsuite.src/typedef.at
@@ -3,57 +3,60 @@ AT_COPYRIGHT([Test cases Copyright (C) 2024 Free Software Foundation
 Written by Simon Sobisch])
 
 
-AT_KEYWORDS([fundamental EXTERNAL])
+AT_BANNER([TYPEDEF Tests])
 
-AT_DATA([caller.cob], [
-      IDENTIFICATION  DIVISION.
-      PROGRAM-ID.     caller.
+AT_SETUP([typedef 1])
+AT_KEYWORDS([typedef])
 
-      DATA            DIVISION.
-      WORKING-STORAGE SECTION.
-      01  INT         IS TYPEDEF BINARY-LONG.
-          88  INT-ZERO  VALUE 0.
-          88  INT-ONE   VALUE 1.
-      77  EXT-INT     IS TYPEDEF BINARY-LONG EXTERNAL.
-      77  INT-VAL     IS TYPEDEF BINARY-LONG VALUE 12.
-      01  SOMEVAR     USAGE INT VALUE 10.
-      01  SOMEVAR2    USAGE INT VALUE 11.
-      77  SOMEVAL     USAGE INT-VAL.
-      77  SOMEEXT     USAGE EXT-INT.
-
-      PROCEDURE       DIVISION.
-          IF SOMEVAR <> 10
-             DISPLAY "SOMEVAR (INT) wrong: " SOMEVAR.
-          IF SOMEVAL <> 12
-             DISPLAY "SOMEVAL (INT-VAL) wrong: " SOMEVAL.
-          SET INT-ZERO OF SOMEVAR  TO TRUE
-          SET INT-ONE  OF SOMEVAR2 TO TRUE
-          IF SOMEVAR  <> 0
-             DISPLAY "SOMEVAR  (INT) by SET wrong: " SOMEVAR.
-          IF SOMEVAR2 <> 1
-             DISPLAY "SOMEVAR2 (INT) by SET wrong: " SOMEVAR2.
-          IF INT-ONE  OF SOMEVAR
-          OR NOT INT-ONE  OF SOMEVAR2
-             DISPLAY "CHECK BY condition-nam wrong".
-          MOVE 42 TO SOMEEXT
-          CALL "callee"
-          GOBACK.
+AT_DATA([caller.cob], [
+       IDENTIFICATION  DIVISION.
+       PROGRAM-ID.     caller.
+       
+       DATA            DIVISION.
+       WORKING-STORAGE SECTION.
+       01  INT         IS TYPEDEF BINARY-LONG.
+           88  INT-ZERO  VALUE 0.
+           88  INT-ONE   VALUE 1.
+       77  EXT-INT     IS TYPEDEF BINARY-LONG EXTERNAL.
+       77  INT-VAL     IS TYPEDEF BINARY-LONG VALUE 12.
+       01  SOMEVAR     USAGE INT VALUE 10.
+       01  SOMEVAR2    USAGE INT VALUE 11.
+       77  SOMEVAL     USAGE INT-VAL.
+       77  SOMEEXT     USAGE EXT-INT.
+       
+       PROCEDURE       DIVISION.
+           IF SOMEVAR <> 10
+              DISPLAY "SOMEVAR (INT) wrong: " SOMEVAR.
+           IF SOMEVAL <> 12
+              DISPLAY "SOMEVAL (INT-VAL) wrong: " SOMEVAL.
+           SET INT-ZERO OF SOMEVAR  TO TRUE
+           SET INT-ONE  OF SOMEVAR2 TO TRUE
+           IF SOMEVAR  <> 0
+              DISPLAY "SOMEVAR  (INT) by SET wrong: " SOMEVAR.
+           IF SOMEVAR2 <> 1
+              DISPLAY "SOMEVAR2 (INT) by SET wrong: " SOMEVAR2.
+           IF INT-ONE  OF SOMEVAR
+           OR NOT INT-ONE  OF SOMEVAR2
+              DISPLAY "CHECK BY condition-nam wrong".
+           MOVE 42 TO SOMEEXT
+           CALL "callee"
+           GOBACK.
 ])
 
 AT_DATA([callee.cob], [
-      IDENTIFICATION  DIVISION.
-      PROGRAM-ID.     callee.
-
-      DATA            DIVISION.
-      WORKING-STORAGE SECTION.
-      77  EXT-INT     IS TYPEDEF BINARY-LONG EXTERNAL.
-      77  SOMEEXT     USAGE EXT-INT.
-
-      PROCEDURE       DIVISION.
-          IF SOMEEXT <> 42
-             DISPLAY "SOMEEXT (EXT-INT) wrong: " SOMEEXT
-          END-IF
-          .
+       IDENTIFICATION  DIVISION.
+       PROGRAM-ID.     callee.
+       
+       DATA            DIVISION.
+       WORKING-STORAGE SECTION.
+       77  EXT-INT     IS TYPEDEF BINARY-LONG EXTERNAL.
+       77  SOMEEXT     USAGE EXT-INT.
+       
+       PROCEDURE       DIVISION.
+           IF SOMEEXT <> 42
+              DISPLAY "SOMEEXT (EXT-INT) wrong: " SOMEEXT
+           END-IF
+           .
 ])
 
 AT_CHECK([$COMPILE caller.cob], [0], [], [])
@@ -187,9 +190,11 @@ AT_DATA([progstd.cob], [
 ])
 
 AT_CHECK([$COMPILE_ONLY prog.cob], [0], [], [])
+AT_CLEANUP
 
+AT_SETUP([typedef 1])
 
-
+AT_KEYWORDS([typedef])
 
 AT_DATA([badprog.cob], [
       IDENTIFICATION   DIVISION.
@@ -212,7 +217,7 @@ badprog.cob:10: error: entry following TYPE TO may not be subordinate to it
 badprog.cob:11: error: illegal combination of TYPE TO with other clauses
 badprog.cob:12: error: elementary item expected
 ])
-
+AT_CLEANUP
 
 AT_SETUP([SAME AS clause])
 AT_KEYWORDS([definition EXTERNAL GLOBAL])
@@ -276,6 +281,10 @@ AT_CLEANUP
 # totally fine. This is directly copied from the standard (only added
 # the syntactic parts missing).
 
+AT_SETUP([typedef 1])
+
+AT_KEYWORDS([typedef])
+
 AT_DATA([prog.cob], [
       IDENTIFICATION DIVISION.
       PROGRAM-ID. prog.
@@ -407,3 +416,6 @@ AT_DATA([prog.cob], [
        VALIDATE MY-MIXED-GROUP
 
     GOBACK.
+])
+
+AT_CLEANUP
diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc
index a1c50628116c0831bd34ace1f66d19a9d21ee441..71fdca596d93e5432ba7f4ec9162910deca85115 100644
--- a/gcc/cobol/genapi.cc
+++ b/gcc/cobol/genapi.cc
@@ -7455,7 +7455,7 @@ parser_perform_inline_times(struct cbl_perform_tgt_t *tgt,
   }
 
 void
-parser_set_conditional( struct cbl_refer_t refer, bool which_way )
+parser_set_conditional88( struct cbl_refer_t refer, bool which_way )
   {
   struct cbl_field_t *tgt = refer.field;
   SHOW_PARSE
diff --git a/gcc/cobol/genapi.h b/gcc/cobol/genapi.h
index 69113aab2693d962ebb7010b86802bcac6a3d83c..c66b367cc399929a08161a3fafda4f7ef6a65fbd 100644
--- a/gcc/cobol/genapi.h
+++ b/gcc/cobol/genapi.h
@@ -311,7 +311,7 @@ void
 parser_alter( cbl_perform_tgt_t *tgt );
 
 void
-parser_set_conditional( struct cbl_refer_t tgt, bool which_way );
+parser_set_conditional88( struct cbl_refer_t tgt, bool which_way );
 void
 parser_set_numeric(struct cbl_field_t *tgt, ssize_t value);
 
diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y
index 783f01343fc8e713635c00cf9f9013ee9c84bc81..8c82640471b64d20616b7c1500cb619de987f4a0 100644
--- a/gcc/cobol/parse.y
+++ b/gcc/cobol/parse.y
@@ -3874,12 +3874,26 @@ type_clause: TYPE to typename
 		  }
 		  yywarn("warning: TYPE TO is provisional");
 		}
+	| 	USAGE is typename 
+		{
+		  if( ! dialect_mf() ) {
+		    yyerror("error: USAGE TYPENAME requires -dialect mf");
+		    YYERROR;
+		  }
+                  cbl_field_t *field = current_field();
+		  if( $typename ) {
+		    symbol_field_same_as(field, $typename);
+		  }
+		  yywarn("warning: USAGE TYPENAME is provisional");
+		}
 		;
 
 typedef_clause: is TYPEDEF strong 
 		{
                   cbl_field_t *field = current_field();
-		  if( field->level != 1 ) {
+		  switch( field->level ) {
+		  case 1: case 77: break;
+		  default:
 		    yyerrorv("error: %02d %s IS TYPEDEF must be level 01",
 			     field->level, field->name);
 		  }
@@ -7112,7 +7126,7 @@ set:            SET set_tgts[tgts] TO set_operand[src]
 		                 refer.field->name);
 		        return;
 		      }
-                      parser_set_conditional(refer, tf);
+                      parser_set_conditional88(refer, tf);
                     }
                   };
                   std::for_each($names->refers.begin(), $names->refers.end(),
diff --git a/gcc/cobol/parse_ante.h b/gcc/cobol/parse_ante.h
index 83c1b31337d918e24f299c314a0d5aa67365b05e..70eacc18dbe31cc9bda04549c8a80f23cb37a07d 100644
--- a/gcc/cobol/parse_ante.h
+++ b/gcc/cobol/parse_ante.h
@@ -200,7 +200,7 @@ enum data_clause_t {
   based_clause_e       = 0x0800,
   same_clause_e        = 0x1000,
   volatile_clause_e    = 0x2000,
-  type_clause_e        = 0x4000,
+  type_clause_e        = usage_clause_e, 
   typedef_clause_e     = 0x8000,
 };
 
@@ -2843,6 +2843,11 @@ procedure_division_ready( cbl_field_t *returning, ffi_args_t *ffi_args ) {
     if( symbol_redefines(f) ) continue;
     if( f->has_attr(linkage_e) ) continue;
     if( f->has_attr(local_e) ) continue;
+    if( f->is_typedef() ) {
+      auto isym = end_of_group( symbol_index(e) );
+      e = symbol_at(--isym);
+      continue;
+    }
     static const bool like_parser_symbol_add = true;
     parser_initialize(f, like_parser_symbol_add);
   }
diff --git a/gcc/cobol/symbols.cc b/gcc/cobol/symbols.cc
index 2e57410eef7bbbad24c1ab792a594a61a7878f82..6d03c15682298acc609a53f167f24af772ad4ecf 100644
--- a/gcc/cobol/symbols.cc
+++ b/gcc/cobol/symbols.cc
@@ -1504,6 +1504,7 @@ field_str( const cbl_field_t *field ) {
   char parredef =
     parent_of(field) != NULL && parent_of(field)->level == field->level? 'r' : 'P';
   if( 'r' == parredef && field->level == 0 ) parredef = 'p';
+  if( field->has_attr(typedef_e) ) parredef = 'T';
 
   const char *data = field->data.initial? field->data.initial : NULL;
   if( data ) {
@@ -2622,10 +2623,26 @@ symbol_field_same_as( cbl_field_t *tgt, const cbl_field_t *src ) {
   auto last_elem = symbol_at(field_index(tgt));
   tgt->same_as(*src);
 
-  if( tgt->type == FldGroup ) {
-    size_t isrc = field_index(src);
-    symbol_elem_t *bog = symbol_at(isrc);
-    symbol_elem_t *eog = symbol_at_impl(end_of_group(isrc), true);
+  size_t isrc = field_index(src);
+
+  symbol_elem_t *bog = symbol_at(isrc);
+  symbol_elem_t *eog = symbol_at_impl(end_of_group(isrc), true);
+
+  if( src->type != FldGroup ) {
+    // For scalar, check for Level 88. Find next field with other parent.
+    eog = std::find_if( bog + 1, 
+                        symbols_end(),
+                        [parent = isrc]( const auto& elem ) {
+                          if( elem.type == SymField ) {
+                            auto f = cbl_field_of(&elem);
+                            assert(parent != f->parent || f->level == 88);
+                            return parent != f->parent;
+                          }
+                          return true;
+                        } );
+  }    
+
+  if( bog + 1 < eog ) {
     cbl_field_t dup = { .parent = field_index(tgt), .line = tgt->line };
 
     // for each duplicate, map src index to duplicate index
@@ -3064,6 +3081,7 @@ temporaries_t::acquire( cbl_field_type_t type ) {
     field = new_temporary_add(type);
   } else {
     auto p = fields.begin();
+    parser_symbol_add(*p);
     field = *p;
     fields.erase(p);
   }
@@ -3077,6 +3095,8 @@ symbol_temporaries_free() {
   for( auto& elem : temporaries.used ) {
     const cbl_field_type_t& type(elem.first);
     temporaries_t::fieldset_t& used(elem.second);
+    if( type == FldConditional ) continue;
+    
     auto freed = std::inserter(temporaries.freed[type],
                                temporaries.freed[type].begin());
     std::copy( used.begin(), used.end(), freed );
@@ -3084,6 +3104,17 @@ symbol_temporaries_free() {
   }
 }
 
+#if 0
+void
+temporaries_t::release( cbl_field_type_t type ) {
+  fieldset_t& used[type];
+  auto freed = std::inserter(freed[type],
+                             freed[type].begin());
+  std::copy( used.begin(), used.end(), freed );
+  used.clear();
+}
+#endif
+
 cbl_field_t *
 new_temporary( enum cbl_field_type_t type ) {
   return temporaries.acquire(type);
diff --git a/gcc/cobol/symbols.h b/gcc/cobol/symbols.h
index bd7f26b0cfc3f0088718aa310b45afc928e7d0af..909063f70934d43372b580aad803753aa9aad5de 100644
--- a/gcc/cobol/symbols.h
+++ b/gcc/cobol/symbols.h
@@ -2091,6 +2091,7 @@ char date_time_fmt( const char input[] );
 size_t current_program_index();
 const char * current_declarative_section_name();
 
+size_t end_of_group( size_t igroup );
 
 struct symbol_elem_t * symbol_typedef( size_t program, std::list<const char *> names );
 struct symbol_elem_t * symbol_typedef( size_t program, const char name[] );