Skip to content

Commit d2956a3

Browse files
committed
[libcxx] Fix ODR violation in iostream.
Note: This commit does not need a test, we already validate it via: * It compiles successfully after replacing `#include <istream>` with `#include <iostream>` in `iostream.cpp` * It passes existing tests after removing the ODR violation exception from the allowlist * There are already existing tests to validate that it runs correctly. Also tested with -ftrivial-auto-var-init and confirmed that it doesn't affect this (probably since it's a global variable)
1 parent c3959f2 commit d2956a3

8 files changed

+59
-68
lines changed

libcxx/include/__ostream/basic_ostream.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ class basic_ostream : virtual public basic_ios<_CharT, _Traits> {
5656
}
5757
~basic_ostream() override;
5858

59+
// Required by iostream to create cin as uninitialized.
60+
_LIBCPP_HIDE_FROM_ABI explicit basic_ostream(__uninitialized_ios uninit): basic_ios<_CharT, _Traits>(uninit) {}
61+
5962
basic_ostream(const basic_ostream& __rhs) = delete;
6063
basic_ostream& operator=(const basic_ostream& __rhs) = delete;
6164

libcxx/include/ios

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
250250

251251
typedef ptrdiff_t streamsize;
252252

253+
struct _LIBCPP_HIDE_FROM_ABI __uninitialized_ios{};
254+
253255
class _LIBCPP_EXPORTED_FROM_ABI ios_base {
254256
public:
255257
class _LIBCPP_EXPORTED_FROM_ABI failure;
@@ -370,6 +372,8 @@ protected:
370372
// for the details.
371373
}
372374

375+
_LIBCPP_HIDE_FROM_ABI constexpr ios_base(__uninitialized_ios) {}
376+
373377
void init(void* __sb);
374378
_LIBCPP_HIDE_FROM_ABI void* rdbuf() const { return __rdbuf_; }
375379

@@ -618,6 +622,9 @@ protected:
618622
// purposefully does no initialization
619623
// since the destructor does nothing this does not have ios_base issues.
620624
}
625+
626+
_LIBCPP_HIDE_FROM_ABI constexpr basic_ios(__uninitialized_ios uninit): ios_base{uninit} {}
627+
621628
_LIBCPP_HIDE_FROM_ABI void init(basic_streambuf<char_type, traits_type>* __sb);
622629

623630
_LIBCPP_HIDE_FROM_ABI void move(basic_ios& __rhs);

libcxx/include/istream

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,9 @@ protected:
224224
}
225225

226226
public:
227+
// Required by iostream to create cin as uninitialized.
228+
_LIBCPP_HIDE_FROM_ABI explicit basic_istream(__uninitialized_ios uninit): basic_ios<_CharT, _Traits>(uninit) {}
229+
227230
basic_istream(const basic_istream& __rhs) = delete;
228231
basic_istream& operator=(const basic_istream& __rhs) = delete;
229232

libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,7 +1222,7 @@
12221222
{'is_defined': True, 'name': '_ZNSt6__ndk131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
12231223
{'is_defined': True, 'name': '_ZNSt6__ndk132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
12241224
{'is_defined': True, 'name': '_ZNSt6__ndk134__construct_barrier_algorithm_baseERi', 'type': 'FUNC'}
1225-
{'is_defined': True, 'name': '_ZNSt6__ndk13cinE', 'size': 148, 'type': 'OBJECT'}
1225+
{'is_defined': True, 'name': '_ZNSt6__ndk13cinE', 'size': 88, 'type': 'OBJECT'}
12261226
{'is_defined': True, 'name': '_ZNSt6__ndk13pmr15memory_resourceD0Ev', 'type': 'FUNC'}
12271227
{'is_defined': True, 'name': '_ZNSt6__ndk13pmr15memory_resourceD1Ev', 'type': 'FUNC'}
12281228
{'is_defined': True, 'name': '_ZNSt6__ndk13pmr15memory_resourceD2Ev', 'type': 'FUNC'}
@@ -1290,9 +1290,9 @@
12901290
{'is_defined': True, 'name': '_ZNSt6__ndk14__fs10filesystem8__removeERKNS1_4pathEPNS_10error_codeE', 'type': 'FUNC'}
12911291
{'is_defined': True, 'name': '_ZNSt6__ndk14__fs10filesystem8__renameERKNS1_4pathES4_PNS_10error_codeE', 'type': 'FUNC'}
12921292
{'is_defined': True, 'name': '_ZNSt6__ndk14__fs10filesystem8__statusERKNS1_4pathEPNS_10error_codeE', 'type': 'FUNC'}
1293-
{'is_defined': True, 'name': '_ZNSt6__ndk14cerrE', 'size': 136, 'type': 'OBJECT'}
1294-
{'is_defined': True, 'name': '_ZNSt6__ndk14clogE', 'size': 136, 'type': 'OBJECT'}
1295-
{'is_defined': True, 'name': '_ZNSt6__ndk14coutE', 'size': 136, 'type': 'OBJECT'}
1293+
{'is_defined': True, 'name': '_ZNSt6__ndk14cerrE', 'size': 84, 'type': 'OBJECT'}
1294+
{'is_defined': True, 'name': '_ZNSt6__ndk14clogE', 'size': 84, 'type': 'OBJECT'}
1295+
{'is_defined': True, 'name': '_ZNSt6__ndk14coutE', 'size': 84, 'type': 'OBJECT'}
12961296
{'is_defined': True, 'name': '_ZNSt6__ndk14stodERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPj', 'type': 'FUNC'}
12971297
{'is_defined': True, 'name': '_ZNSt6__ndk14stodERKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEEPj', 'type': 'FUNC'}
12981298
{'is_defined': True, 'name': '_ZNSt6__ndk14stofERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPj', 'type': 'FUNC'}
@@ -1301,7 +1301,7 @@
13011301
{'is_defined': True, 'name': '_ZNSt6__ndk14stoiERKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEEPji', 'type': 'FUNC'}
13021302
{'is_defined': True, 'name': '_ZNSt6__ndk14stolERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPji', 'type': 'FUNC'}
13031303
{'is_defined': True, 'name': '_ZNSt6__ndk14stolERKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEEPji', 'type': 'FUNC'}
1304-
{'is_defined': True, 'name': '_ZNSt6__ndk14wcinE', 'size': 148, 'type': 'OBJECT'}
1304+
{'is_defined': True, 'name': '_ZNSt6__ndk14wcinE', 'size': 88, 'type': 'OBJECT'}
13051305
{'is_defined': True, 'name': '_ZNSt6__ndk15alignEjjRPvRj', 'type': 'FUNC'}
13061306
{'is_defined': True, 'name': '_ZNSt6__ndk15ctypeIcE10table_sizeE', 'size': 4, 'type': 'OBJECT'}
13071307
{'is_defined': True, 'name': '_ZNSt6__ndk15ctypeIcE13classic_tableEv', 'type': 'FUNC'}
@@ -1326,9 +1326,9 @@
13261326
{'is_defined': True, 'name': '_ZNSt6__ndk15stollERKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEEPji', 'type': 'FUNC'}
13271327
{'is_defined': True, 'name': '_ZNSt6__ndk15stoulERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPji', 'type': 'FUNC'}
13281328
{'is_defined': True, 'name': '_ZNSt6__ndk15stoulERKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEEPji', 'type': 'FUNC'}
1329-
{'is_defined': True, 'name': '_ZNSt6__ndk15wcerrE', 'size': 136, 'type': 'OBJECT'}
1330-
{'is_defined': True, 'name': '_ZNSt6__ndk15wclogE', 'size': 136, 'type': 'OBJECT'}
1331-
{'is_defined': True, 'name': '_ZNSt6__ndk15wcoutE', 'size': 136, 'type': 'OBJECT'}
1329+
{'is_defined': True, 'name': '_ZNSt6__ndk15wcerrE', 'size': 84, 'type': 'OBJECT'}
1330+
{'is_defined': True, 'name': '_ZNSt6__ndk15wclogE', 'size': 84, 'type': 'OBJECT'}
1331+
{'is_defined': True, 'name': '_ZNSt6__ndk15wcoutE', 'size': 84, 'type': 'OBJECT'}
13321332
{'is_defined': True, 'name': '_ZNSt6__ndk16__clocEv', 'type': 'FUNC'}
13331333
{'is_defined': True, 'name': '_ZNSt6__ndk16__itoa8__u32toaEjPc', 'type': 'FUNC'}
13341334
{'is_defined': True, 'name': '_ZNSt6__ndk16__itoa8__u64toaEyPc', 'type': 'FUNC'}

libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,7 +1237,6 @@
12371237
{'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
12381238
{'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
12391239
{'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'}
1240-
{'is_defined': True, 'name': '_ZNSt3__13cinE', 'size': 400, 'type': 'OBJECT'}
12411240
{'is_defined': True, 'name': '_ZNSt3__13pmr15memory_resourceD0Ev', 'type': 'FUNC'}
12421241
{'is_defined': True, 'name': '_ZNSt3__13pmr15memory_resourceD1Ev', 'type': 'FUNC'}
12431242
{'is_defined': True, 'name': '_ZNSt3__13pmr15memory_resourceD2Ev', 'type': 'FUNC'}
@@ -1305,9 +1304,6 @@
13051304
{'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem8__removeERKNS1_4pathEPNS_10error_codeE', 'type': 'FUNC'}
13061305
{'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem8__renameERKNS1_4pathES4_PNS_10error_codeE', 'type': 'FUNC'}
13071306
{'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem8__statusERKNS1_4pathEPNS_10error_codeE', 'type': 'FUNC'}
1308-
{'is_defined': True, 'name': '_ZNSt3__14cerrE', 'size': 384, 'type': 'OBJECT'}
1309-
{'is_defined': True, 'name': '_ZNSt3__14clogE', 'size': 384, 'type': 'OBJECT'}
1310-
{'is_defined': True, 'name': '_ZNSt3__14coutE', 'size': 384, 'type': 'OBJECT'}
13111307
{'is_defined': True, 'name': '_ZNSt3__14stodERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPm', 'type': 'FUNC'}
13121308
{'is_defined': True, 'name': '_ZNSt3__14stodERKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEEPm', 'type': 'FUNC'}
13131309
{'is_defined': True, 'name': '_ZNSt3__14stofERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPm', 'type': 'FUNC'}
@@ -1316,7 +1312,6 @@
13161312
{'is_defined': True, 'name': '_ZNSt3__14stoiERKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEEPmi', 'type': 'FUNC'}
13171313
{'is_defined': True, 'name': '_ZNSt3__14stolERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPmi', 'type': 'FUNC'}
13181314
{'is_defined': True, 'name': '_ZNSt3__14stolERKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEEPmi', 'type': 'FUNC'}
1319-
{'is_defined': True, 'name': '_ZNSt3__14wcinE', 'size': 400, 'type': 'OBJECT'}
13201315
{'is_defined': True, 'name': '_ZNSt3__15alignEmmRPvRm', 'type': 'FUNC'}
13211316
{'is_defined': True, 'name': '_ZNSt3__15ctypeIcE10table_sizeE', 'size': 8, 'type': 'OBJECT'}
13221317
{'is_defined': True, 'name': '_ZNSt3__15ctypeIcE13classic_tableEv', 'type': 'FUNC'}
@@ -1341,9 +1336,6 @@
13411336
{'is_defined': True, 'name': '_ZNSt3__15stollERKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEEPmi', 'type': 'FUNC'}
13421337
{'is_defined': True, 'name': '_ZNSt3__15stoulERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPmi', 'type': 'FUNC'}
13431338
{'is_defined': True, 'name': '_ZNSt3__15stoulERKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEEPmi', 'type': 'FUNC'}
1344-
{'is_defined': True, 'name': '_ZNSt3__15wcerrE', 'size': 384, 'type': 'OBJECT'}
1345-
{'is_defined': True, 'name': '_ZNSt3__15wclogE', 'size': 384, 'type': 'OBJECT'}
1346-
{'is_defined': True, 'name': '_ZNSt3__15wcoutE', 'size': 384, 'type': 'OBJECT'}
13471339
{'is_defined': True, 'name': '_ZNSt3__16__itoa8__u32toaEjPc', 'type': 'FUNC'}
13481340
{'is_defined': True, 'name': '_ZNSt3__16__itoa8__u64toaEmPc', 'type': 'FUNC'}
13491341
{'is_defined': True, 'name': '_ZNSt3__16__sortIRNS_6__lessIaaEEPaEEvT0_S5_T_', 'type': 'FUNC'}

libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,7 +1235,6 @@
12351235
{'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
12361236
{'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
12371237
{'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'}
1238-
{'is_defined': True, 'name': '_ZNSt3__13cinE', 'size': 280, 'type': 'OBJECT'}
12391238
{'is_defined': True, 'name': '_ZNSt3__13pmr15memory_resourceD0Ev', 'type': 'FUNC'}
12401239
{'is_defined': True, 'name': '_ZNSt3__13pmr15memory_resourceD1Ev', 'type': 'FUNC'}
12411240
{'is_defined': True, 'name': '_ZNSt3__13pmr15memory_resourceD2Ev', 'type': 'FUNC'}
@@ -1303,9 +1302,6 @@
13031302
{'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem8__removeERKNS1_4pathEPNS_10error_codeE', 'type': 'FUNC'}
13041303
{'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem8__renameERKNS1_4pathES4_PNS_10error_codeE', 'type': 'FUNC'}
13051304
{'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem8__statusERKNS1_4pathEPNS_10error_codeE', 'type': 'FUNC'}
1306-
{'is_defined': True, 'name': '_ZNSt3__14cerrE', 'size': 264, 'type': 'OBJECT'}
1307-
{'is_defined': True, 'name': '_ZNSt3__14clogE', 'size': 264, 'type': 'OBJECT'}
1308-
{'is_defined': True, 'name': '_ZNSt3__14coutE', 'size': 264, 'type': 'OBJECT'}
13091305
{'is_defined': True, 'name': '_ZNSt3__14stodERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPm', 'type': 'FUNC'}
13101306
{'is_defined': True, 'name': '_ZNSt3__14stodERKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEEPm', 'type': 'FUNC'}
13111307
{'is_defined': True, 'name': '_ZNSt3__14stofERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPm', 'type': 'FUNC'}
@@ -1314,7 +1310,6 @@
13141310
{'is_defined': True, 'name': '_ZNSt3__14stoiERKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEEPmi', 'type': 'FUNC'}
13151311
{'is_defined': True, 'name': '_ZNSt3__14stolERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPmi', 'type': 'FUNC'}
13161312
{'is_defined': True, 'name': '_ZNSt3__14stolERKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEEPmi', 'type': 'FUNC'}
1317-
{'is_defined': True, 'name': '_ZNSt3__14wcinE', 'size': 280, 'type': 'OBJECT'}
13181313
{'is_defined': True, 'name': '_ZNSt3__15alignEmmRPvRm', 'type': 'FUNC'}
13191314
{'is_defined': True, 'name': '_ZNSt3__15ctypeIcE10table_sizeE', 'size': 8, 'type': 'OBJECT'}
13201315
{'is_defined': True, 'name': '_ZNSt3__15ctypeIcE13classic_tableEv', 'type': 'FUNC'}
@@ -1341,9 +1336,6 @@
13411336
{'is_defined': True, 'name': '_ZNSt3__15stollERKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEEPmi', 'type': 'FUNC'}
13421337
{'is_defined': True, 'name': '_ZNSt3__15stoulERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPmi', 'type': 'FUNC'}
13431338
{'is_defined': True, 'name': '_ZNSt3__15stoulERKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEEPmi', 'type': 'FUNC'}
1344-
{'is_defined': True, 'name': '_ZNSt3__15wcerrE', 'size': 264, 'type': 'OBJECT'}
1345-
{'is_defined': True, 'name': '_ZNSt3__15wclogE', 'size': 264, 'type': 'OBJECT'}
1346-
{'is_defined': True, 'name': '_ZNSt3__15wcoutE', 'size': 264, 'type': 'OBJECT'}
13471339
{'is_defined': True, 'name': '_ZNSt3__16__clocEv', 'type': 'FUNC'}
13481340
{'is_defined': True, 'name': '_ZNSt3__16__itoa8__u32toaEjPc', 'type': 'FUNC'}
13491341
{'is_defined': True, 'name': '_ZNSt3__16__itoa8__u64toaEmPc', 'type': 'FUNC'}

libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,7 +1206,6 @@
12061206
{'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
12071207
{'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
12081208
{'is_defined': True, 'name': '_ZNSt3__134__construct_barrier_algorithm_baseERl', 'type': 'FUNC'}
1209-
{'is_defined': True, 'name': '_ZNSt3__13cinE', 'size': 280, 'type': 'OBJECT'}
12101209
{'is_defined': True, 'name': '_ZNSt3__13pmr15memory_resourceD0Ev', 'type': 'FUNC'}
12111210
{'is_defined': True, 'name': '_ZNSt3__13pmr15memory_resourceD1Ev', 'type': 'FUNC'}
12121211
{'is_defined': True, 'name': '_ZNSt3__13pmr15memory_resourceD2Ev', 'type': 'FUNC'}
@@ -1274,9 +1273,6 @@
12741273
{'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem8__removeERKNS1_4pathEPNS_10error_codeE', 'type': 'FUNC'}
12751274
{'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem8__renameERKNS1_4pathES4_PNS_10error_codeE', 'type': 'FUNC'}
12761275
{'is_defined': True, 'name': '_ZNSt3__14__fs10filesystem8__statusERKNS1_4pathEPNS_10error_codeE', 'type': 'FUNC'}
1277-
{'is_defined': True, 'name': '_ZNSt3__14cerrE', 'size': 264, 'type': 'OBJECT'}
1278-
{'is_defined': True, 'name': '_ZNSt3__14clogE', 'size': 264, 'type': 'OBJECT'}
1279-
{'is_defined': True, 'name': '_ZNSt3__14coutE', 'size': 264, 'type': 'OBJECT'}
12801276
{'is_defined': True, 'name': '_ZNSt3__14stodERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPm', 'type': 'FUNC'}
12811277
{'is_defined': True, 'name': '_ZNSt3__14stodERKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEEPm', 'type': 'FUNC'}
12821278
{'is_defined': True, 'name': '_ZNSt3__14stofERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPm', 'type': 'FUNC'}
@@ -1285,7 +1281,6 @@
12851281
{'is_defined': True, 'name': '_ZNSt3__14stoiERKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEEPmi', 'type': 'FUNC'}
12861282
{'is_defined': True, 'name': '_ZNSt3__14stolERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPmi', 'type': 'FUNC'}
12871283
{'is_defined': True, 'name': '_ZNSt3__14stolERKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEEPmi', 'type': 'FUNC'}
1288-
{'is_defined': True, 'name': '_ZNSt3__14wcinE', 'size': 280, 'type': 'OBJECT'}
12891284
{'is_defined': True, 'name': '_ZNSt3__15alignEmmRPvRm', 'type': 'FUNC'}
12901285
{'is_defined': True, 'name': '_ZNSt3__15ctypeIcE10table_sizeE', 'size': 8, 'type': 'OBJECT'}
12911286
{'is_defined': True, 'name': '_ZNSt3__15ctypeIcE13classic_tableEv', 'type': 'FUNC'}
@@ -1312,9 +1307,6 @@
13121307
{'is_defined': True, 'name': '_ZNSt3__15stollERKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEEPmi', 'type': 'FUNC'}
13131308
{'is_defined': True, 'name': '_ZNSt3__15stoulERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPmi', 'type': 'FUNC'}
13141309
{'is_defined': True, 'name': '_ZNSt3__15stoulERKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEEPmi', 'type': 'FUNC'}
1315-
{'is_defined': True, 'name': '_ZNSt3__15wcerrE', 'size': 264, 'type': 'OBJECT'}
1316-
{'is_defined': True, 'name': '_ZNSt3__15wclogE', 'size': 264, 'type': 'OBJECT'}
1317-
{'is_defined': True, 'name': '_ZNSt3__15wcoutE', 'size': 264, 'type': 'OBJECT'}
13181310
{'is_defined': True, 'name': '_ZNSt3__16__clocEv', 'type': 'FUNC'}
13191311
{'is_defined': True, 'name': '_ZNSt3__16__itoa8__u32toaEjPc', 'type': 'FUNC'}
13201312
{'is_defined': True, 'name': '_ZNSt3__16__itoa8__u64toaEmPc', 'type': 'FUNC'}

libcxx/src/iostream.cpp

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,18 @@
99
#include "std_stream.h"
1010

1111
#include <__memory/construct_at.h>
12-
#include <__ostream/basic_ostream.h>
13-
#include <istream>
12+
#include <iostream>
1413

1514
#define ABI_NAMESPACE_STR _LIBCPP_TOSTRING(_LIBCPP_ABI_NAMESPACE)
1615

1716
_LIBCPP_BEGIN_NAMESPACE_STD
1817

19-
template <class StreamT, class BufferT>
18+
template <class BufferT, typename StreamT, StreamT& stream>
2019
union stream_data {
2120
constexpr stream_data() {}
2221
constexpr ~stream_data() {}
22+
// Make this a struct inside a union so it can be uninitialized.
2323
struct {
24-
// The stream has to be the first element, since that's referenced by the stream declarations in <iostream>
25-
StreamT stream;
2624
BufferT buffer;
2725
mbstate_t mb;
2826
};
@@ -50,21 +48,25 @@ union stream_data {
5048
"?" #var "@" ABI_NAMESPACE_STR "@std@@3V?$" #StreamT \
5149
"@" CHAR_MANGLING(CharT) "U?$char_traits@" CHAR_MANGLING(CharT) "@" ABI_NAMESPACE_STR "@std@@@12@A")
5250
#else
53-
# define STREAM(StreamT, BufferT, CharT, var) STRING_DATA_CONSTINIT stream_data<StreamT<CharT>, BufferT<CharT>> var
54-
#endif
5551

56-
// These definitions and the declarations in <iostream> technically cause ODR violations, since they have different
57-
// types (stream_data and {i,o}stream respectively). This means that <iostream> should never be included in this TU.
52+
// To avoid ODR violations without breaking the ABI, we need to define it as a StreamT<CharT>.
53+
// However, since initialization order of statics is arbitrary, we could run DoIOSInit first and then
54+
// construct the stream for a second time, overwriting the data in it.
55+
// To avoid this, we call a constructor overload that specifically avoids initializing any members.
56+
# define STREAM(StreamT, BufferT, CharT, var) \
57+
StreamT<CharT> var{std::__uninitialized_ios{}}; \
58+
static stream_data<BufferT<CharT>, StreamT<CharT>, var> sd_##var;
59+
#endif
5860

59-
_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_istream, __stdinbuf, char, cin);
60-
_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, char, cout);
61-
_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, char, cerr);
62-
_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, char, clog);
61+
_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_istream, __stdinbuf, char, cin)
62+
_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, char, cout)
63+
_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, char, cerr)
64+
_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, char, clog)
6365
#if _LIBCPP_HAS_WIDE_CHARACTERS
64-
_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_istream, __stdinbuf, wchar_t, wcin);
65-
_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, wchar_t, wcout);
66-
_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, wchar_t, wcerr);
67-
_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, wchar_t, wclog);
66+
_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_istream, __stdinbuf, wchar_t, wcin)
67+
_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, wchar_t, wcout)
68+
_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, wchar_t, wcerr)
69+
_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, wchar_t, wclog)
6870
#endif // _LIBCPP_HAS_WIDE_CHARACTERS
6971

