arseny.kapoulkine created this revision. arseny.kapoulkine added a subscriber: cfe-commits.
For nested functions, local-name can be followed by function arguments; in some cases the first argument starts with a digit (if it's a named type). For example, this code: void test() { struct g { void foo(Point p); }; } Generates this name for symbol foo: _ZZ4testvEN1g3fooE5Point When decomposed, this results in a local-name with entity name N1g3fooE (aka g::foo). According to Itanium ABI, entity name can be followed by a discriminator that has to start with _. However, libcxxabi defines an extension that says that discriminator can start with a digit. This makes the grammar ambiguous, and causes 5 to be skipped and Point to be parsed as a series of types for function arguments. Resolve ambiguity by requiring that a digit-only discriminator is the last token in the input string. http://reviews.llvm.org/D13192 Files: libcxxabi/trunk/src/cxa_demangle.cpp libcxxabi/trunk/test/test_demangle.pass.cpp Index: libcxxabi/trunk/test/test_demangle.pass.cpp =================================================================== --- libcxxabi/trunk/test/test_demangle.pass.cpp +++ libcxxabi/trunk/test/test_demangle.pass.cpp @@ -29593,6 +29593,7 @@ {"_ZNK3Ncr6Silver7Utility6detail12CallOnThreadIZ53-[DeploymentSetupController handleManualServerEntry:]E3$_5EclIJEEEDTclclL_ZNS2_4getTIS4_EERT_vEEspclsr3stdE7forwardIT_Efp_EEEDpOSA_", "decltype(-[DeploymentSetupController handleManualServerEntry:]::$_5& Ncr::Silver::Utility::detail::getT<-[DeploymentSetupController handleManualServerEntry:]::$_5>()()(std::forward<-[DeploymentSetupController handleManualServerEntry:]::$_5>(fp))) Ncr::Silver::Utility::detail::CallOnThread<-[DeploymentSetupController handleManualServerEntry:]::$_5>::operator()<>(-[DeploymentSetupController handleManualServerEntry:]::$_5&&) const"}, {"_Zli2_xy", "operator\"\" _x(unsigned long long)"}, {"_Z1fIiEDcT_", "decltype(auto) f<int>(int)"}, + {"_ZZ4testvEN1g3fooE5Point", "test()::g::foo(Point)"}, }; const unsigned N = sizeof(cases) / sizeof(cases[0]); Index: libcxxabi/trunk/src/cxa_demangle.cpp =================================================================== --- libcxxabi/trunk/src/cxa_demangle.cpp +++ libcxxabi/trunk/src/cxa_demangle.cpp @@ -4054,7 +4054,7 @@ // <discriminator> := _ <non-negative number> # when number < 10 // := __ <non-negative number> _ # when number >= 10 -// extension := decimal-digit+ +// extension := decimal-digit+ # at the end of string const char* parse_discriminator(const char* first, const char* last) @@ -4083,7 +4083,8 @@ const char* t1 = first+1; for (; t1 != last && std::isdigit(*t1); ++t1) ; - first = t1; + if (t1 == last) + first = last; } } return first;
Index: libcxxabi/trunk/test/test_demangle.pass.cpp =================================================================== --- libcxxabi/trunk/test/test_demangle.pass.cpp +++ libcxxabi/trunk/test/test_demangle.pass.cpp @@ -29593,6 +29593,7 @@ {"_ZNK3Ncr6Silver7Utility6detail12CallOnThreadIZ53-[DeploymentSetupController handleManualServerEntry:]E3$_5EclIJEEEDTclclL_ZNS2_4getTIS4_EERT_vEEspclsr3stdE7forwardIT_Efp_EEEDpOSA_", "decltype(-[DeploymentSetupController handleManualServerEntry:]::$_5& Ncr::Silver::Utility::detail::getT<-[DeploymentSetupController handleManualServerEntry:]::$_5>()()(std::forward<-[DeploymentSetupController handleManualServerEntry:]::$_5>(fp))) Ncr::Silver::Utility::detail::CallOnThread<-[DeploymentSetupController handleManualServerEntry:]::$_5>::operator()<>(-[DeploymentSetupController handleManualServerEntry:]::$_5&&) const"}, {"_Zli2_xy", "operator\"\" _x(unsigned long long)"}, {"_Z1fIiEDcT_", "decltype(auto) f<int>(int)"}, + {"_ZZ4testvEN1g3fooE5Point", "test()::g::foo(Point)"}, }; const unsigned N = sizeof(cases) / sizeof(cases[0]); Index: libcxxabi/trunk/src/cxa_demangle.cpp =================================================================== --- libcxxabi/trunk/src/cxa_demangle.cpp +++ libcxxabi/trunk/src/cxa_demangle.cpp @@ -4054,7 +4054,7 @@ // <discriminator> := _ <non-negative number> # when number < 10 // := __ <non-negative number> _ # when number >= 10 -// extension := decimal-digit+ +// extension := decimal-digit+ # at the end of string const char* parse_discriminator(const char* first, const char* last) @@ -4083,7 +4083,8 @@ const char* t1 = first+1; for (; t1 != last && std::isdigit(*t1); ++t1) ; - first = t1; + if (t1 == last) + first = last; } } return first;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits