Skip to content

Potential ODR violation linking C++14 with C++17+ TUs that use container emplace functions #4962

@CaseyCarter

Description

@CaseyCarter

The emplace_front and emplace_back members of our containers and emplace members of our container adaptors use a "tricky" technique to implement the C++17 change that had these functions return a reference to the newly emplaced element. We changed the declared return types from void to decltype(auto), and each function returns with e.g.:

#if _HAS_CXX17
    return back();
#endif

This approach has the nice property that the functions continue to return void in C++14 mode as they did before the change.

However, the mangled name of the functions is the same in both language modes (credit to STL):

C:\Temp>type meow.cpp

#include <vector>

decltype(auto) meow(std::vector<int>& v) {
    return v.emplace_back(1729);
}

C:\Temp>cl /EHsc /nologo /W4 /std:c++14 /c meow.cpp
meow.cpp

C:\Temp>dumpbin /symbols meow.obj | rg emplace_back
0AC 00000000 SECT19 notype ()    External     | ??$emplace_back@H@?$vector@HV?$allocator@H@std@@@std@@QEAA?A_T$$QEAH@Z (public: decltype(auto) __cdecl std::vector<int,class std::allocator<int> >::emplace_back<int>(int &&))
196 00000000 SECT73 notype       Static       | $unwind$??$emplace_back@H@?$vector@HV?$allocator@H@std@@@std@@QEAA?A_T$$QEAH@Z
199 00000000 SECT74 notype       Static       | $pdata$??$emplace_back@H@?$vector@HV?$allocator@H@std@@@std@@QEAA?A_T$$QEAH@Z

C:\Temp>cl /EHsc /nologo /W4 /std:c++latest /c meow.cpp
meow.cpp

C:\Temp>dumpbin /symbols meow.obj | rg emplace_back
0B0 00000000 SECT1A notype ()    External     | ??$emplace_back@H@?$vector@HV?$allocator@H@std@@@std@@QEAA?A_T$$QEAH@Z (public: decltype(auto) __cdecl std::vector<int,class std::allocator<int> >::emplace_back<int>(int &&))
19C 00000000 SECT74 notype       Static       | $unwind$??$emplace_back@H@?$vector@HV?$allocator@H@std@@@std@@QEAA?A_T$$QEAH@Z
19F 00000000 SECT75 notype       Static       | $pdata$??$emplace_back@H@?$vector@HV?$allocator@H@std@@@std@@QEAA?A_T$$QEAH@Z

potentially creating an ODR violation when linking C++14 and C++17 TUs that instantiate the same emplace function. If a C++17 TU uses the returned reference, but the linker chooses the instantiation from a C++14 TU that returns no such reference, terrible things will happen.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixedSomething works now, yay!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions