diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index d3b95192e..8b7f78e5e 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -800,6 +800,31 @@ void Parser::ParseDecl() { } } } + // Check that no identifiers clash with auto generated fields. + // This is not an ideal situation, but should occur very infrequently, + // and allows us to keep using very readable names for type & length fields + // without inducing compile errors. + auto CheckClash = [&fields, &struct_def](const char *suffix, + BaseType basetype) { + auto len = strlen(suffix); + for (auto it = fields.begin(); it != fields.end(); ++it) { + auto &name = (*it)->name; + if (name.length() > len && + name.compare(name.length() - len, len, suffix) == 0 && + (*it)->value.type.base_type != BASE_TYPE_UTYPE) { + auto field = struct_def.fields.Lookup( + name.substr(0, name.length() - len)); + if (field && field->value.type.base_type == basetype) + Error("Field " + name + + " would clash with generated functions for field " + + field->name); + } + } + }; + CheckClash("_type", BASE_TYPE_UNION); + CheckClash("Type", BASE_TYPE_UNION); + CheckClash("_length", BASE_TYPE_VECTOR); + CheckClash("Length", BASE_TYPE_VECTOR); Expect('}'); } diff --git a/tests/test.cpp b/tests/test.cpp index 07545a0a8..edb971aab 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -488,6 +488,7 @@ void ErrorTest() { TestError("struct X { Y:int; } root_type X;", "a table"); TestError("union X { Y }", "referenced"); TestError("union Z { X } struct X { Y:int; }", "only tables"); + TestError("table X { Y:[int]; YLength:int; }", "clash"); } // Additional parser testing not covered elsewhere.