This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Enhance __gnu_debug::string debug assertion


    This patch improves the assertion message generated in 2 __gnu_debug::string constructors giving the assertion context thanks to the __FUNCTION__ macro.

Was:

/home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/debug/string:56: const _CharT* __gnu_debug::__check_string(const _CharT*, _Integer, const char*, unsigned int, const char*) [with _CharT = char; _Integer = long unsigned int]: Assertion '__s != 0 || __n == 0' failed.
XFAIL: 21_strings/basic_string/debug/1_neg.cc execution test

Now:

/home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/debug/string:172:
In function:
    __gnu_debug::basic_string<_CharT, _Traits,
    _Allocator>::basic_string(const _CharT*,
    __gnu_debug::basic_string<_CharT, _Traits, _Allocator>::size_type, const
    _Allocator&) [with _CharT = char; _Traits = std::char_traits<char>;
    _Allocator = std::allocator<char>; __gnu_debug::basic_string<_CharT,
    _Traits, _Allocator>::size_type = long unsigned int]

Error: __s != 0 || __n == 0.
XFAIL: 21_strings/basic_string/debug/1_neg.cc execution test

    Tested under Linux x86_64 normal and debug modes.

    If not told otherwise I plan to commit the attached patch tomorrow.

François

diff --git a/libstdc++-v3/include/debug/functions.h b/libstdc++-v3/include/debug/functions.h
index 5c16a45..97b1f94 100644
--- a/libstdc++-v3/include/debug/functions.h
+++ b/libstdc++-v3/include/debug/functions.h
@@ -239,29 +239,6 @@ namespace __gnu_debug
       return __foreign_iterator_aux(__it, __other, __other_end, _Integral());
     }
 
-  /** Checks that __s is non-NULL or __n == 0, and then returns __s. */
-  template<typename _CharT, typename _Integer>
-    inline const _CharT*
-    __check_string(const _CharT* __s,
-		   const _Integer& __n __attribute__((__unused__)))
-    {
-#ifdef _GLIBCXX_DEBUG_PEDANTIC
-      __glibcxx_assert(__s != 0 || __n == 0);
-#endif
-      return __s;
-    }
-
-  /** Checks that __s is non-NULL and then returns __s. */
-  template<typename _CharT>
-    inline const _CharT*
-    __check_string(const _CharT* __s)
-    {
-#ifdef _GLIBCXX_DEBUG_PEDANTIC
-      __glibcxx_assert(__s != 0);
-#endif
-      return __s;
-    }
-
   // Can't check if an input iterator sequence is sorted, because we
   // can't step through the sequence.
   template<typename _InputIterator>
diff --git a/libstdc++-v3/include/debug/string b/libstdc++-v3/include/debug/string
index 963b84f..9568f8b 100644
--- a/libstdc++-v3/include/debug/string
+++ b/libstdc++-v3/include/debug/string
@@ -36,8 +36,50 @@
 #include <debug/safe_container.h>
 #include <debug/safe_iterator.h>
 
+#define _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_Cond,_File,_Line,_Func)	\
+  if (! (_Cond))							\
+    __gnu_debug::_Error_formatter::_S_at(_File, _Line, _Func)		\
+      ._M_message(#_Cond)._M_error()
+
 namespace __gnu_debug
 {
+  /** Checks that __s is non-NULL or __n == 0, and then returns __s. */
+  template<typename _CharT, typename _Integer>
+    inline const _CharT*
+    __check_string(const _CharT* __s,
+		   _Integer __n __attribute__((__unused__)),
+		   const char* __file __attribute__((__unused__)),
+		   unsigned int __line __attribute__((__unused__)),
+		   const char* __function __attribute__((__unused__)))
+    {
+#ifdef _GLIBCXX_DEBUG_PEDANTIC
+      _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(__s != 0 || __n == 0,
+					__file, __line, __function);
+#endif
+      return __s;
+    }
+
+  /** Checks that __s is non-NULL and then returns __s. */
+  template<typename _CharT>
+    inline const _CharT*
+    __check_string(const _CharT* __s,
+		   const char* __file __attribute__((__unused__)),
+		   unsigned int __line __attribute__((__unused__)),
+		   const char* __function __attribute__((__unused__)))
+    {
+#ifdef _GLIBCXX_DEBUG_PEDANTIC
+      _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(__s != 0,
+					__file, __line, __function);
+#endif
+      return __s;
+    }
+
+#define __glibcxx_check_string_n_constructor(_Str, _Size) \
+  __check_string(_Str, _Size, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define __glibcxx_check_string_constructor(_Str) \
+  __check_string(_Str, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
   /// Class std::basic_string with safety/checking/debug instrumentation.
   template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
 	   typename _Allocator = std::allocator<_CharT> >
@@ -127,10 +169,10 @@ template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
 
       basic_string(const _CharT* __s, size_type __n,
 		   const _Allocator& __a = _Allocator())
-    : _Base(__gnu_debug::__check_string(__s, __n), __n, __a) { }
+      : _Base(__glibcxx_check_string_n_constructor(__s, __n), __n, __a) { }
 
       basic_string(const _CharT* __s, const _Allocator& __a = _Allocator())
-    : _Base(__gnu_debug::__check_string(__s), __a)
+      : _Base(__glibcxx_check_string_constructor(__s), __a)
       { this->assign(__s); }
 
       basic_string(size_type __n, _CharT __c,
@@ -565,7 +607,8 @@ template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
 
       template<typename _InputIterator>
 	iterator
-      insert(const_iterator __p, _InputIterator __first, _InputIterator __last)
+	insert(const_iterator __p,
+	       _InputIterator __first, _InputIterator __last)
 	{
 	  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
 	  __glibcxx_check_insert_range(__p, __first, __last, __dist);
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/debug/1_neg.cc b/libstdc++-v3/testsuite/21_strings/basic_string/debug/1_neg.cc
new file mode 100644
index 0000000..5d035d0
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/debug/1_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2010-2018 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-do run { xfail *-*-* } }
+
+#define _GLIBCXX_DEBUG_PEDANTIC
+
+#include <debug/string>
+
+void test01()
+{
+  const char* __null_str = 0;
+  __gnu_debug::string str(__null_str, 1);
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/debug/2_neg.cc b/libstdc++-v3/testsuite/21_strings/basic_string/debug/2_neg.cc
new file mode 100644
index 0000000..29caa3d
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/debug/2_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2010-2018 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-do run { xfail *-*-* } }
+
+#define _GLIBCXX_DEBUG_PEDANTIC
+
+#include <debug/string>
+
+void test01()
+{
+  const char* __null_str = 0;
+  __gnu_debug::string str(__null_str);
+}
+
+int main()
+{
+  test01();
+  return 0;
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]