File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -267,12 +267,15 @@ class CG {
267267 */
268268template <class Base >
269269struct CGOStreamFunc {
270- static thread_local std::function<std::ostream& (std::ostream&, const CG <Base>&)> FUNC ;
270+ // Because of a GCC bug (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66944)
271+ // FUNC_OBJ can't be a CGOStreamFunc static member.
272+ // Instead, we store it as CGOStreamFunc::FUNC method static variable.
273+ static std::function<std::ostream& (std::ostream&, const CG <Base>&)>& FUNC () {
274+ static thread_local std::function<std::ostream& (std::ostream&, const CG <Base>&)> FUNC_OBJ = nullptr ;
275+ return FUNC_OBJ ;
276+ }
271277};
272278
273- template <class Base >
274- thread_local std::function<std::ostream& (std::ostream&, const CG <Base>&)> CGOStreamFunc<Base>::FUNC = nullptr ;
275-
276279/* *
277280 * Output stream operator for CG objects.
278281 * Default behavior can be overridden using CGOStreamFunc::FUN.
@@ -282,8 +285,8 @@ inline std::ostream& operator<<(
282285 std::ostream& os, // < stream to write to
283286 const CG <Base>& v// < vector that is output
284287 ) {
285- if (CGOStreamFunc<Base>::FUNC != nullptr ) {
286- return CGOStreamFunc<Base>::FUNC (os, v);
288+ if (CGOStreamFunc<Base>::FUNC () != nullptr ) {
289+ return CGOStreamFunc<Base>::FUNC ()( os, v);
287290 }
288291
289292 if (v.isParameter ()) {
Original file line number Diff line number Diff line change @@ -44,16 +44,16 @@ class OperationNodeNameStreambuf : public std::streambuf {
4444 if (BUF != nullptr ) {
4545 throw CGException (" Only one OperationNodeNameStreambuf can exist at a time in each thread" );
4646 }
47- if (CGOStreamFunc<Base>::FUNC != nullptr ) {
47+ if (CGOStreamFunc<Base>::FUNC () != nullptr ) {
4848 throw CGException (" CGOStreamFunc<Base>::FUNC already defined in this thread" );
4949 }
5050 BUF = this ;
51- CGOStreamFunc<Base>::FUNC = registerNode;
51+ CGOStreamFunc<Base>::FUNC () = registerNode;
5252 }
5353
5454 virtual ~OperationNodeNameStreambuf () {
5555 BUF = nullptr ;
56- CGOStreamFunc<Base>::FUNC = nullptr ;
56+ CGOStreamFunc<Base>::FUNC () = nullptr ;
5757 }
5858
5959 std::streamsize xsputn (const char_type* s,
Original file line number Diff line number Diff line change @@ -22,6 +22,7 @@ add_cppadcg_test(inputstream.cpp)
2222add_cppadcg_test (temporary.cpp )
2323add_cppadcg_test (mult_sparsity_pattern.cpp )
2424add_cppadcg_test (multi_object_1.cpp multi_object.cpp )
25+ add_cppadcg_test (gcc_build_issue.cpp )
2526
2627ADD_SUBDIRECTORY (extra )
2728ADD_SUBDIRECTORY (operations )
Original file line number Diff line number Diff line change 1+ /* --------------------------------------------------------------------------
2+ * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
3+ * Copyright (C) 2012 Joris Vaillant
4+ *
5+ * CppADCodeGen is distributed under multiple licenses:
6+ *
7+ * - Eclipse Public License Version 1.0 (EPL1), and
8+ * - GNU General Public License Version 3 (GPL3).
9+ *
10+ * EPL1 terms and conditions can be found in the file "epl-v10.txt", while
11+ * terms and conditions for the GPL3 can be found in the file "gpl3.txt".
12+ * ----------------------------------------------------------------------------
13+ * Author: Joris Vaillant
14+ */
15+ #include " CppADCGTest.hpp"
16+
17+ using namespace CppAD ;
18+ using namespace CppAD ::cg;
19+
20+ // Test GCC compilation bug issue: https://github.com/joaoleal/CppADCodeGen/issues/92
21+ // This test only have to build to pass
22+
23+ struct A {};
24+ struct B {};
25+
26+ template <typename T>
27+ struct Wrapper {
28+ virtual void foo () {
29+ v.FUNC ();
30+ }
31+ CppAD::cg::CGOStreamFunc<T> v;
32+ };
33+
34+ int main () {
35+ };
36+
37+ TEST_F (CppADCGTest, TestGCCBuildIssue) {
38+ Wrapper<A> a;
39+ Wrapper<B> b;
40+ a.v .FUNC ();
41+ }
You can’t perform that action at this time.
0 commit comments