summaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/rtti
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/g++.dg/rtti
downloadcbb-gcc-4.6.4-upstream.tar.bz2
cbb-gcc-4.6.4-upstream.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'gcc/testsuite/g++.dg/rtti')
-rw-r--r--gcc/testsuite/g++.dg/rtti/anon-ns1.C15
-rw-r--r--gcc/testsuite/g++.dg/rtti/crash1.C10
-rw-r--r--gcc/testsuite/g++.dg/rtti/crash2.C9
-rw-r--r--gcc/testsuite/g++.dg/rtti/crash3.C10
-rw-r--r--gcc/testsuite/g++.dg/rtti/crash4.C16
-rw-r--r--gcc/testsuite/g++.dg/rtti/cv1.C17
-rw-r--r--gcc/testsuite/g++.dg/rtti/darwin-builtin-linkage.C20
-rw-r--r--gcc/testsuite/g++.dg/rtti/dyncast1.C23
-rw-r--r--gcc/testsuite/g++.dg/rtti/dyncast2.C31
-rw-r--r--gcc/testsuite/g++.dg/rtti/dyncast3.C81
-rw-r--r--gcc/testsuite/g++.dg/rtti/dyncast4.C26
-rw-r--r--gcc/testsuite/g++.dg/rtti/incomplete1.C12
-rw-r--r--gcc/testsuite/g++.dg/rtti/no-rtti-voidptr.C21
-rw-r--r--gcc/testsuite/g++.dg/rtti/no-rtti.C18
-rw-r--r--gcc/testsuite/g++.dg/rtti/predefined-rtti-macro-1.C12
-rw-r--r--gcc/testsuite/g++.dg/rtti/predefined-rtti-macro-2.C12
-rw-r--r--gcc/testsuite/g++.dg/rtti/repo1.C19
-rw-r--r--gcc/testsuite/g++.dg/rtti/tinfo1.C40
-rw-r--r--gcc/testsuite/g++.dg/rtti/typeid1.C11
-rw-r--r--gcc/testsuite/g++.dg/rtti/typeid2.C15
-rw-r--r--gcc/testsuite/g++.dg/rtti/typeid3.C11
-rw-r--r--gcc/testsuite/g++.dg/rtti/typeid4.C26
-rw-r--r--gcc/testsuite/g++.dg/rtti/typeid5.C13
-rw-r--r--gcc/testsuite/g++.dg/rtti/typeid6.C12
-rw-r--r--gcc/testsuite/g++.dg/rtti/typeid7.C61
-rw-r--r--gcc/testsuite/g++.dg/rtti/typeid8.C26
-rw-r--r--gcc/testsuite/g++.dg/rtti/typeid9.C21
27 files changed, 588 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/rtti/anon-ns1.C b/gcc/testsuite/g++.dg/rtti/anon-ns1.C
new file mode 100644
index 000000000..e18be4300
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/anon-ns1.C
@@ -0,0 +1,15 @@
+// PR c++/49440
+// The typeinfo name for A should start with * so we compare
+// it by address rather than contents.
+
+// { dg-final { scan-assembler "\"\*N\[^\"\]+1AE" } }
+
+namespace
+{
+ class A { };
+}
+
+void f()
+{
+ throw A();
+}
diff --git a/gcc/testsuite/g++.dg/rtti/crash1.C b/gcc/testsuite/g++.dg/rtti/crash1.C
new file mode 100644
index 000000000..eea6a3950
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/crash1.C
@@ -0,0 +1,10 @@
+// { dg-do compile }
+
+// Copyright (C) 2002 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 29 Sep 2002 <nathan@codesourcery.com>
+
+// PR 7788. ICE
+
+class foo;
+extern const foo bar;
+class bar;
diff --git a/gcc/testsuite/g++.dg/rtti/crash2.C b/gcc/testsuite/g++.dg/rtti/crash2.C
new file mode 100644
index 000000000..9646dfdc1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/crash2.C
@@ -0,0 +1,9 @@
+// Copyright (C) 2005 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 16 Jun 2005 <nathan@codesourcery.com>
+
+// Crash when compiler is optimized
+// Origin: Andrew Pinski pinskia@gcc.gnu.org
+
+struct facet { virtual ~facet(); };
+struct ctype_base {};
+struct ctype : facet, ctype_base {};
diff --git a/gcc/testsuite/g++.dg/rtti/crash3.C b/gcc/testsuite/g++.dg/rtti/crash3.C
new file mode 100644
index 000000000..076e36002
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/crash3.C
@@ -0,0 +1,10 @@
+// PR c++/23947
+// { dg-do compile }
+
+class A {};
+class B {};
+class C : public A, public B {};
+class D : public C {};
+void f () throw (D)
+{
+}
diff --git a/gcc/testsuite/g++.dg/rtti/crash4.C b/gcc/testsuite/g++.dg/rtti/crash4.C
new file mode 100644
index 000000000..49807e99f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/crash4.C
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+class ios_base {
+public:
+ virtual ~ios_base();
+};
+template<typename _CharT>
+class basic_ostream : virtual public ios_base {
+public:
+ virtual ~basic_ostream() { }
+};
+extern template class basic_ostream<char>;
+template <typename _CharT>
+class basic_ostringstream : public basic_ostream<_CharT> { };
+template class basic_ostringstream<char>;
diff --git a/gcc/testsuite/g++.dg/rtti/cv1.C b/gcc/testsuite/g++.dg/rtti/cv1.C
new file mode 100644
index 000000000..59dd6592c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/cv1.C
@@ -0,0 +1,17 @@
+// { dg-do run }
+
+#include <typeinfo>
+#include <string.h>
+
+struct S {};
+
+typedef S volatile T[4];
+
+T t[3];
+
+const std::type_info& ti = typeid (t);
+
+int main () {
+ if (strcmp (ti.name (), "A3_A4_1S") != 0)
+ return 1;
+}
diff --git a/gcc/testsuite/g++.dg/rtti/darwin-builtin-linkage.C b/gcc/testsuite/g++.dg/rtti/darwin-builtin-linkage.C
new file mode 100644
index 000000000..6db161169
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/darwin-builtin-linkage.C
@@ -0,0 +1,20 @@
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-final { scan-assembler-not "\\.weak_definition __ZTI" } } */
+
+/* Verify that none of the type_info structures for the fundamental
+ types are emitted as weak on Darwin. */
+
+#include <cxxabi.h>
+
+namespace __cxxabiv1 {
+
+using namespace std;
+
+// This has special meaning to the compiler, and will cause it
+// to emit the type_info structures for the fundamental types which are
+// mandated to exist in the runtime.
+__fundamental_type_info::
+~__fundamental_type_info ()
+{}
+
+}
diff --git a/gcc/testsuite/g++.dg/rtti/dyncast1.C b/gcc/testsuite/g++.dg/rtti/dyncast1.C
new file mode 100644
index 000000000..ace1aef06
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/dyncast1.C
@@ -0,0 +1,23 @@
+class JunkBase
+{
+public:
+ virtual void DoSomething( void ) = 0;
+protected:
+ virtual ~JunkBase( void ) {}
+ JunkBase( void ) {}
+};
+
+class Junk : protected JunkBase
+{
+public:
+ Junk( void ) : JunkBase() {}
+ virtual ~Junk( void ) {}
+protected:
+ inline JunkBase * AsBase( void )
+ { return dynamic_cast< JunkBase * >( this ); }
+ virtual void DoSomething( void ) { }
+};
+
+
+
+
diff --git a/gcc/testsuite/g++.dg/rtti/dyncast2.C b/gcc/testsuite/g++.dg/rtti/dyncast2.C
new file mode 100644
index 000000000..2e4f61596
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/dyncast2.C
@@ -0,0 +1,31 @@
+// PR c++/34364
+// { dg-do run }
+
+struct A
+{
+ virtual ~A () {}
+};
+
+struct B : public A
+{
+ template <typename T> struct C
+ {
+ static void f (A &a)
+ {
+ dynamic_cast <B &>(a).g ();
+ }
+ };
+
+ B () : c (6) {}
+ void g () { c++; }
+ int c;
+};
+
+B b;
+
+int
+main (void)
+{
+ B::C<int>::f (b);
+ return b.c != 7;
+}
diff --git a/gcc/testsuite/g++.dg/rtti/dyncast3.C b/gcc/testsuite/g++.dg/rtti/dyncast3.C
new file mode 100644
index 000000000..08352599b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/dyncast3.C
@@ -0,0 +1,81 @@
+// This testcase used to crash while looking in A for my_module. I'm still
+// not sure it's well-formed, but it works now because of the optimization
+// to look at the expected address first.
+
+// { dg-do run }
+
+extern "C" int puts (const char *);
+extern "C" void abort ();
+
+struct my_object
+{
+ my_object() { puts ("in my_object ctor");}
+ virtual ~my_object() { puts ("in my_object dtor"); }
+};
+
+my_object* my_module_ptr = 0;
+
+struct my_module : my_object
+{
+ my_module()
+ {
+ puts ("in my_module ctor, setting up ptr");
+ my_module_ptr = this;
+ }
+ ~my_module() { puts ("in my_module dtor");}
+};
+
+struct D
+{
+ D() { puts ("in D ctor"); }
+ virtual ~D();
+};
+
+D::~D()
+{
+ puts ("in D dtor");
+ puts ("before DCASTing to my_module*");
+ my_module* m = dynamic_cast<my_module*>(my_module_ptr);
+ if (m != my_module_ptr)
+ abort ();
+ puts ("after DCASTing to my_module*");
+}
+
+struct my_interface
+{
+ my_interface() { puts ("in my_interface ctor");}
+ ~my_interface() { puts ("in my_interface dtor");}
+};
+
+struct myif : virtual my_interface
+{
+ myif() { puts ("in myif ctor");}
+ ~myif() { puts ("in myif dtor");}
+};
+
+struct A: virtual myif
+{
+ A() { puts ("in A ctor"); }
+ ~A() { puts ("in A dtor"); }
+
+ D d;
+};
+
+struct B: virtual myif
+{
+ B() { puts ("in B ctor"); }
+ ~B() { puts ("in B dtor"); }
+
+ D d;
+};
+
+struct C : my_module, A, B
+{
+ C() { puts ("in C ctor");}
+ ~C() { puts ("in C dtor"); }
+};
+
+int main(int, char**)
+{
+ C t;
+}
diff --git a/gcc/testsuite/g++.dg/rtti/dyncast4.C b/gcc/testsuite/g++.dg/rtti/dyncast4.C
new file mode 100644
index 000000000..2a5fd2b3b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/dyncast4.C
@@ -0,0 +1,26 @@
+// Test to make sure that we keep searching if we don't find the type we
+// want at the expected address.
+
+// { dg-do run }
+
+struct A
+{
+ virtual void f() {};
+};
+
+struct B: A { };
+
+struct C: A { };
+
+struct D: B, C { };
+
+int main()
+{
+ D d;
+ A* ap = static_cast<B*>(&d);
+ C* cp = dynamic_cast<C*>(ap);
+ if (cp == 0)
+ return 1;
+ else
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/rtti/incomplete1.C b/gcc/testsuite/g++.dg/rtti/incomplete1.C
new file mode 100644
index 000000000..2bf46e079
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/incomplete1.C
@@ -0,0 +1,12 @@
+// PR c++/28109
+// { dg-do compile }
+
+#include <typeinfo>
+
+struct A;
+
+void foo()
+{
+ A a; // { dg-error "incomplete type" }
+ typeid (a);
+}
diff --git a/gcc/testsuite/g++.dg/rtti/no-rtti-voidptr.C b/gcc/testsuite/g++.dg/rtti/no-rtti-voidptr.C
new file mode 100644
index 000000000..2b3915d17
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/no-rtti-voidptr.C
@@ -0,0 +1,21 @@
+// { dg-do compile }
+// { dg-options "-fno-rtti" }
+
+// PR C++/28687
+
+struct A {
+ virtual ~A() { }
+};
+
+struct B : A {
+};
+
+A* f()
+{
+ return new B();
+}
+
+int main()
+{
+ void* b = dynamic_cast<void*>(f());
+}
diff --git a/gcc/testsuite/g++.dg/rtti/no-rtti.C b/gcc/testsuite/g++.dg/rtti/no-rtti.C
new file mode 100644
index 000000000..fdf2e6052
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/no-rtti.C
@@ -0,0 +1,18 @@
+// { dg-do compile }
+// { dg-options "-fno-rtti" }
+
+// PR C++/10891
+
+struct A {
+ virtual ~A() { }
+};
+
+struct B : A {
+};
+
+A* f();
+
+int main()
+{
+ B* b = dynamic_cast<B*>(f()); // { dg-error "" }
+}
diff --git a/gcc/testsuite/g++.dg/rtti/predefined-rtti-macro-1.C b/gcc/testsuite/g++.dg/rtti/predefined-rtti-macro-1.C
new file mode 100644
index 000000000..5c94bc1de
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/predefined-rtti-macro-1.C
@@ -0,0 +1,12 @@
+// { dg-do compile }
+
+struct A { virtual ~A() { }; };
+struct B : A { };
+
+void f(B* bp)
+{
+ bp =
+#ifdef __GXX_RTTI
+ dynamic_cast<B*>(static_cast<A*>(0));
+#endif
+}
diff --git a/gcc/testsuite/g++.dg/rtti/predefined-rtti-macro-2.C b/gcc/testsuite/g++.dg/rtti/predefined-rtti-macro-2.C
new file mode 100644
index 000000000..284f2f64a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/predefined-rtti-macro-2.C
@@ -0,0 +1,12 @@
+// { dg-do compile }
+// { dg-options "-fno-rtti" }
+
+struct B { };
+
+void f(B* bp)
+{
+ bp =
+#ifndef __GXX_RTTI
+ static_cast<B*>(0);
+#endif
+}
diff --git a/gcc/testsuite/g++.dg/rtti/repo1.C b/gcc/testsuite/g++.dg/rtti/repo1.C
new file mode 100644
index 000000000..f72a9730a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/repo1.C
@@ -0,0 +1,19 @@
+// PR c++/22204
+// { dg-options "-frepo" }
+// { dg-require-host-local "" }
+// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
+
+#include <typeinfo>
+template<int>
+struct function1
+{
+ function1()
+ {
+ typeid(int[100]);
+ }
+};
+function1<1> b;
+
+int main () {}
+
+// { dg-final { cleanup-repo-files } }
diff --git a/gcc/testsuite/g++.dg/rtti/tinfo1.C b/gcc/testsuite/g++.dg/rtti/tinfo1.C
new file mode 100644
index 000000000..bd379aace
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/tinfo1.C
@@ -0,0 +1,40 @@
+// Test if a local definition is in a linkonce/comdat section.
+// { dg-do compile }
+// { dg-final { scan-assembler "_ZTIP9CTemplateIhE\[: \t\n\]" } }
+// { dg-final { scan-assembler-not "(.globl|.global)\[ \]+_ZTIP9CTemplateIhE" } }
+// { dg-final { scan-assembler-not ".section\[^\n\r\]*_ZTIP9CTemplateIhE\[^\n\r\]*" } }
+
+
+namespace std
+{
+ class type_info
+ {
+ protected:
+ const char *__name;
+
+ protected:
+ explicit type_info(const char *__n): __name(__n) { }
+
+ public:
+ const char* name() const
+ { return __name; }
+ };
+}
+
+template<class TYPE>
+class CTemplate
+{
+};
+
+class CSecondModule {
+public:
+ CSecondModule();
+
+private:
+ const CTemplate<unsigned char> *m_variable; typedef CTemplate<unsigned char> m_variable_type;
+};
+
+CSecondModule::CSecondModule()
+{
+ typeid(const_cast<m_variable_type *>(m_variable)).name() != 0;
+}
diff --git a/gcc/testsuite/g++.dg/rtti/typeid1.C b/gcc/testsuite/g++.dg/rtti/typeid1.C
new file mode 100644
index 000000000..e26517576
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/typeid1.C
@@ -0,0 +1,11 @@
+#include <typeinfo>
+
+struct A {
+ virtual ~A() {}
+};
+
+int main() {
+ A* a = new A;
+ typeid(*a).name();
+}
+
diff --git a/gcc/testsuite/g++.dg/rtti/typeid2.C b/gcc/testsuite/g++.dg/rtti/typeid2.C
new file mode 100644
index 000000000..0dbcc598b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/typeid2.C
@@ -0,0 +1,15 @@
+// { dg-do run }
+
+#include <typeinfo>
+
+template <typename T> const char *print_type (const T &) {
+ return typeid(T).name();
+}
+
+/* no template */ void pp1 (int) {}
+template <typename X> void pp2 (X) {}
+
+int main () {
+ if (print_type (&pp1) != print_type (&pp2<int>))
+ return 1;
+}
diff --git a/gcc/testsuite/g++.dg/rtti/typeid3.C b/gcc/testsuite/g++.dg/rtti/typeid3.C
new file mode 100644
index 000000000..a07b39924
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/typeid3.C
@@ -0,0 +1,11 @@
+#include <typeinfo>
+
+template <template <class> class T> struct A {
+ void error() {
+ typeid(T).name(); // { dg-error "missing" }
+ }
+};
+
+template <class T> struct B {};
+
+template void A<B>::error();
diff --git a/gcc/testsuite/g++.dg/rtti/typeid4.C b/gcc/testsuite/g++.dg/rtti/typeid4.C
new file mode 100644
index 000000000..e6a1dce16
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/typeid4.C
@@ -0,0 +1,26 @@
+// { dg-do run }
+// { dg-options "-O2" }
+
+#include <typeinfo>
+#include <iostream>
+
+struct A { virtual ~A () {} };
+
+struct APtr
+{
+ APtr (A* p) : p_ (p) { }
+ A& operator* () const { return *p_; }
+ A* p_;
+};
+
+int main ()
+{
+ APtr ap (new A);
+ std::type_info const* const exp = &typeid (*ap);
+ for (bool cont = true; cont; cont = false)
+ {
+ std::cout << "inner: cont " << cont << std::endl;
+ if (exp) ;
+ }
+}
+
diff --git a/gcc/testsuite/g++.dg/rtti/typeid5.C b/gcc/testsuite/g++.dg/rtti/typeid5.C
new file mode 100644
index 000000000..ef769ce53
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/typeid5.C
@@ -0,0 +1,13 @@
+// PR c++/29928
+// { dg-do compile }
+
+#include <typeinfo>
+
+struct S;
+
+void f()
+{
+ const std::type_info& info1 = typeid(int []);
+ const std::type_info& info2 = typeid(S [3]);
+ const std::type_info& info3 = typeid(S []);
+}
diff --git a/gcc/testsuite/g++.dg/rtti/typeid6.C b/gcc/testsuite/g++.dg/rtti/typeid6.C
new file mode 100644
index 000000000..d8879c59c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/typeid6.C
@@ -0,0 +1,12 @@
+// PR c++/33463
+
+namespace std
+{
+ class type_info {};
+}
+
+template<int> void foo()
+{
+ !typeid(void); // { dg-error "!typeid\\(void\\)|candidate is" }
+ // { dg-message "" "match candidate text" { target *-*-* } 10 }
+}
diff --git a/gcc/testsuite/g++.dg/rtti/typeid7.C b/gcc/testsuite/g++.dg/rtti/typeid7.C
new file mode 100644
index 000000000..7391405fc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/typeid7.C
@@ -0,0 +1,61 @@
+// PR c++/32260
+// { dg-do compile }
+// { dg-options "-O2 -W -Wall" }
+
+#include <typeinfo>
+
+const std::type_info &
+f1 (int i)
+{
+ return typeid (i + 1);
+}
+
+const std::type_info &
+f2 ()
+{
+ return typeid (int);
+}
+
+struct A
+{
+ A ();
+ virtual ~A ();
+ void foo ();
+};
+
+const std::type_info &
+f3 ()
+{
+ return typeid (A);
+}
+
+const std::type_info &
+f4 (A *p)
+{
+ return typeid (*p);
+}
+
+const std::type_info &
+f5 ()
+{
+ return typeid (int *);
+}
+
+const std::type_info &
+f6 ()
+{
+ return typeid (int [26][12]);
+}
+
+const std::type_info &
+f7 ()
+{
+ return typeid (int [26][12]);
+}
+
+void (A::*pmr) ();
+const std::type_info &
+f8 ()
+{
+ return typeid (pmr);
+}
diff --git a/gcc/testsuite/g++.dg/rtti/typeid8.C b/gcc/testsuite/g++.dg/rtti/typeid8.C
new file mode 100644
index 000000000..2b13be5ef
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/typeid8.C
@@ -0,0 +1,26 @@
+// PR c++/36405
+// { dg-do compile }
+
+#include <typeinfo>
+
+struct A
+{
+ void foo ()
+ {
+ typeid (foo).name (); // { dg-error "invalid use of member" }
+ typeid (A::foo).name (); // { dg-error "invalid use of member" }
+ }
+ void bar ()
+ {
+ typeid (foo).name (); // { dg-error "invalid use of member" }
+ typeid (A::foo).name (); // { dg-error "invalid use of member" }
+ }
+ static void baz ()
+ {
+ typeid (baz).name ();
+ typeid (A::baz).name ();
+ }
+};
+
+const char *p1 = typeid (A::foo).name (); // { dg-error "invalid use of non-static member" }
+const char *p2 = typeid (A::baz).name ();
diff --git a/gcc/testsuite/g++.dg/rtti/typeid9.C b/gcc/testsuite/g++.dg/rtti/typeid9.C
new file mode 100644
index 000000000..381252dc6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/typeid9.C
@@ -0,0 +1,21 @@
+// Test that the typeid name for a local class is properly null-terminated.
+// { dg-do run }
+
+#include <string.h>
+#include <typeinfo>
+#include <stdio.h>
+
+int f()
+{
+ struct A {}; struct B {};
+ const std::type_info &ti = typeid(A);
+ const std::type_info &ti2 = typeid(B);
+ puts (ti.name());
+ puts (ti2.name());
+ return strcmp (ti.name(), "Z1fvE1A") || strcmp (ti2.name(), "Z1fvE1B");
+}
+
+int main()
+{
+ return f();
+}