-
- type* EType;
-
- /* We have a symbol with this name already */
- if (Entry->Flags & SC_TYPE) {
- Error (ERR_MULTIPLE_DEFINITION, Name);
- return Entry;
- }
-
- /* Get the type string of the existing symbol */
- EType = Entry->Type;
-
- /* If we are handling arrays, the old entry or the new entry may be an
- * incomplete declaration. Accept this, and if the exsting entry is
- * incomplete, complete it.
- */
- if (IsArray (Type) && IsArray (EType)) {
-
- /* Get the array sizes */
- unsigned Size = Decode (Type + 1);
- unsigned ESize = Decode (EType + 1);
-
- if ((Size != 0 && ESize != 0) ||
- TypeCmp (Type+DECODE_SIZE+1, EType+DECODE_SIZE+1) != 0) {
- /* Types not identical: Duplicate definition */
- Error (ERR_MULTIPLE_DEFINITION, Name);
- } else {
- /* Check if we have a size in the existing definition */
- if (ESize == 0) {
- /* Existing, size not given, use size from new def */
- Encode (EType + 1, Size);
- }
- }
-
- } else {
- /* New type must be identical */
- if (!EqualTypes (EType, Type) != 0) {
- Error (ERR_MULTIPLE_DEFINITION, Name);
- }
-
- /* In case of a function, use the new type descriptor, since it
- * contains pointers to the new symbol tables that are needed if
- * an actual function definition follows.
- */
- if (IsFunc (Type)) {
- CopyEncode (Type+1, EType+1);
- }
- }
-
- /* Add the new flags */
- Entry->Flags |= Flags;
+ Type* EType;
+
+ /* If the existing symbol is an enumerated constant,
+ ** then avoid a compiler crash. See GitHub issue #728.
+ */
+ if (Entry->Flags & SC_ENUM) {
+ Fatal ("Can't redeclare enum constant '%s' as global variable", Name);
+ }
+
+ /* We have a symbol with this name already */
+ if (Entry->Flags & SC_TYPE) {
+ Error ("Multiple definition for '%s'", Name);
+ return Entry;
+ }
+
+ /* Get the type string of the existing symbol */
+ EType = Entry->Type;
+
+ /* If we are handling arrays, the old entry or the new entry may be an
+ ** incomplete declaration. Accept this, and if the exsting entry is
+ ** incomplete, complete it.
+ */
+ if (IsTypeArray (T) && IsTypeArray (EType)) {
+
+ /* Get the array sizes */
+ long Size = GetElementCount (T);
+ long ESize = GetElementCount (EType);
+
+ if ((Size != UNSPECIFIED && ESize != UNSPECIFIED && Size != ESize) ||
+ TypeCmp (T + 1, EType + 1) < TC_EQUAL) {
+ /* Types not identical: Conflicting types */
+ Error ("Conflicting types for '%s'", Name);
+ return Entry;
+ } else {
+ /* Check if we have a size in the existing definition */
+ if (ESize == UNSPECIFIED) {
+ /* Existing, size not given, use size from new def */
+ SetElementCount (EType, Size);
+ }
+ }
+
+ } else {
+ /* New type must be identical */
+ if (TypeCmp (EType, T) < TC_EQUAL) {
+ Error ("Conflicting types for '%s'", Name);
+ return Entry;
+ }
+
+ /* In case of a function, use the new type descriptor, since it
+ ** contains pointers to the new symbol tables that are needed if
+ ** an actual function definition follows. Be sure not to use the
+ ** new descriptor if it contains a function declaration with an
+ ** empty parameter list.
+ */
+ if (IsFunc) {
+ /* Get the function descriptor from the new type */
+ FuncDesc* F = GetFuncDesc (T);
+ /* Use this new function descriptor if it doesn't contain
+ ** an empty parameter list.
+ */
+ if ((F->Flags & FD_EMPTY) == 0) {
+ Entry->V.F.Func = F;
+ SetFuncDesc (EType, F);
+ }
+ }
+ }
+
+ /* If a static declaration follows a non-static declaration, then
+ ** warn about the conflict. (It will compile a public declaration.)
+ */
+ if ((Flags & SC_EXTERN) == 0 && (Entry->Flags & SC_EXTERN) != 0) {
+ Warning ("static declaration follows non-static declaration of '%s'.", Name);
+ }
+
+ /* An extern declaration must not change the current linkage. */
+ if (IsFunc || (Flags & (SC_EXTERN | SC_STORAGE)) == SC_EXTERN) {
+ Flags &= ~SC_EXTERN;
+ }
+
+ /* If a public declaration follows a static declaration, then
+ ** warn about the conflict. (It will compile a public declaration.)
+ */
+ if ((Flags & SC_EXTERN) != 0 && (Entry->Flags & SC_EXTERN) == 0) {
+ Warning ("public declaration follows static declaration of '%s'.", Name);
+ }
+
+ /* Add the new flags */
+ Entry->Flags |= Flags;