7072
// Pretend we're inside a system header so the compiler doesn't flag the use of the init_priority
@@ -98,34 +100,34 @@ class DoIOSInit {
98100
DoIOSInit::DoIOSInit() {
99101
force_locale_initialization();
100102

101-
cin.init(stdin);
102-
cout.init(stdout);
103-
cerr.init(stderr);
104-
clog.init(stderr);
103+
sd_cin.init(stdin);
104+
sd_cout.init(stdout);
105+
sd_cerr.init(stderr);
106+
sd_clog.init(stderr);
105107

106-
cin.stream.tie(&cout.stream);
107-
std::unitbuf(cerr.stream);
108-
cerr.stream.tie(&cout.stream);
108+
cin.tie(&cout);
109+
std::unitbuf(cerr);
110+
cerr.tie(&cout);
109111

110112
#if _LIBCPP_HAS_WIDE_CHARACTERS
111-
wcin.init(stdin);
112-
wcout.init(stdout);
113-
wcerr.init(stderr);
114-
wclog.init(stderr);
115-
116-
wcin.stream.tie(&wcout.stream);
117-
std::unitbuf(wcerr.stream);
118-
wcerr.stream.tie(&wcout.stream);
113+
sd_wcin.init(stdin);
114+
sd_wcout.init(stdout);
115+
sd_wcerr.init(stderr);
116+
sd_wclog.init(stderr);
117+
118+
wcin.tie(&wcout);
119+
std::unitbuf(wcerr);
120+
wcerr.tie(&wcout);
119121
#endif
120122
}
121123

122124
DoIOSInit::~DoIOSInit() {
123-
cout.stream.flush();
124-
clog.stream.flush();
125+
cout.flush();
126+
clog.flush();
125127

126128
#if _LIBCPP_HAS_WIDE_CHARACTERS
127-
wcout.stream.flush();
128-
wclog.stream.flush();
129+
wcout.flush();
130+
wclog.flush();
129131
#endif
130132
}
131133

0 commit comments

Comments
 (0)