diff --git a/src/cc65/declare.c b/src/cc65/declare.c
index 8d3e0f458..6aff1960e 100644
--- a/src/cc65/declare.c
+++ b/src/cc65/declare.c
@@ -515,7 +515,7 @@ static void ParseStorageClass (DeclSpec* D, unsigned DefStorage)
 
 
 
-static SymEntry* ESUForwardDecl (const char* Name, unsigned Flags)
+static SymEntry* ESUForwardDecl (const char* Name, unsigned Flags, unsigned* DSFlags)
 /* Handle an enum, struct or union forward decl */
 {
     /* Try to find an enum/struct/union with the given name. If there is none,
@@ -524,9 +524,9 @@ static SymEntry* ESUForwardDecl (const char* Name, unsigned Flags)
     SymEntry* Entry = FindTagSym (Name);
     if (Entry == 0) {
         if ((Flags & SC_ESUTYPEMASK) != SC_ENUM) {
-            Entry = AddStructSym (Name, Flags, 0, 0);
+            Entry = AddStructSym (Name, Flags, 0, 0, DSFlags);
         } else {
-            Entry = AddEnumSym (Name, Flags, 0, 0);
+            Entry = AddEnumSym (Name, Flags, 0, 0, DSFlags);
         }
     } else if ((Entry->Flags & SC_TYPEMASK) != (Flags & SC_ESUTYPEMASK)) {
         /* Already defined, but not the same type class */
@@ -575,7 +575,7 @@ static const Type* GetEnumeratorType (long Min, unsigned long Max, int Signed)
 
 
 
-static SymEntry* ParseEnumDecl (const char* Name)
+static SymEntry* ParseEnumDecl (const char* Name, unsigned* DSFlags)
 /* Process an enum declaration */
 {
     SymTable*       FieldTab;
@@ -593,11 +593,11 @@ static SymEntry* ParseEnumDecl (const char* Name)
 
     if (CurTok.Tok != TOK_LCURLY) {
         /* Just a forward definition */
-        return ESUForwardDecl (Name, SC_ENUM);
+        return ESUForwardDecl (Name, SC_ENUM, DSFlags);
     }
 
     /* Add a forward declaration for the enum tag in the current lexical level */
-    AddEnumSym (Name, 0, 0, 0);
+    AddEnumSym (Name, 0, 0, 0, DSFlags);
 
     /* Skip the opening curly brace */
     NextToken ();
@@ -740,7 +740,7 @@ static SymEntry* ParseEnumDecl (const char* Name)
         Flags |= SC_FICTITIOUS;
     }
 
-    return AddEnumSym (Name, Flags, MemberType, FieldTab);
+    return AddEnumSym (Name, Flags, MemberType, FieldTab, DSFlags);
 }
 
 
@@ -870,7 +870,7 @@ static unsigned AliasAnonStructFields (const Declaration* Decl, SymEntry* Anon)
 
 
 
-static SymEntry* ParseUnionDecl (const char* Name)
+static SymEntry* ParseUnionDecl (const char* Name, unsigned* DSFlags)
 /* Parse a union declaration. */
 {
 
@@ -886,11 +886,11 @@ static SymEntry* ParseUnionDecl (const char* Name)
 
     if (CurTok.Tok != TOK_LCURLY) {
         /* Just a forward declaration */
-        return ESUForwardDecl (Name, SC_UNION);
+        return ESUForwardDecl (Name, SC_UNION, DSFlags);
     }
 
     /* Add a forward declaration for the union tag in the current lexical level */
-    UnionTagEntry = AddStructSym (Name, SC_UNION, 0, 0);
+    UnionTagEntry = AddStructSym (Name, SC_UNION, 0, 0, DSFlags);
 
     UnionTagEntry->V.S.ACount = 0;
 
@@ -1005,12 +1005,12 @@ NextMember: if (CurTok.Tok != TOK_COMMA) {
     }
 
     /* Make a real entry from the forward decl and return it */
-    return AddStructSym (Name, SC_UNION | SC_DEF | Flags, UnionSize, FieldTab);
+    return AddStructSym (Name, SC_UNION | SC_DEF | Flags, UnionSize, FieldTab, DSFlags);
 }
 
 
 
