summaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite')
-rw-r--r--gcc/testsuite/g++.dg/tm/composite1.C14
-rw-r--r--gcc/testsuite/g++.dg/tm/dynamic1.C13
-rw-r--r--gcc/testsuite/g++.dg/tm/dynamic2.C17
-rw-r--r--gcc/testsuite/g++.dg/tm/eh1.C10
-rw-r--r--gcc/testsuite/g++.dg/tm/eh2.C14
-rw-r--r--gcc/testsuite/g++.dg/tm/eh4.C21
-rw-r--r--gcc/testsuite/g++.dg/tm/inherit1.C11
-rw-r--r--gcc/testsuite/g++.dg/tm/inherit2.C33
-rw-r--r--gcc/testsuite/g++.dg/tm/jump1.C23
-rw-r--r--gcc/testsuite/g++.dg/tm/keyword1.C9
-rw-r--r--gcc/testsuite/g++.dg/tm/lambda1.C10
-rw-r--r--gcc/testsuite/g++.dg/tm/lambda2.C9
-rw-r--r--gcc/testsuite/g++.dg/tm/macro1.C5
-rw-r--r--gcc/testsuite/g++.dg/tm/mangle1.C18
-rw-r--r--gcc/testsuite/g++.dg/tm/noexcept-7.C7
-rw-r--r--gcc/testsuite/g++.dg/tm/overload1.C6
-rw-r--r--gcc/testsuite/g++.dg/tm/overload2.C9
-rw-r--r--gcc/testsuite/g++.dg/tm/pretty-print1.C6
-rw-r--r--gcc/testsuite/g++.dg/tm/static_cast1.C9
-rw-r--r--gcc/testsuite/g++.dg/tm/sync1.C15
-rw-r--r--gcc/testsuite/g++.dg/tm/sync2.C21
-rw-r--r--gcc/testsuite/g++.dg/tm/template-3.C15
-rw-r--r--gcc/testsuite/g++.dg/tm/template-4.C13
-rw-r--r--gcc/testsuite/g++.dg/tm/template-5.C12
-rw-r--r--gcc/testsuite/g++.dg/tm/unsafe1.C15
-rw-r--r--gcc/testsuite/g++.dg/tm/unsafe2.C13
-rw-r--r--gcc/testsuite/lib/g++.exp4
27 files changed, 352 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/tm/composite1.C b/gcc/testsuite/g++.dg/tm/composite1.C
new file mode 100644
index 00000000000..6e823176128
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/composite1.C
@@ -0,0 +1,14 @@
+// Test for composite pointer type.
+// { dg-options -fgnu-tm }
+
+void f(bool b)
+{
+ void (*p)() transaction_safe = 0;
+ void (*g)() = 0;
+
+ g = b ? p : g; // OK
+ p = b ? p : g; // { dg-error "" }
+
+ p == g;
+ p != g;
+}
diff --git a/gcc/testsuite/g++.dg/tm/dynamic1.C b/gcc/testsuite/g++.dg/tm/dynamic1.C
new file mode 100644
index 00000000000..a6f49567432
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/dynamic1.C
@@ -0,0 +1,13 @@
+// Test that transaction_safe_dynamic can only be used on virtual functions.
+// { dg-options "-fgnu-tm -std=c++14" }
+
+void f() transaction_safe_dynamic; // { dg-error "virtual" }
+auto a = []() transaction_safe_dynamic {}; // { dg-error "virtual" }
+struct A {
+ void f() transaction_safe_dynamic; // { dg-error "virtual" }
+ virtual void g();
+};
+
+struct B: A {
+ void g() transaction_safe_dynamic;
+};
diff --git a/gcc/testsuite/g++.dg/tm/dynamic2.C b/gcc/testsuite/g++.dg/tm/dynamic2.C
new file mode 100644
index 00000000000..3003b62ca0a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/dynamic2.C
@@ -0,0 +1,17 @@
+// { dg-options "-fgnu-tm -std=c++14 -O2" }
+
+void unsafe();
+struct A {
+ virtual void f() transaction_safe_dynamic;
+};
+struct B:A {
+ void f() { unsafe(); }
+};
+
+void f() transaction_safe {
+ B b;
+ A& ar = b;
+ // This is undefined behavior, we want to give an error with
+ // devirtualization.
+ ar.f(); // { dg-error "unsafe" }
+}
diff --git a/gcc/testsuite/g++.dg/tm/eh1.C b/gcc/testsuite/g++.dg/tm/eh1.C
new file mode 100644
index 00000000000..156121142e7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/eh1.C
@@ -0,0 +1,10 @@
+// A handler can involve a transaction-safety conversion.
+// { dg-do run }
+// { dg-options "-fgnu-tm" }
+
+void g() transaction_safe {}
+int main()
+{
+ try { throw g; }
+ catch (void (*p)()) { }
+}
diff --git a/gcc/testsuite/g++.dg/tm/eh2.C b/gcc/testsuite/g++.dg/tm/eh2.C
new file mode 100644
index 00000000000..307a63924c3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/eh2.C
@@ -0,0 +1,14 @@
+// A handler cannot do the reverse of a transaction-safety conversion.
+// { dg-do run }
+// { dg-options "-fgnu-tm" }
+
+extern "C" void abort();
+
+void g() {}
+
+int main()
+{
+ try { throw g; }
+ catch (void (*p)() transaction_safe) { abort(); }
+ catch (...) { }
+}
diff --git a/gcc/testsuite/g++.dg/tm/eh4.C b/gcc/testsuite/g++.dg/tm/eh4.C
new file mode 100644
index 00000000000..68275e99706
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/eh4.C
@@ -0,0 +1,21 @@
+// Test that throwing out of an atomic_commit block commits the transaction.
+
+// { dg-do run }
+// { dg-options "-fgnu-tm" }
+
+int main()
+{
+ static int i;
+ bool caught = false;
+ try {
+ atomic_commit {
+ i = 12;
+ throw 42;
+ i = 24;
+ }
+ } catch (int x) {
+ caught = (x == 42);
+ }
+ if (!caught || i != 12)
+ __builtin_abort();
+}
diff --git a/gcc/testsuite/g++.dg/tm/inherit1.C b/gcc/testsuite/g++.dg/tm/inherit1.C
new file mode 100644
index 00000000000..b8480a10892
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/inherit1.C
@@ -0,0 +1,11 @@
+// Testcase from TM TS
+// { dg-options "-std=c++14 -fgnu-tm" }
+
+struct B {
+ virtual void f() transaction_safe;
+};
+
+struct D3 : B
+{
+ void f() transaction_safe_dynamic override; // { dg-error "" "B::f() is transaction_safe" }
+};
diff --git a/gcc/testsuite/g++.dg/tm/inherit2.C b/gcc/testsuite/g++.dg/tm/inherit2.C
new file mode 100644
index 00000000000..3b696a9ffb6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/inherit2.C
@@ -0,0 +1,33 @@
+// Testcase from TM TS
+// { dg-options "-std=c++14 -fgnu-tm" }
+
+#include <iostream>
+
+struct B {
+ virtual void f() transaction_safe;
+ virtual ~B() transaction_safe_dynamic;
+};
+// pre-existing code
+struct D1 : B
+{
+ void f() override { } // ok
+ ~D1() override { } // ok
+};
+struct D2 : B
+{
+ void f() override { std::cout << "D2::f" << std::endl; } // { dg-error "" "transaction-safe f has transaction-unsafe definition" }
+ ~D2() override { std::cout << "~D2" << std::endl; } // ok
+};
+int main()
+{
+ D2 * d2 = new D2;
+ B * b2 = d2;
+ atomic_commit {
+ B b; // ok
+ D1 d1; // ok
+ B& b1 = d1;
+ D2 x; // { dg-error "" "destructor of D2 is not transaction-safe" }
+ b1.f(); // ok, calls D1::f()
+ delete b2; // undefined behavior: calls unsafe destructor of D2
+ }
+}
diff --git a/gcc/testsuite/g++.dg/tm/jump1.C b/gcc/testsuite/g++.dg/tm/jump1.C
new file mode 100644
index 00000000000..003eed034c9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/jump1.C
@@ -0,0 +1,23 @@
+// A goto or switch statement shall not be used to transfer control into a
+// synchronized or atomic block.
+// { dg-options "-fgnu-tm" }
+
+void f()
+{
+ static int i;
+ synchronized {
+ ++i;
+ inside: // { dg-message "" }
+ ++i;
+ }
+ goto inside; // { dg-message "" }
+
+ switch (i)
+ {
+ synchronized {
+ ++i;
+ case 42: // { dg-error "" }
+ ++i;
+ }
+ }
+}
diff --git a/gcc/testsuite/g++.dg/tm/keyword1.C b/gcc/testsuite/g++.dg/tm/keyword1.C
new file mode 100644
index 00000000000..3537e0fe992
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/keyword1.C
@@ -0,0 +1,9 @@
+// Test that these aren't keywords without -fgnu-tm.
+
+int main()
+{
+ synchronized { } // { dg-error "not declared" }
+ atomic_noexcept { } // { dg-error "not declared" }
+ atomic_cancel { } // { dg-error "not declared" }
+ atomic_commit { } // { dg-error "not declared" }
+}
diff --git a/gcc/testsuite/g++.dg/tm/lambda1.C b/gcc/testsuite/g++.dg/tm/lambda1.C
new file mode 100644
index 00000000000..d0cffbff22f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/lambda1.C
@@ -0,0 +1,10 @@
+// Test for lambda conversion.
+// { dg-options "-fgnu-tm -std=c++14" }
+
+void f(bool b)
+{
+ void (*p)() transaction_safe;
+
+ p = []() transaction_safe {};
+ p = []{}; // { dg-error "transaction_safe" }
+}
diff --git a/gcc/testsuite/g++.dg/tm/lambda2.C b/gcc/testsuite/g++.dg/tm/lambda2.C
new file mode 100644
index 00000000000..82e509e3658
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/lambda2.C
@@ -0,0 +1,9 @@
+// Test for lambda call.
+// { dg-options "-fgnu-tm -std=c++14" }
+
+void unsafe ();
+void f() transaction_safe
+{
+ []{}(); // OK, implicitly transaction-safe.
+ []{unsafe();}(); // { dg-error "unsafe" }
+}
diff --git a/gcc/testsuite/g++.dg/tm/macro1.C b/gcc/testsuite/g++.dg/tm/macro1.C
new file mode 100644
index 00000000000..dcf388839b1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/macro1.C
@@ -0,0 +1,5 @@
+// { dg-options -fgnu-tm }
+
+#ifndef __cpp_transactional_memory
+#error __cpp_transactional_memory not defined
+#endif
diff --git a/gcc/testsuite/g++.dg/tm/mangle1.C b/gcc/testsuite/g++.dg/tm/mangle1.C
new file mode 100644
index 00000000000..f081f8e0289
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/mangle1.C
@@ -0,0 +1,18 @@
+// Test for transaction_safe mangling.
+// { dg-options -fgnu-tm }
+
+// { dg-final { scan-assembler "_Z1fPDxFvvE" } }
+void f(void (*)() transaction_safe) {}
+
+// { dg-final { scan-assembler "_Z1fPDxFvvEPFvvE" } }
+void f(void (*)() transaction_safe, void (*)()) {}
+
+// { dg-final { scan-assembler "_Z1fPDxFvvES0_" } }
+void f(void (*)() transaction_safe, void (*)() transaction_safe) {}
+
+// { dg-final { scan-assembler "_Z1f1AIKDxFvvEE" } }
+template <class T> struct A { };
+void f(A<void () const transaction_safe>) { }
+
+// { dg-final { scan-assembler "_Z1fM1AIiEKDxFvvE" } }
+void f(void (A<int>::*)() const transaction_safe) { }
diff --git a/gcc/testsuite/g++.dg/tm/noexcept-7.C b/gcc/testsuite/g++.dg/tm/noexcept-7.C
new file mode 100644
index 00000000000..bfa675c987f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/noexcept-7.C
@@ -0,0 +1,7 @@
+// FIXME the TS says atomic_noexcept calls abort, not terminate.
+// { dg-options "-fgnu-tm" }
+
+void f()
+{
+ atomic_noexcept { throw; } // { dg-warning "terminate" }
+}
diff --git a/gcc/testsuite/g++.dg/tm/overload1.C b/gcc/testsuite/g++.dg/tm/overload1.C
new file mode 100644
index 00000000000..71ecab9ff15
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/overload1.C
@@ -0,0 +1,6 @@
+// Function declarations that differ only in the presence or absence of a
+// tx-qualifier cannot be overloaded.
+// { dg-options "-fgnu-tm" }
+
+void f(); // { dg-message "" }
+void f() transaction_safe; // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/tm/overload2.C b/gcc/testsuite/g++.dg/tm/overload2.C
new file mode 100644
index 00000000000..3510779644e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/overload2.C
@@ -0,0 +1,9 @@
+// 13.4p1: A function with type F is selected for the function type FT of the
+// target type required in the context if F (after possibly applying the
+// transaction-safety conversion (4.14 [conv.tx])) is identical to FT.
+// { dg-options "-fgnu-tm" }
+
+void f() transaction_safe;
+void f(int);
+
+void (*p)() = f;
diff --git a/gcc/testsuite/g++.dg/tm/pretty-print1.C b/gcc/testsuite/g++.dg/tm/pretty-print1.C
new file mode 100644
index 00000000000..d7c1de0ae52
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/pretty-print1.C
@@ -0,0 +1,6 @@
+// Test for pretty-printing in diagnostics.
+// { dg-options "-fgnu-tm" }
+
+void f();
+void (*p)() transaction_safe = f; // { dg-error "void \\(\\*\\)\\(\\) transaction_safe" }
+
diff --git a/gcc/testsuite/g++.dg/tm/static_cast1.C b/gcc/testsuite/g++.dg/tm/static_cast1.C
new file mode 100644
index 00000000000..31606c57a7e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/static_cast1.C
@@ -0,0 +1,9 @@
+// The inverse of a transaction-safety conversion cannot be performed with
+// static_cast.
+// { dg-options "-fgnu-tm" }
+
+typedef void (*TS)() transaction_safe;
+void f()
+{
+ static_cast<TS>(f); // { dg-error "static_cast" }
+}
diff --git a/gcc/testsuite/g++.dg/tm/sync1.C b/gcc/testsuite/g++.dg/tm/sync1.C
new file mode 100644
index 00000000000..a567b2cc3e2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/sync1.C
@@ -0,0 +1,15 @@
+// Testcase from TM TS.
+// { dg-options -fgnu-tm }
+
+extern "C" int printf (const char *, ...);
+
+int f()
+{
+ static int i = 0;
+ synchronized {
+ printf("before %d\n", i);
+ ++i;
+ printf("after %d\n", i);
+ return i;
+ }
+}
diff --git a/gcc/testsuite/g++.dg/tm/sync2.C b/gcc/testsuite/g++.dg/tm/sync2.C
new file mode 100644
index 00000000000..f13c9c55e90
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/sync2.C
@@ -0,0 +1,21 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "-fgnu-tm -fdump-tree-optimized-asmname" }
+
+struct Tsafe
+{
+ void f() transaction_safe;
+};
+
+void Tsafe::f() { }
+
+struct Tcall
+{
+ [[optimize_for_synchronized]] void f();
+};
+
+void Tcall::f() { }
+
+// { dg-final { scan-tree-dump-times "_ZN5Tsafe1fEv" 1 "optimized" } }
+// { dg-final { scan-tree-dump-times "_ZN5Tcall1fEv" 1 "optimized" } }
+// { dg-final { scan-tree-dump-times "_ZGTtN5Tsafe1fEv" 1 "optimized" } }
+// { dg-final { scan-tree-dump-times "_ZGTtN5Tcall1fEv" 1 "optimized" } }
diff --git a/gcc/testsuite/g++.dg/tm/template-3.C b/gcc/testsuite/g++.dg/tm/template-3.C
new file mode 100644
index 00000000000..356d2a89b9b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/template-3.C
@@ -0,0 +1,15 @@
+// { dg-options "-fgnu-tm" }
+
+void fn(int) transaction_safe;
+void fn(double);
+
+template <class T> void f(T t) transaction_safe
+{
+ fn(t); // { dg-error "double" }
+}
+
+void g()
+{
+ f(42); // OK
+ f(3.14);
+}
diff --git a/gcc/testsuite/g++.dg/tm/template-4.C b/gcc/testsuite/g++.dg/tm/template-4.C
new file mode 100644
index 00000000000..dd257111bda
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/template-4.C
@@ -0,0 +1,13 @@
+// Test for transaction-safety conversion in deduction.
+// { dg-options "-fgnu-tm" }
+
+void fn(int) transaction_safe;
+void fn();
+
+template <class T> void f(void(*)(T));
+template <class T> void f2(void(*)(T) transaction_safe);
+
+void g()
+{
+ f(fn);
+}
diff --git a/gcc/testsuite/g++.dg/tm/template-5.C b/gcc/testsuite/g++.dg/tm/template-5.C
new file mode 100644
index 00000000000..6501ed1a073
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/template-5.C
@@ -0,0 +1,12 @@
+// Test for deduction based on transaction_safe.
+// { dg-options "-fgnu-tm -std=c++11" }
+
+void f() transaction_safe;
+void g();
+
+template <class T> struct A;
+template <class R, class...Ps>
+struct A<R (Ps...) transaction_safe> { };
+
+A<decltype(f)> a;
+A<decltype(g)> b; // { dg-error "incomplete" }
diff --git a/gcc/testsuite/g++.dg/tm/unsafe1.C b/gcc/testsuite/g++.dg/tm/unsafe1.C
new file mode 100644
index 00000000000..91dd7b110ec
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/unsafe1.C
@@ -0,0 +1,15 @@
+// Transaction-unsafe testcase from TM TS.
+// { dg-options -fgnu-tm }
+
+struct S {
+ virtual ~S();
+};
+int f() transaction_safe {
+ S s; // { dg-error "unsafe" "invocation of unsafe destructor" }
+}
+
+int g(int x) { // is transaction-safe
+ if (x <= 0)
+ return 0;
+ return x + g(x-1);
+}
diff --git a/gcc/testsuite/g++.dg/tm/unsafe2.C b/gcc/testsuite/g++.dg/tm/unsafe2.C
new file mode 100644
index 00000000000..1b81b310057
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/unsafe2.C
@@ -0,0 +1,13 @@
+// Transaction-unsafe testcase from TM TS.
+// { dg-options -fgnu-tm }
+
+template<class T>
+void f(T) transaction_safe;
+template<>
+void f(bool); // not transaction-safe
+
+int g() transaction_safe
+{
+ f(42); // OK
+ f(true); // { dg-error "unsafe" }
+}
diff --git a/gcc/testsuite/lib/g++.exp b/gcc/testsuite/lib/g++.exp
index b440dd7f6c8..229fbc3f633 100644
--- a/gcc/testsuite/lib/g++.exp
+++ b/gcc/testsuite/lib/g++.exp
@@ -141,6 +141,10 @@ proc g++_link_flags { paths } {
if [file exists "${gccpath}/librx/librx.a"] {
append flags "-L${gccpath}/librx "
}
+ if [file exists "${gccpath}/libitm/libitm.spec"] {
+ append flags "-B${gccpath}/libitm/ -L${gccpath}/libitm/.libs"
+ append ld_library_path ":${gccpath}/libitm/.libs"
+ }
append ld_library_path [gcc-set-multilib-library-path $GXX_UNDER_TEST]
} else {
global tool_root_dir