diff --git a/gcc/cobol/symbols.cc b/gcc/cobol/symbols.cc
index c6fc305f4a44e97c0136b9641a52cac3742a0aae..2936d8bfd0ea80a1af5c15e1c7cc5b2064982019 100644
--- a/gcc/cobol/symbols.cc
+++ b/gcc/cobol/symbols.cc
@@ -2962,8 +2962,8 @@ new_temporary( enum cbl_field_type_t type ) {
   return parser_symbol_add2(field);
 }
 
-cbl_field_t *
-new_literal( const char initial[], enum cbl_field_attr_t attr ) {
+static cbl_field_t *
+new_literal_impl( const char initial[], enum cbl_field_attr_t attr ) {
   static char empty[2] = "\0";
   cbl_field_t *field = NULL;
   if( !(attr & quoted_e) )
@@ -2989,6 +2989,28 @@ new_literal( const char initial[], enum cbl_field_attr_t attr ) {
   return parser_symbol_add2(field);
 }
 
+static temporaries_t temporaries;
+
+cbl_field_t *
+temporaries_t::literal( const char value[], cbl_field_attr_t attr ) {
+  auto p = literals.find(value);
+  if( p != literals.end() ) {
+    cbl_field_t *field = p->second;
+    if( false && attr != none_e && field->attr != attr ) {
+      warnx("temporaries_t::%s:%d: '%s' logic: using prior attr %08lx, not %08lx",
+            __func__, __LINE__,
+            field->data.initial, field->attr, attr);
+    }
+    return field;
+  }
+  return literals[value] = new_literal_impl(value, attr);
+}
+
+cbl_field_t *
+new_literal( const char initial[], enum cbl_field_attr_t attr ) {
+  return temporaries.literal(initial, attr);
+}
+
 cbl_field_t *
 new_alphanumeric( size_t capacity ) {
   cbl_field_t * field = new_temporary_impl(FldAlphanumeric);
diff --git a/gcc/cobol/symbols.h b/gcc/cobol/symbols.h
index 463a0ecf161a109d84725eda9415716fccaf388d..c5f60e0561bc59c408ecc4e485e41aa8300d9f19 100644
--- a/gcc/cobol/symbols.h
+++ b/gcc/cobol/symbols.h
@@ -1183,6 +1183,14 @@ cbl_field_t * new_temporary( enum cbl_field_type_t type );
 cbl_field_t * new_literal( const char initial[],
                            enum cbl_field_attr_t attr = none_e );
 
+class temporaries_t {
+  std::map<std::string, cbl_field_t *> literals;
+  typedef std::set<cbl_field_t *> fieldset_t;
+  std::map<cbl_field_type_t, fieldset_t> used, freed;
+public:
+  cbl_field_t *literal( const char value[], cbl_field_attr_t attr  = none_e );
+};
+
 static inline bool is_table( const cbl_field_t *field ) {
   return field && field->occurs.ntimes() > 0;
 }