-static SymEntry* ParseStructDecl (const char* Name)
+static SymEntry* ParseStructDecl (const char* Name, unsigned* DSFlags)
 /* Parse a struct declaration. */
 {
 
@@ -1027,11 +1027,11 @@ static SymEntry* ParseStructDecl (const char* Name)
 
     if (CurTok.Tok != TOK_LCURLY) {
         /* Just a forward declaration */
-        return ESUForwardDecl (Name, SC_STRUCT);
+        return ESUForwardDecl (Name, SC_STRUCT, DSFlags);
     }
 
     /* Add a forward declaration for the struct tag in the current lexical level */
-    StructTagEntry = AddStructSym (Name, SC_STRUCT, 0, 0);
+    StructTagEntry = AddStructSym (Name, SC_STRUCT, 0, 0, DSFlags);
 
     StructTagEntry->V.S.ACount = 0;
 
@@ -1219,7 +1219,7 @@ NextMember: if (CurTok.Tok != TOK_COMMA) {
     }
 
     /* Make a real entry from the forward decl and return it */
-    return AddStructSym (Name, SC_STRUCT | SC_DEF | Flags, StructSize, FieldTab);
+    return AddStructSym (Name, SC_STRUCT | SC_DEF | Flags, StructSize, FieldTab, DSFlags);
 }
 
 
@@ -1402,7 +1402,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers,
             /* Remember we have an extra type decl */
             D->Flags |= DS_EXTRA_TYPE;
             /* Declare the union in the current scope */
-            Entry = ParseUnionDecl (Ident);
+            Entry = ParseUnionDecl (Ident, &D->Flags);
             /* Encode the union entry into the type */
             D->Type[0].C = T_UNION;
             SetESUSymEntry (D->Type, Entry);
@@ -1421,7 +1421,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers,
             /* Remember we have an extra type decl */
             D->Flags |= DS_EXTRA_TYPE;
             /* Declare the struct in the current scope */
-            Entry = ParseStructDecl (Ident);
+            Entry = ParseStructDecl (Ident, &D->Flags);
             /* Encode the struct entry into the type */
             D->Type[0].C = T_STRUCT;
             SetESUSymEntry (D->Type, Entry);
@@ -1444,7 +1444,8 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers,
             /* Remember we have an extra type decl */
             D->Flags |= DS_EXTRA_TYPE;
             /* Parse the enum decl */
-            Entry = ParseEnumDecl (Ident);
+            Entry = ParseEnumDecl (Ident, &D->Flags);
+            /* Encode the enum entry into the type */
             D->Type[0].C |= T_ENUM;
             SetESUSymEntry (D->Type, Entry);
             D->Type[1].C = T_END;
@@ -1583,6 +1584,13 @@ static void ParseOldStyleParamList (FuncDesc* F)
 
             /* Read the parameter */
             ParseDecl (&Spec, &Decl, DM_NEED_IDENT);
+
+            /* Warn about new local type declaration */
+            if ((Spec.Flags & DS_NEW_TYPE_DECL) != 0) {
+                Warning ("'%s' will be invisible out of this function",
+                         GetFullTypeName (Spec.Type));
+            }
+
             if (Decl.Ident[0] != '\0') {
 
                 /* We have a name given. Search for the symbol */
@@ -1650,6 +1658,12 @@ static void ParseAnsiParamList (FuncDesc* F)
             Spec.StorageClass = SC_AUTO | SC_PARAM | SC_DEF;
         }
 
+        /* Warn about new local type declaration */
+        if ((Spec.Flags & DS_NEW_TYPE_DECL) != 0) {
+            Warning ("'%s' will be invisible out of this function",
+                     GetFullTypeName (Spec.Type));
+        }
+
         /* Allow parameters without a name, but remember if we had some to
         ** eventually print an error message later.
         */
