Repository navigation
fix(cpp): a bare call in a gtest TEST_F or TEST_P body reaches the fixture's method - #2537
Merged
Merged
Conversation
…xture's method The index holds a gtest `TEST_F(Fixture, Name)` / `TEST_P` body as a function named `TEST_F`; gtest makes it a method of a class derived from `Fixture`. #2533 gave such a body the fixture's data members (cppTestFixture), not its methods. rocksdb's tests call `DBTestBase`'s `Put(…)`, `Flush()`, `Key(i)` and `NewIterator(…)` bare, and those calls were guessed by name, often reaching a namesake in another class at 0.4 (`ColumnFamilyTestBase::Put`); `auto iter = NewIterator(…)` gave `iter` no type, so `iter->SeekToFirst()` reached the nested `MemTableRep::Iterator`. - cppImplicitThisMethod is #2479's lookup, taken out of matchCppImplicitThisCall: the caller's class, its bases, the classes around it, with cppTestFixture as the owner of a gtest body. matchCppImplicitThisCall keeps the local-shadowing check for the link. - cppExpressionType types a bare call by the same lookup, as on `this`, instead of the class's first declaration. Of two classes sharing a name in different test files it reads the caller's own, and in a template a dependent base a using-declaration names still counts, as before (protobuf's `using RepeatedFieldWrapper<T>::MutableRepeatedField;`). `this` in a gtest body points to the fixture. - A `->` call on a value of a type from outside the project no longer takes the type's last name for the class it is in (isCppArrowThroughOutsideType); the name strategies decide. matchCppDeclaredTypeCall steps aside for `->` on a value before #2532's outside-type check, so typing JsonTest's `auto m = ToProto<Any>(…)` (an `absl::StatusOr<Any>`) had sent `m->value()` to protobuf's own `hpb::StatusOr::value` at 0.9. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 13, 2026
# Conflicts: # CHANGELOG.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The index holds a gtest
TEST_F(Fixture, Name)orTEST_Pbody as a function namedTEST_F, but gtest makes it a method of a class it derives fromFixture. C++ looks a name the body calls up in that class, then in the fixture and the classes it derives from, before the namespace.#2533 gave such a body the fixture's data members (
cppTestFixture), but not its methods. facebook/rocksdb's 5,000 test bodies callDBTestBase'sPut(…),Flush(),Key(i)andNewIterator(…)bare, and those calls were guessed by name:ColumnFamilyTestBase::Put,WriteBatch::Put);auto iter = NewIterator(…)gaveiterno type, soiter->SeekToFirst()reached the nestedMemTableRep::Iterator.protocolbuffers/protobuf's command-line tests sent
ExpectNoErrors()to the unrelatedEncodeDecodeTest::ExpectNoErrors.What changed (name-matcher.ts)
cppImplicitThisMethod. This is fix(cpp): a call a method makes with no receiver links to its class's own or inherited method #2479's lookup taken out ofmatchCppImplicitThisCall: the caller's class, the classes it derives from, then the classes around it. A gtest body's owner is its fixture (cppTestFixture).BestEffortsRecoverIncompleteVersionTestandLRUCacheTestin two test files each, with different bases.matchCppImplicitThisCallkeeps fix(cpp): a call a method makes with no receiver links to its class's own or inherited method #2479's local-shadowing check for the link.cppExpressionTypetypes a bare call (auto iter = NewIterator(…)) with the same lookup, made as onthis, rather than in the class's first declaration.using RepeatedFieldWrapper<T>::MutableRepeatedField;.thisin a gtest body is a pointer to the fixture.->on a value of an outside type. A->call on a value of a type from outside the project no longer takes that type's last name for the class (isCppArrowThroughOutsideType); the name strategies decide.auto m = ToProto<Any>(…)asabsl::StatusOr<Any>had sentm->value()to protobuf's ownhpb::StatusOr::valueat 0.9.autovariable or a chained call reaches the class C++ finds, not a namesake #2532's outside-type gate for->on a value, so that gate never saw these calls. On main, a declaredabsl::StatusOr<Any> parsedgets the same; these repos just declare none whose methodhpb::StatusOralso has.Validation
Site-keyed edge diffs (
diff-sites.mjs), maindf3ce972vs this branch, both built from the same tree, kernel included:Nodes and files are identical between the arms, and every changed site is in a gtest
TEST_F/TEST_Pbody: no edge outside one moved.Retargeted, every group read. A script checked every retargeted or added bare call in a gtest body: it reaches the fixture the body's header names, or a class the fixture derives from.
using FeaturesBaseTest = ValidationErrorTest;.The large groups, by the class the calls left:
Flush()andPut(…)go fromColumnFamilyTestBase's namesakes at 0.4 toDBTestBaseat 0.9;Key(i), toDBTestBase's static method, which the class scope finds first;CompactionJobStatsTestand 1,549CuckooTableDBTest(DestroyAndReopen,CurrentOptions, …);iter->Seek(…)/iter->SeekToFirst()calls leaveMemTableRep::IteratorforIteratorBase.ExpectNoErrors()calls go to theCommandLineInterfaceTesterthatCommandLineInterfaceTestderives from;BuildFile(…)calls go toValidationErrorTest, no longerAllowUnknownDependenciesTest;AddToDatabasecalls go to the fixture's method, which hides the namespace function of that name.LogTest::Read, not the nestedStringSource::Read;DBTest::Put, notModelDB::Put;Harness::Add.Overload choices within one class (rocksdb 520, protobuf 437) were sorted by argument count against each overload's parameters. 809 fit better and none fit worse. 135 tie on arity, and 13 have raw-string arguments the count can't read:
const char*/std::string,Get(0, "key0")toGet(int cf, …), braced lists tostd::initializer_list.cppOverloadForkeeps the first-written overload when arguments tie, and here only the argument's type tells them apart:BuildFile(X::descriptor()->file())(18) now reachesBuildFile(absl::string_view), notBuildFile(const FileDescriptor*), which main's 0.7 guess had;Insert(ch)on achar(2).Removed, every site read. rocksdb's 68 and protobuf's 14 were wrong guesses on library types the fixture's methods now type:
compaction_stats.size()and 10blob_files_initial.size()on returnedstd::vectors, which had reachedCompactionInputFiles/BlobContentsat 0.65;arena.get()on astd::unique_ptr<Arena>, which had reachedArenaHolder::get.Added:
dbfull()->TEST_CompactMemTable(), rocksdb'sdbfull()->TEST_WaitForCompact();iter->Seek(…),precise_cache->GetUsage()onNewCache(…)'sstd::shared_ptr<Cache>.Metadata-only: the same target, now found by C++ lookup at 0.9, no longer guessed.
Tests:
__tests__/cpp-test-fixture-call.test.ts, 9 cases:auto iter = NewIterator();TEST_Pandthis->;->on anabsl::StatusOrvalue, which main sends tohpb::StatusOrfor a declared parameter.TESTbody has no fixture;SpecialEnv, which an earlier version of this change broke);RepeatedFieldPrimitiveAccessor).Together with #2536
Iterator* const iter). The two branches touch different parts of name-matcher.ts and conflict only in CHANGELOG, where both bullets go after fix(cpp): a call on a data member of the caller's class reaches its type's method, wherever the class is declared #2533's: keep both.df3ce972pass the 28 C/C++ test files (335 tests).MemTableRep::Iteratorgo from 111 to 53, the same as with this PR alone. 44 of the 53 are right:memtable.cc's own 42, and 2 on astatic_cast<MemTableRep::Iterator*>. The other 9 have a receiver typed through astd::function<Iterator*()>call or a structured binding (auto& [cfh, iter]).Not in this PR
cppOverloadFit), not by the arguments' types: the 20 ties above.absl::StatusOr<T>'s->isn't followed toTthe waystd::unique_ptr's andstd::optional's are, soresolver->MergeFeatures(…)stays a 0.7 guess.🤖 Generated with Claude Code