xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/src/c++11/debug.cc (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 // Debugging mode support code -*- C++ -*-
2 
3 // Copyright (C) 2003-2016 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 #include <bits/move.h>
26 #include <bits/stl_iterator_base_types.h>
27 
28 #include <debug/formatter.h>
29 #include <debug/safe_base.h>
30 #include <debug/safe_unordered_base.h>
31 #include <debug/safe_iterator.h>
32 #include <debug/safe_local_iterator.h>
33 
34 #include <cassert>
35 #include <cstdio>
36 
37 #include <algorithm> // for std::min
38 #include <functional> // for _Hash_impl
39 
40 #include <cxxabi.h> // for __cxa_demangle
41 
42 using namespace std;
43 
44 namespace
45 {
46   /** Returns different instances of __mutex depending on the passed address
47    *  in order to limit contention without breaking current library binary
48    *  compatibility. */
49   __gnu_cxx::__mutex&
50   get_safe_base_mutex(void* __address)
51   {
52     const size_t mask = 0xf;
53     static __gnu_cxx::__mutex safe_base_mutex[mask + 1];
54     const size_t index = _Hash_impl::hash(__address) & mask;
55     return safe_base_mutex[index];
56   }
57 
58   void
59   swap_its(__gnu_debug::_Safe_sequence_base& __lhs,
60 	   __gnu_debug::_Safe_iterator_base*& __lhs_its,
61 	   __gnu_debug::_Safe_sequence_base& __rhs,
62 	   __gnu_debug::_Safe_iterator_base*& __rhs_its)
63   {
64     swap(__lhs_its, __rhs_its);
65     __gnu_debug::_Safe_iterator_base* __iter;
66     for (__iter = __rhs_its; __iter; __iter = __iter->_M_next)
67       __iter->_M_sequence = &__rhs;
68     for (__iter = __lhs_its; __iter; __iter = __iter->_M_next)
69       __iter->_M_sequence = &__lhs;
70   }
71 
72   void
73   swap_seq(__gnu_debug::_Safe_sequence_base& __lhs,
74 	   __gnu_debug::_Safe_sequence_base& __rhs)
75   {
76     swap(__lhs._M_version, __rhs._M_version);
77     swap_its(__lhs, __lhs._M_iterators,
78 	     __rhs, __rhs._M_iterators);
79     swap_its(__lhs, __lhs._M_const_iterators,
80 	     __rhs, __rhs._M_const_iterators);
81   }
82 
83   void
84   swap_ucont(__gnu_debug::_Safe_unordered_container_base& __lhs,
85 	    __gnu_debug::_Safe_unordered_container_base& __rhs)
86   {
87     swap_seq(__lhs, __rhs);
88     swap_its(__lhs, __lhs._M_local_iterators,
89 	     __rhs, __rhs._M_local_iterators);
90     swap_its(__lhs, __lhs._M_const_local_iterators,
91 	     __rhs, __rhs._M_const_local_iterators);
92   }
93 
94   void
95   detach_all(__gnu_debug::_Safe_iterator_base* __iter)
96   {
97     for (; __iter;)
98       {
99 	__gnu_debug::_Safe_iterator_base* __old = __iter;
100 	__iter = __iter->_M_next;
101 	__old->_M_reset();
102       }
103   }
104 } // anonymous namespace
105 
106 namespace __gnu_debug
107 {
108   const char* const _S_debug_messages[] =
109   {
110     // General Checks
111     "function requires a valid iterator range [%1.name;, %2.name;)",
112     "attempt to insert into container with a singular iterator",
113     "attempt to insert into container with an iterator"
114     " from a different container",
115     "attempt to erase from container with a %2.state; iterator",
116     "attempt to erase from container with an iterator"
117     " from a different container",
118     "attempt to subscript container with out-of-bounds index %2;,"
119     " but container only holds %3; elements",
120     "attempt to access an element in an empty container",
121     "elements in iterator range [%1.name;, %2.name;)"
122     " are not partitioned by the value %3;",
123     "elements in iterator range [%1.name;, %2.name;)"
124     " are not partitioned by the predicate %3; and value %4;",
125     "elements in iterator range [%1.name;, %2.name;) are not sorted",
126     "elements in iterator range [%1.name;, %2.name;)"
127     " are not sorted according to the predicate %3;",
128     "elements in iterator range [%1.name;, %2.name;) do not form a heap",
129     "elements in iterator range [%1.name;, %2.name;)"
130     " do not form a heap with respect to the predicate %3;",
131     // std::bitset checks
132     "attempt to write through a singular bitset reference",
133     "attempt to read from a singular bitset reference",
134     "attempt to flip a singular bitset reference",
135     // std::list checks
136     "attempt to splice a list into itself",
137     "attempt to splice lists with unequal allocators",
138     "attempt to splice elements referenced by a %1.state; iterator",
139     "attempt to splice an iterator from a different container",
140     "splice destination %1.name;"
141     " occurs within source range [%2.name;, %3.name;)",
142     // iterator checks
143     "attempt to initialize an iterator that will immediately become singular",
144     "attempt to copy-construct an iterator from a singular iterator",
145     "attempt to construct a constant iterator"
146     " from a singular mutable iterator",
147     "attempt to copy from a singular iterator",
148     "attempt to dereference a %1.state; iterator",
149     "attempt to increment a %1.state; iterator",
150     "attempt to decrement a %1.state; iterator",
151     "attempt to subscript a %1.state; iterator %2; step from"
152     " its current position, which falls outside its dereferenceable range",
153     "attempt to advance a %1.state; iterator %2; steps,"
154     " which falls outside its valid range",
155     "attempt to retreat a %1.state; iterator %2; steps,"
156     " which falls outside its valid range",
157     "attempt to compare a %1.state; iterator to a %2.state; iterator",
158     "attempt to compare iterators from different sequences",
159     "attempt to order a %1.state; iterator to a %2.state; iterator",
160     "attempt to order iterators from different sequences",
161     "attempt to compute the difference between a %1.state;"
162     " iterator to a %2.state; iterator",
163     "attempt to compute the different between two iterators"
164     " from different sequences",
165     // istream_iterator
166     "attempt to dereference an end-of-stream istream_iterator",
167     "attempt to increment an end-of-stream istream_iterator",
168     // ostream_iterator
169     "attempt to output via an ostream_iterator with no associated stream",
170     // istreambuf_iterator
171     "attempt to dereference an end-of-stream istreambuf_iterator"
172     " (this is a GNU extension)",
173     "attempt to increment an end-of-stream istreambuf_iterator",
174     // std::forward_list
175     "attempt to insert into container after an end iterator",
176     "attempt to erase from container after a %2.state; iterator not followed"
177     " by a dereferenceable one",
178     "function requires a valid iterator range (%2.name;, %3.name;)"
179     ", \"%2.name;\" shall be before and not equal to \"%3.name;\"",
180     // std::unordered_container::local_iterator
181     "attempt to compare local iterators from different unordered container"
182     " buckets",
183     "function requires a non-empty iterator range [%1.name;, %2.name;)",
184     "attempt to self move assign",
185     "attempt to access container with out-of-bounds bucket index %2;,"
186     " container only holds %3; buckets",
187     "load factor shall be positive",
188     "allocators must be equal",
189     "attempt to insert with an iterator range [%1.name;, %2.name;) from this"
190     " container",
191     "comparison doesn't meet irreflexive requirements, assert(!(a < a))"
192   };
193 
194   void
195   _Safe_sequence_base::
196   _M_detach_all()
197   {
198     __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
199     detach_all(_M_iterators);
200     _M_iterators = 0;
201 
202     detach_all(_M_const_iterators);
203     _M_const_iterators = 0;
204   }
205 
206   void
207   _Safe_sequence_base::
208   _M_detach_singular()
209   {
210     __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
211     for (_Safe_iterator_base* __iter = _M_iterators; __iter;)
212       {
213 	_Safe_iterator_base* __old = __iter;
214 	__iter = __iter->_M_next;
215 	if (__old->_M_singular())
216 	  __old->_M_detach_single();
217       }
218 
219     for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;)
220       {
221 	_Safe_iterator_base* __old = __iter2;
222 	__iter2 = __iter2->_M_next;
223 	if (__old->_M_singular())
224 	  __old->_M_detach_single();
225       }
226   }
227 
228   void
229   _Safe_sequence_base::
230   _M_revalidate_singular()
231   {
232     __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
233     for (_Safe_iterator_base* __iter = _M_iterators; __iter;
234 	 __iter = __iter->_M_next)
235       __iter->_M_version = _M_version;
236 
237     for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;
238 	 __iter2 = __iter2->_M_next)
239       __iter2->_M_version = _M_version;
240   }
241 
242   void
243   _Safe_sequence_base::
244   _M_swap(_Safe_sequence_base& __x) noexcept
245   {
246     // We need to lock both sequences to swap
247     using namespace __gnu_cxx;
248     __mutex *__this_mutex = &_M_get_mutex();
249     __mutex *__x_mutex = &__x._M_get_mutex();
250     if (__this_mutex == __x_mutex)
251       {
252 	__scoped_lock __lock(*__this_mutex);
253 	swap_seq(*this, __x);
254       }
255     else
256       {
257 	__scoped_lock __l1(__this_mutex < __x_mutex
258 			     ? *__this_mutex : *__x_mutex);
259 	__scoped_lock __l2(__this_mutex < __x_mutex
260 			     ? *__x_mutex : *__this_mutex);
261 	swap_seq(*this, __x);
262       }
263   }
264 
265   __gnu_cxx::__mutex&
266   _Safe_sequence_base::
267   _M_get_mutex() throw ()
268   { return get_safe_base_mutex(this); }
269 
270   void
271   _Safe_sequence_base::
272   _M_attach(_Safe_iterator_base* __it, bool __constant)
273   {
274     __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
275     _M_attach_single(__it, __constant);
276   }
277 
278   void
279   _Safe_sequence_base::
280   _M_attach_single(_Safe_iterator_base* __it, bool __constant) throw ()
281   {
282     _Safe_iterator_base*& __its =
283       __constant ? _M_const_iterators : _M_iterators;
284     __it->_M_next = __its;
285     if (__it->_M_next)
286       __it->_M_next->_M_prior = __it;
287     __its = __it;
288   }
289 
290   void
291   _Safe_sequence_base::
292   _M_detach(_Safe_iterator_base* __it)
293   {
294     // Remove __it from this sequence's list
295     __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
296     _M_detach_single(__it);
297   }
298 
299   void
300   _Safe_sequence_base::
301   _M_detach_single(_Safe_iterator_base* __it) throw ()
302   {
303     // Remove __it from this sequence's list
304     __it->_M_unlink();
305     if (_M_const_iterators == __it)
306       _M_const_iterators = __it->_M_next;
307     if (_M_iterators == __it)
308       _M_iterators = __it->_M_next;
309   }
310 
311   void
312   _Safe_iterator_base::
313   _M_attach(_Safe_sequence_base* __seq, bool __constant)
314   {
315     _M_detach();
316 
317     // Attach to the new sequence (if there is one)
318     if (__seq)
319       {
320 	_M_sequence = __seq;
321 	_M_version = _M_sequence->_M_version;
322 	_M_sequence->_M_attach(this, __constant);
323       }
324   }
325 
326   void
327   _Safe_iterator_base::
328   _M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw ()
329   {
330     _M_detach_single();
331 
332     // Attach to the new sequence (if there is one)
333     if (__seq)
334       {
335 	_M_sequence = __seq;
336 	_M_version = _M_sequence->_M_version;
337 	_M_sequence->_M_attach_single(this, __constant);
338       }
339   }
340 
341   void
342   _Safe_iterator_base::
343   _M_detach()
344   {
345     if (_M_sequence)
346       _M_sequence->_M_detach(this);
347 
348     _M_reset();
349   }
350 
351   void
352   _Safe_iterator_base::
353   _M_detach_single() throw ()
354   {
355     if (_M_sequence)
356       _M_sequence->_M_detach_single(this);
357 
358     _M_reset();
359   }
360 
361   void
362   _Safe_iterator_base::
363   _M_reset() throw ()
364   {
365     _M_sequence = 0;
366     _M_version = 0;
367     _M_prior = 0;
368     _M_next = 0;
369   }
370 
371   bool
372   _Safe_iterator_base::
373   _M_singular() const throw ()
374   { return !_M_sequence || _M_version != _M_sequence->_M_version; }
375 
376   bool
377   _Safe_iterator_base::
378   _M_can_compare(const _Safe_iterator_base& __x) const throw ()
379   {
380     return (!_M_singular()
381 	    && !__x._M_singular() && _M_sequence == __x._M_sequence);
382   }
383 
384   __gnu_cxx::__mutex&
385   _Safe_iterator_base::
386   _M_get_mutex() throw ()
387   { return get_safe_base_mutex(_M_sequence); }
388 
389   _Safe_unordered_container_base*
390   _Safe_local_iterator_base::
391   _M_get_container() const noexcept
392   { return static_cast<_Safe_unordered_container_base*>(_M_sequence); }
393 
394   void
395   _Safe_local_iterator_base::
396   _M_attach(_Safe_sequence_base* __cont, bool __constant)
397   {
398     _M_detach();
399 
400     // Attach to the new container (if there is one)
401     if (__cont)
402       {
403 	_M_sequence = __cont;
404 	_M_version = _M_sequence->_M_version;
405 	_M_get_container()->_M_attach_local(this, __constant);
406       }
407   }
408 
409   void
410   _Safe_local_iterator_base::
411   _M_attach_single(_Safe_sequence_base* __cont, bool __constant) throw ()
412   {
413     _M_detach_single();
414 
415     // Attach to the new container (if there is one)
416     if (__cont)
417       {
418 	_M_sequence = __cont;
419 	_M_version = _M_sequence->_M_version;
420 	_M_get_container()->_M_attach_local_single(this, __constant);
421       }
422   }
423 
424   void
425   _Safe_local_iterator_base::
426   _M_detach()
427   {
428     if (_M_sequence)
429       _M_get_container()->_M_detach_local(this);
430 
431     _M_reset();
432   }
433 
434   void
435   _Safe_local_iterator_base::
436   _M_detach_single() throw ()
437   {
438     if (_M_sequence)
439       _M_get_container()->_M_detach_local_single(this);
440 
441     _M_reset();
442   }
443 
444   void
445   _Safe_unordered_container_base::
446   _M_detach_all()
447   {
448     __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
449     detach_all(_M_iterators);
450     _M_iterators = 0;
451 
452     detach_all(_M_const_iterators);
453     _M_const_iterators = 0;
454 
455     detach_all(_M_local_iterators);
456     _M_local_iterators = 0;
457 
458     detach_all(_M_const_local_iterators);
459     _M_const_local_iterators = 0;
460   }
461 
462   void
463   _Safe_unordered_container_base::
464   _M_swap(_Safe_unordered_container_base& __x) noexcept
465   {
466     // We need to lock both containers to swap
467     using namespace __gnu_cxx;
468     __mutex *__this_mutex = &_M_get_mutex();
469     __mutex *__x_mutex = &__x._M_get_mutex();
470     if (__this_mutex == __x_mutex)
471       {
472 	__scoped_lock __lock(*__this_mutex);
473 	swap_ucont(*this, __x);
474       }
475     else
476       {
477 	__scoped_lock __l1(__this_mutex < __x_mutex
478 			     ? *__this_mutex : *__x_mutex);
479 	__scoped_lock __l2(__this_mutex < __x_mutex
480 			     ? *__x_mutex : *__this_mutex);
481 	swap_ucont(*this, __x);
482       }
483   }
484 
485   void
486   _Safe_unordered_container_base::
487   _M_attach_local(_Safe_iterator_base* __it, bool __constant)
488   {
489     __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
490     _M_attach_local_single(__it, __constant);
491   }
492 
493   void
494   _Safe_unordered_container_base::
495   _M_attach_local_single(_Safe_iterator_base* __it, bool __constant) throw ()
496   {
497     _Safe_iterator_base*& __its =
498       __constant ? _M_const_local_iterators : _M_local_iterators;
499     __it->_M_next = __its;
500     if (__it->_M_next)
501       __it->_M_next->_M_prior = __it;
502     __its = __it;
503   }
504 
505   void
506   _Safe_unordered_container_base::
507   _M_detach_local(_Safe_iterator_base* __it)
508   {
509     // Remove __it from this container's list
510     __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
511     _M_detach_local_single(__it);
512   }
513 
514   void
515   _Safe_unordered_container_base::
516   _M_detach_local_single(_Safe_iterator_base* __it) throw ()
517   {
518     // Remove __it from this container's list
519     __it->_M_unlink();
520     if (_M_const_local_iterators == __it)
521       _M_const_local_iterators = __it->_M_next;
522     if (_M_local_iterators == __it)
523       _M_local_iterators = __it->_M_next;
524   }
525 }
526 
527 namespace
528 {
529   using _Error_formatter = __gnu_debug::_Error_formatter;
530   using _Parameter = __gnu_debug::_Error_formatter::_Parameter;
531 
532   void
533   get_max_length(std::size_t& max_length)
534   {
535     const char* nptr = std::getenv("GLIBCXX_DEBUG_MESSAGE_LENGTH");
536     if (nptr)
537       {
538 	char* endptr;
539 	const unsigned long ret = std::strtoul(nptr, &endptr, 0);
540 	if (*nptr != '\0' && *endptr == '\0')
541 	  max_length = ret;
542       }
543   }
544 
545   struct PrintContext
546   {
547     PrintContext()
548       : _M_max_length(78), _M_column(1), _M_first_line(true), _M_wordwrap(false)
549     { get_max_length(_M_max_length); }
550 
551     std::size_t	_M_max_length;
552     enum { _M_indent = 4 } ;
553     std::size_t	_M_column;
554     bool	_M_first_line;
555     bool	_M_wordwrap;
556   };
557 
558   template<size_t Length>
559     void
560     print_literal(PrintContext& ctx, const char(&word)[Length])
561     { print_word(ctx, word, Length - 1); }
562 
563   void
564   print_word(PrintContext& ctx, const char* word,
565 	     std::ptrdiff_t count = -1)
566   {
567     size_t length = count >= 0 ? count : __builtin_strlen(word);
568     if (length == 0)
569       return;
570 
571     // Consider first '\n' at begining cause it impacts column.
572     if (word[0] == '\n')
573       {
574 	fprintf(stderr, "\n");
575 	ctx._M_column = 1;
576 	++word;
577 	--length;
578 
579 	if (length == 0)
580 	  return;
581       }
582 
583     size_t visual_length
584       = isspace(word[length - 1]) ? length - 1 : length;
585     if (visual_length == 0
586 	|| !ctx._M_wordwrap
587 	|| (ctx._M_column + visual_length < ctx._M_max_length)
588 	|| (visual_length >= ctx._M_max_length && ctx._M_column == 1))
589       {
590 	// If this isn't the first line, indent
591 	if (ctx._M_column == 1 && !ctx._M_first_line)
592 	  {
593 	    char spacing[ctx._M_indent + 1];
594 	    for (int i = 0; i < ctx._M_indent; ++i)
595 	      spacing[i] = ' ';
596 	    spacing[ctx._M_indent] = '\0';
597 	    fprintf(stderr, "%s", spacing);
598 	    ctx._M_column += ctx._M_indent;
599 	  }
600 
601 	int written = fprintf(stderr, "%s", word);
602 
603 	if (word[length - 1] == '\n')
604 	  {
605 	    ctx._M_first_line = false;
606 	    ctx._M_column = 1;
607 	  }
608 	else
609 	  ctx._M_column += written;
610       }
611     else
612       {
613 	print_literal(ctx, "\n");
614 	print_word(ctx, word, count);
615       }
616   }
617 
618   template<size_t Length>
619     void
620     print_type(PrintContext& ctx,
621 	       const type_info* info,
622 	       const char(&unknown_name)[Length])
623     {
624       if (!info)
625 	print_literal(ctx, unknown_name);
626       else
627 	{
628 	  int status;
629 	  char* demangled_name =
630 	    __cxxabiv1::__cxa_demangle(info->name(), NULL, NULL, &status);
631 	  print_word(ctx, status == 0 ? demangled_name : info->name());
632 	  free(demangled_name);
633 	}
634     }
635 
636   bool
637   print_field(PrintContext& ctx,
638 	      const char* name, const _Parameter::_Type& type)
639   {
640     if (__builtin_strcmp(name, "name") == 0)
641       {
642 	assert(type._M_name);
643 	print_word(ctx, type._M_name);
644       }
645     else if (__builtin_strcmp(name, "type") == 0)
646       print_type(ctx, type._M_type, "<unknown type>");
647     else
648       return false;
649 
650     return true;
651   }
652 
653   bool
654   print_field(PrintContext& ctx,
655 	      const char* name, const _Parameter::_Instance& inst)
656   {
657     const _Parameter::_Type& type = inst;
658     if (print_field(ctx, name, type))
659       { }
660     else if (__builtin_strcmp(name, "address") == 0)
661       {
662 	char buf[64];
663 	int ret = __builtin_sprintf(buf, "%p", inst._M_address);
664 	print_word(ctx, buf, ret);
665       }
666     else
667       return false;
668 
669     return true;
670   }
671 
672   void
673   print_field(PrintContext& ctx, const _Parameter& param, const char* name)
674   {
675     assert(param._M_kind != _Parameter::__unused_param);
676     const int bufsize = 64;
677     char buf[bufsize];
678 
679     const auto& variant = param._M_variant;
680     switch (param._M_kind)
681     {
682     case _Parameter::__iterator:
683       {
684 	const auto& iterator = variant._M_iterator;
685 	if (print_field(ctx, name, iterator))
686 	  { }
687 	else if (__builtin_strcmp(name, "constness") == 0)
688 	  {
689 	    static const char*
690 	      constness_names[_Error_formatter::__last_constness] =
691 	      {
692 		"<unknown>",
693 		"constant",
694 		"mutable"
695 	      };
696 	    print_word(ctx, constness_names[iterator._M_constness]);
697 	  }
698 	else if (__builtin_strcmp(name, "state") == 0)
699 	  {
700 	    static const char*
701 	      state_names[_Error_formatter::__last_state] =
702 	      {
703 		"<unknown>",
704 		"singular",
705 		"dereferenceable (start-of-sequence)",
706 		"dereferenceable",
707 		"past-the-end",
708 		"before-begin"
709 	      };
710 	    print_word(ctx, state_names[iterator._M_state]);
711 	  }
712 	else if (__builtin_strcmp(name, "sequence") == 0)
713 	  {
714 	    assert(iterator._M_sequence);
715 	    int written = __builtin_sprintf(buf, "%p", iterator._M_sequence);
716 	    print_word(ctx, buf, written);
717 	  }
718 	else if (__builtin_strcmp(name, "seq_type") == 0)
719 	  print_type(ctx, iterator._M_seq_type, "<unknown seq_type>");
720 	else
721 	  assert(false);
722       }
723       break;
724 
725     case _Parameter::__sequence:
726       if (!print_field(ctx, name, variant._M_sequence))
727 	assert(false);
728       break;
729 
730     case _Parameter::__integer:
731       if (__builtin_strcmp(name, "name") == 0)
732 	{
733 	  assert(variant._M_integer._M_name);
734 	  print_word(ctx, variant._M_integer._M_name);
735 	}
736       else
737 	assert(false);
738       break;
739 
740     case _Parameter::__string:
741       if (__builtin_strcmp(name, "name") == 0)
742 	{
743 	  assert(variant._M_string._M_name);
744 	  print_word(ctx, variant._M_string._M_name);
745 	}
746       else
747 	assert(false);
748       break;
749 
750     case _Parameter::__instance:
751       if (!print_field(ctx, name, variant._M_instance))
752 	assert(false);
753       break;
754 
755     case _Parameter::__iterator_value_type:
756       if (!print_field(ctx, name, variant._M_iterator_value_type))
757 	assert(false);
758       break;
759 
760     default:
761       assert(false);
762       break;
763     }
764   }
765 
766   void
767   print_description(PrintContext& ctx, const _Parameter::_Type& type)
768   {
769     if (type._M_name)
770       {
771 	print_literal(ctx, "\"");
772 	print_word(ctx, type._M_name);
773 	print_literal(ctx, "\"");
774       }
775 
776     print_literal(ctx, " {\n");
777 
778     if (type._M_type)
779       {
780 	print_literal(ctx, "  type = ");
781 	print_type(ctx, type._M_type, "<unknown type>");
782 	print_literal(ctx, ";\n");
783       }
784   }
785 
786   void
787   print_description(PrintContext& ctx, const _Parameter::_Instance& inst)
788   {
789     const int bufsize = 64;
790     char buf[bufsize];
791 
792     if (inst._M_name)
793       {
794 	print_literal(ctx, "\"");
795 	print_word(ctx, inst._M_name);
796 	print_literal(ctx, "\" ");
797       }
798 
799     int written
800       = __builtin_sprintf(buf, "@ 0x%p {\n", inst._M_address);
801     print_word(ctx, buf, written);
802 
803     if (inst._M_type)
804       {
805 	print_literal(ctx, "  type = ");
806 	print_type(ctx, inst._M_type, "<unknown type>");
807       }
808   }
809 
810   void
811   print_description(PrintContext& ctx, const _Parameter& param)
812   {
813     const int bufsize = 128;
814     char buf[bufsize];
815 
816     const auto& variant = param._M_variant;
817     switch (param._M_kind)
818       {
819       case _Parameter::__iterator:
820 	{
821 	  const auto& ite = variant._M_iterator;
822 
823 	  print_literal(ctx, "iterator ");
824 	  print_description(ctx, ite);
825 
826 	  if (ite._M_type)
827 	    {
828 	      if (ite._M_constness != _Error_formatter::__unknown_constness)
829 		{
830 		  print_literal(ctx, " (");
831 		  print_field(ctx, param, "constness");
832 		  print_literal(ctx, " iterator)");
833 		}
834 
835 	      print_literal(ctx, ";\n");
836 	    }
837 
838 	  if (ite._M_state != _Error_formatter::__unknown_state)
839 	    {
840 	      print_literal(ctx, "  state = ");
841 	      print_field(ctx, param, "state");
842 	      print_literal(ctx, ";\n");
843 	    }
844 
845 	  if (ite._M_sequence)
846 	    {
847 	      print_literal(ctx, "  references sequence ");
848 	      if (ite._M_seq_type)
849 		{
850 		  print_literal(ctx, "with type '");
851 		  print_field(ctx, param, "seq_type");
852 		  print_literal(ctx, "' ");
853 		}
854 
855 	      int written
856 		= __builtin_sprintf(buf, "@ 0x%p\n", ite._M_sequence);
857 	      print_word(ctx, buf, written);
858 	    }
859 
860 	  print_literal(ctx, "}\n");
861 	}
862 	break;
863 
864       case _Parameter::__sequence:
865 	print_literal(ctx, "sequence ");
866 	print_description(ctx, variant._M_sequence);
867 
868 	if (variant._M_sequence._M_type)
869 	  print_literal(ctx, ";\n");
870 
871 	print_literal(ctx, "}\n");
872 	break;
873 
874       case _Parameter::__instance:
875 	print_literal(ctx, "instance ");
876 	print_description(ctx, variant._M_instance);
877 
878 	if (variant._M_instance._M_type)
879 	  print_literal(ctx, ";\n");
880 
881 	print_literal(ctx, "}\n");
882 	break;
883 
884       case _Parameter::__iterator_value_type:
885 	print_literal(ctx, "iterator::value_type ");
886 	print_description(ctx, variant._M_iterator_value_type);
887 	print_literal(ctx, "}\n");
888 	break;
889 
890       default:
891 	break;
892       }
893   }
894 
895   void
896   print_string(PrintContext& ctx, const char* string,
897 	       const _Parameter* parameters, std::size_t num_parameters)
898   {
899     const char* start = string;
900     const int bufsize = 128;
901     char buf[bufsize];
902     int bufindex = 0;
903 
904     while (*start)
905       {
906 	if (isspace(*start))
907 	  {
908 	    buf[bufindex++] = *start++;
909 	    buf[bufindex] = '\0';
910 	    print_word(ctx, buf, bufindex);
911 	    bufindex = 0;
912 	    continue;
913 	  }
914 
915 	if (*start != '%')
916 	  {
917 	    // Normal char.
918 	    buf[bufindex++] = *start++;
919 	    continue;
920 	  }
921 
922 	if (*++start == '%')
923 	  {
924 	    // Escaped '%'
925 	    buf[bufindex++] = *start++;
926 	    continue;
927 	  }
928 
929 	// We are on a parameter property reference, we need to flush buffer
930 	// first.
931 	if (bufindex != 0)
932 	  {
933 	    buf[bufindex] = '\0';
934 	    print_word(ctx, buf, bufindex);
935 	    bufindex = 0;
936 	  }
937 
938 	// Get the parameter number
939 	assert(*start >= '1' && *start <= '9');
940 	size_t param_index = *start - '0' - 1;
941 	assert(param_index < num_parameters);
942 	const auto& param = parameters[param_index];
943 
944 	// '.' separates the parameter number from the field
945 	// name, if there is one.
946 	++start;
947 	if (*start != '.')
948 	  {
949 	    assert(*start == ';');
950 	    ++start;
951 	    if (param._M_kind == _Parameter::__integer)
952 	      {
953 		int written
954 		  = __builtin_sprintf(buf, "%ld",
955 				      param._M_variant._M_integer._M_value);
956 		print_word(ctx, buf, written);
957 	      }
958 	    else if (param._M_kind == _Parameter::__string)
959 	      print_string(ctx, param._M_variant._M_string._M_value,
960 			   parameters, num_parameters);
961 	    continue;
962 	  }
963 
964 	// Extract the field name we want
965 	const int max_field_len = 16;
966 	char field[max_field_len];
967 	int field_idx = 0;
968 	++start;
969 	while (*start != ';')
970 	  {
971 	    assert(*start);
972 	    assert(field_idx < max_field_len - 1);
973 	    field[field_idx++] = *start++;
974 	  }
975 	++start;
976 	field[field_idx] = '\0';
977 
978 	print_field(ctx, param, field);
979       }
980 
981     // Might need to flush.
982     if (bufindex)
983       {
984 	buf[bufindex] = '\0';
985 	print_word(ctx, buf, bufindex);
986       }
987   }
988 }
989 
990 namespace __gnu_debug
991 {
992   _Error_formatter&
993   _Error_formatter::_M_message(_Debug_msg_id __id) const throw ()
994   {
995     return const_cast<_Error_formatter*>(this)
996       ->_M_message(_S_debug_messages[__id]);
997   }
998 
999   void
1000   _Error_formatter::_M_error() const
1001   {
1002     // Emit file & line number information
1003     bool go_to_next_line = false;
1004     PrintContext ctx;
1005     if (_M_file)
1006       {
1007 	print_word(ctx, _M_file);
1008 	print_literal(ctx, ":");
1009 	go_to_next_line = true;
1010       }
1011 
1012     if (_M_line > 0)
1013       {
1014 	char buf[64];
1015 	int written = __builtin_sprintf(buf, "%u:", _M_line);
1016 	print_word(ctx, buf, written);
1017 	go_to_next_line = true;
1018       }
1019 
1020     if (go_to_next_line)
1021       print_literal(ctx, "\n");
1022 
1023     if (ctx._M_max_length)
1024       ctx._M_wordwrap = true;
1025 
1026     print_literal(ctx, "Error: ");
1027 
1028     // Print the error message
1029     assert(_M_text);
1030     print_string(ctx, _M_text, _M_parameters, _M_num_parameters);
1031     print_literal(ctx, ".\n");
1032 
1033     // Emit descriptions of the objects involved in the operation
1034     ctx._M_first_line = true;
1035     ctx._M_wordwrap = false;
1036     bool has_header = false;
1037     for (unsigned int i = 0; i < _M_num_parameters; ++i)
1038       {
1039 	switch (_M_parameters[i]._M_kind)
1040 	  {
1041 	  case _Parameter::__iterator:
1042 	  case _Parameter::__sequence:
1043 	  case _Parameter::__instance:
1044 	  case _Parameter::__iterator_value_type:
1045 	    if (!has_header)
1046 	      {
1047 		print_literal(ctx, "\nObjects involved in the operation:\n");
1048 		has_header = true;
1049 	      }
1050 	    print_description(ctx, _M_parameters[i]);
1051 	    break;
1052 
1053 	  default:
1054 	    break;
1055 	  }
1056       }
1057 
1058     abort();
1059   }
1060 
1061   // Deprecated methods kept for backward compatibility.
1062   void
1063   _Error_formatter::_Parameter::_M_print_field(
1064 	const _Error_formatter*, const char*) const
1065   { }
1066 
1067   void
1068   _Error_formatter::_Parameter::_M_print_description(const _Error_formatter*) const
1069   { }
1070 
1071   template<typename _Tp>
1072     void
1073     _Error_formatter::_M_format_word(char*, int, const char*, _Tp)
1074     const throw ()
1075     { }
1076 
1077   void
1078   _Error_formatter::_M_print_word(const char*) const
1079   { }
1080 
1081   void
1082   _Error_formatter::_M_print_string(const char*) const
1083   { }
1084 
1085   void
1086   _Error_formatter::_M_get_max_length() const throw ()
1087   { }
1088 
1089   // Instantiations.
1090   template
1091     void
1092     _Error_formatter::_M_format_word(char*, int, const char*,
1093                                     const void*) const;
1094 
1095   template
1096     void
1097     _Error_formatter::_M_format_word(char*, int, const char*, long) const;
1098 
1099   template
1100     void
1101     _Error_formatter::_M_format_word(char*, int, const char*,
1102                                     std::size_t) const;
1103 
1104   template
1105     void
1106     _Error_formatter::_M_format_word(char*, int, const char*,
1107                                     const char*) const;
1108 } // namespace __gnu_debug
1109