diff --git a/src/cc65/declare.h b/src/cc65/declare.h
index 615f16a4a..3293a0dcb 100644
--- a/src/cc65/declare.h
+++ b/src/cc65/declare.h
@@ -57,6 +57,9 @@
 #define DS_DEF_STORAGE          0x0001U /* Default storage class used   */
 #define DS_DEF_TYPE             0x0002U /* Default type used            */
 #define DS_EXTRA_TYPE           0x0004U /* Extra type declared          */
+#define DS_NEW_TYPE_DECL        0x0010U /* New type declared            */
+#define DS_NEW_TYPE_DEF         0x0020U /* New type defined             */
+#define DS_NEW_TYPE             (DS_NEW_TYPE_DECL | DS_NEW_TYPE_DEF)
 
 /* Result of ParseDeclSpec */
 typedef struct DeclSpec DeclSpec;
diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c
index 7e6a9f5bb..6a02fc0ce 100644
--- a/src/cc65/symtab.c
+++ b/src/cc65/symtab.c
@@ -686,7 +686,7 @@ static void AddSymEntry (SymTable* T, SymEntry* S)
 
 
 
-SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTable* Tab)
+SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTable* Tab, unsigned* DSFlags)
 /* Add an enum entry and return it */
 {
     SymTable* CurTagTab = TagTab;
@@ -719,6 +719,11 @@ SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTab
                 Entry->V.E.Type   = Type;
                 Entry->Flags     &= ~SC_DECL;
                 Entry->Flags     |= SC_DEF;
+
+                /* Remember this is the first definition of this type */
+                if (DSFlags != 0) {
+                    *DSFlags |= DS_NEW_TYPE_DEF;
+                }
             }
         }
 
@@ -741,6 +746,14 @@ SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTab
             Entry->Flags |= SC_DEF;
         }
 
+        /* Remember this is the first definition of this type */
+        if (CurTagTab != FailSafeTab && DSFlags != 0) {
+            if ((Entry->Flags & SC_DEF) != 0) {
+                *DSFlags |= DS_NEW_TYPE_DEF;
+            }
+            *DSFlags |= DS_NEW_TYPE_DECL;
+        }
+
         /* Add it to the current table */
         AddSymEntry (CurTagTab, Entry);
     }
@@ -751,7 +764,7 @@ SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTab
 
 
 
-SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTable* Tab)
+SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTable* Tab, unsigned* DSFlags)
 /* Add a struct/union entry and return it */
 {
     SymTable* CurTagTab = TagTab;
@@ -791,6 +804,11 @@ SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTabl
                 Entry->Flags      = Flags;
                 Entry->V.S.SymTab = Tab;
                 Entry->V.S.Size   = Size;
+
+                /* Remember this is the first definition of this type */
+                if (DSFlags != 0) {
+                    *DSFlags |= DS_NEW_TYPE_DEF;
+                }
             }
         }
 
@@ -809,6 +827,14 @@ SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTabl
         Entry->V.S.SymTab = Tab;
         Entry->V.S.Size   = Size;
 
+        /* Remember this is the first definition of this type */
+        if (CurTagTab != FailSafeTab && DSFlags != 0) {
+            if ((Entry->Flags & SC_DEF) != 0) {
+                *DSFlags |= DS_NEW_TYPE_DEF;
+            }
+            *DSFlags |= DS_NEW_TYPE_DECL;
+        }
+
         /* Add it to the current tag table */
         AddSymEntry (CurTagTab, Entry);
     }
diff --git a/src/cc65/symtab.h b/src/cc65/symtab.h
index 750e41b54..1231eb528 100644
--- a/src/cc65/symtab.h
+++ b/src/cc65/symtab.h
@@ -149,10 +149,10 @@ unsigned short FindSPAdjustment (const char* Name);
 
 
 
-SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTable* Tab);
+SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTable* Tab, unsigned* DSFlags);
 /* Add an enum entry and return it */
 
-SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTable* Tab);
+SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTable* Tab, unsigned* DSFlags);
 /* Add a struct/union entry and return it */
 
 SymEntry* AddBitField (const char* Name, const Type* Type, unsigned Offs,