public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] libstdc++: fix pointer type exception catch [PR105387]
@ 2022-05-03 10:56 Jakob Hasse
  2022-05-04 11:14 ` Jonathan Wakely
  0 siblings, 1 reply; 7+ messages in thread
From: Jakob Hasse @ 2022-05-03 10:56 UTC (permalink / raw)
  To: libstdc++; +Cc: Ivan Grokhotkov, Rocha Euripedes

[-- Attachment #1: Type: text/plain, Size: 2671 bytes --]

This is a patch for the bug 105387 reported in bugzilla: 105387 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105387. This report should contain all the necessary information about the issue. But the patch there was just a preliminary one.
I created a proper patch with the fix and a test case, based on TAG releases/gcc-11.2.0 (7ca388565af176bd4efd4f8db1e5e9e11e98ef45). The changelog is part of the commit message in the patch.

# TESTS
First, I tested only the test case with and without the actual fix, gcc configuration:  ../configure -prefix=/usr --enable-languages=c,c++ --enable-multiarch --host=x86_64-linux-gnu --build=x86_64-linux-gnu --target=x86_64-linux-gnu --enable-cxx-flags=-fno-rtti
		=== libstdc++ Summary ===

# of expected passes		1
# of unexpected failures	1

With the fix:
		=== libstdc++ Summary ===

# of expected passes		2

Then, I tested without RTTI. The gcc configuration was: ../configure -prefix=/usr --enable-languages=c,c++ --enable-multiarch --host=x86_64-linux-gnu --build=x86_64-linux-gnu --target=x86_64-linux-gnu --enable-cxx-flags=-fno-rtti
Without the patch:
		=== libstdc++ Summary ===

# of expected passes		14006
# of unexpected failures	114
# of expected failures		104
# of unresolved testcases	84
# of unsupported tests		663

With the patch:
		=== libstdc++ Summary ===

# of expected passes		14007
# of unexpected failures	113
# of expected failures		104
# of unresolved testcases	84
# of unsupported tests		664

Number of unexpected failures went down by one and the number of unsupported tests went  up by one. 17_intro/headers/c++1998/49745.cc suddenly passes, 22_locale/time_get/get_date/wchar_t/4.cc is suddenly unsupported. I don't know why.

I also tested the entire libstdc++ test suite with RTTI enabled, i.e.: ../configure -prefix=/usr --enable-languages=c,c++ --enable-multiarch --host=x86_64-linux-gnu --build=x86_64-linux-gnu --target=x86_64-linux-gnu --enable-cxx-flags=-frtti

Without patch:
		=== libstdc++ Summary ===

# of expected passes		14201
# of unexpected failures	3
# of expected failures		104
# of unsupported tests		663

With patch:
		=== libstdc++ Summary ===

# of expected passes		14202
# of unexpected failures	2
# of expected failures		104
# of unsupported tests		664

Same symptoms as when running the entire libstdc++ test suite without RTTI.
I'm not sure why the tests behave different, they seem unrelated.

I would be happy to receive feedback, in particular if parts have to be improved or additional information is necessary. I'm completely new to gcc, I'd appreciate concrete recommendations what to do.

Thanks,
Jakob Hasse

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-libstdc-v3-Check-for-ptr-in-__pbase_type_info-__do_c.patch --]
[-- Type: text/x-patch; name="0001-libstdc-v3-Check-for-ptr-in-__pbase_type_info-__do_c.patch", Size: 4386 bytes --]

From c258b231c0737ac02ddba88ab0e54a96ab9c04b4 Mon Sep 17 00:00:00 2001
From: Jakob Hasse <0xjakob@users.noreply.github.com>
Date: Tue, 26 Apr 2022 12:03:47 +0800
Subject: [PATCH] libstdc++-v3: Check for ptr in
 __pbase_type_info::__do_catch() [105387]

PR libstdc++/105387

__pbase_type_info::__do_catch(), used to catch pointer type exceptions,
did not check if the type info object to compare against is a pointer
type info object before doing a static down-cast to a pointer type info
object. Since a pointer type info object has additional fields, they would
end up being undefined if the actual type info object was not a pointer
type info object.

A simple check has been added before the down-cast happens.

In case RTTI is enabled, this does not seem to be a problem because
RTTI-based checks would run before and prevent running into the bad
down-cast. However, since the check is very simple and I'm not 100% sure
about the RTTI-case, it has been left for both cases (RTTI and no-RTTI).

libstdc++-v3/ChangeLog:

	* libsupc++/pbase_type_info.cc (__do_catch):
	* testsuite/18_support/105387.cc: New test.
---
 libstdc++-v3/libsupc++/pbase_type_info.cc   |  5 ++-
 libstdc++-v3/testsuite/18_support/105387.cc | 46 +++++++++++++++++++++
 2 files changed, 50 insertions(+), 1 deletion(-)
 create mode 100644 libstdc++-v3/testsuite/18_support/105387.cc

diff --git a/libstdc++-v3/libsupc++/pbase_type_info.cc b/libstdc++-v3/libsupc++/pbase_type_info.cc
index ed1ad3da98a..d06dc11e460 100644
--- a/libstdc++-v3/libsupc++/pbase_type_info.cc
+++ b/libstdc++-v3/libsupc++/pbase_type_info.cc
@@ -74,7 +74,10 @@ __do_catch (const type_info *thr_type,
     // Therefore there must at least be a qualification conversion involved
     // But for that to be valid, our outer pointers must be const qualified.
     return false;
-  
+
+  if (!thr_type->__is_pointer_p ())
+    return false;
+
   const __pbase_type_info *thrown_type =
     static_cast <const __pbase_type_info *> (thr_type);
 
diff --git a/libstdc++-v3/testsuite/18_support/105387.cc b/libstdc++-v3/testsuite/18_support/105387.cc
new file mode 100644
index 00000000000..b099814847c
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/105387.cc
@@ -0,0 +1,46 @@
+// Copyright (C) 2022 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/>.
+
+#include <stdexcept>
+#include <cxxabi.h>
+#include <testsuite_hooks.h>
+
+// This test case checks that __pbase_type_info::__do_catch() behaves 
+// correctly when called with a non-pointer type info object as argument.
+// In particular, __pbase_type_info::__do_catch() should not cast
+// the given type object into a pointer type and try to access the
+// extended fields.
+int main(int argc, char **argv) 
+{
+  // Create a zero-initialized buffer for allocation of the type object
+  uint8_t buffer [sizeof(__cxxabiv1::__fundamental_type_info) * 2] = {};
+
+  // Use placement-new to create the fundamental type info object in the
+  // first half of the buffer. Whenever that type info object will be
+  // casted to a pointer type info object, the extended fields of the
+  // pointer type info object will be in the second half of the buffer
+  // and hence be guaranteed zero.
+  __cxxabiv1::__fundamental_type_info *p_fund_info = 
+            new(buffer) __cxxabiv1::__fundamental_type_info("fund_type");
+
+  __cxxabiv1::__pointer_type_info ptr_info("ptr_type", 0, p_fund_info);
+
+  // __do_catch is declared protected in __pointer_type_info, but public in
+  // type_info, so we upcast it here
+  std::type_info *abstract_ptr_info = static_cast<std::type_info*>(&ptr_info);
+  VERIFY(abstract_ptr_info->__do_catch(p_fund_info, nullptr, 1) == false);
+}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-05-06  6:55 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-03 10:56 [PATCH] libstdc++: fix pointer type exception catch [PR105387] Jakob Hasse
2022-05-04 11:14 ` Jonathan Wakely
2022-05-04 11:18   ` Jonathan Wakely
2022-05-04 22:47   ` Jonathan Wakely
2022-05-05 20:19   ` Jonathan Wakely
2022-05-06  1:43     ` Jakob Hasse
2022-05-06  6:55       ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).