From e05ae0d42d040d7832535ad38d5c646311e857a4 Mon Sep 17 00:00:00 2001
From: Maxim Kuvyrkov <maxim@codesourcery.com>
Date: Mon, 27 Dec 2010 04:20:19 -0800
Subject: [PATCH] Testcases

---
 gcc/testsuite/g++.dg/ipa/inline-devirt-1.C |   53 +++++++++++++++++
 gcc/testsuite/g++.dg/ipa/inline-devirt-2.C |   48 ++++++++++++++++
 gcc/testsuite/g++.dg/ipa/inline-devirt-3.C |   48 ++++++++++++++++
 gcc/testsuite/g++.dg/ipa/inline-devirt-4.C |   53 +++++++++++++++++
 gcc/testsuite/g++.dg/ipa/inline-devirt-5.C |   28 +++++++++
 gcc/testsuite/g++.dg/ipa/inline-devirt-6.C |   33 +++++++++++
 gcc/testsuite/g++.dg/ipa/inline-devirt-7.C |   69 +++++++++++++++++++++++
 gcc/testsuite/g++.dg/ipa/inline-devirt-8.C |   71 +++++++++++++++++++++++
 gcc/testsuite/g++.dg/ipa/inline-devirt-9.C |   84 ++++++++++++++++++++++++++++
 9 files changed, 487 insertions(+), 0 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ipa/inline-devirt-1.C
 create mode 100644 gcc/testsuite/g++.dg/ipa/inline-devirt-2.C
 create mode 100644 gcc/testsuite/g++.dg/ipa/inline-devirt-3.C
 create mode 100644 gcc/testsuite/g++.dg/ipa/inline-devirt-4.C
 create mode 100644 gcc/testsuite/g++.dg/ipa/inline-devirt-5.C
 create mode 100644 gcc/testsuite/g++.dg/ipa/inline-devirt-6.C
 create mode 100644 gcc/testsuite/g++.dg/ipa/inline-devirt-7.C
 create mode 100644 gcc/testsuite/g++.dg/ipa/inline-devirt-8.C
 create mode 100644 gcc/testsuite/g++.dg/ipa/inline-devirt-9.C

diff --git a/gcc/testsuite/g++.dg/ipa/inline-devirt-1.C b/gcc/testsuite/g++.dg/ipa/inline-devirt-1.C
new file mode 100644
index 0000000..dadc81e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/inline-devirt-1.C
@@ -0,0 +1,53 @@
+/* Verify that the inliner makes good decisions and the example
+   is optimized to 4 printf()s in main().  */
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-optimized"  }
+
+#include <stdio.h>
+
+class Calculable
+{
+public:
+	virtual unsigned char calculate() = 0;
+	virtual ~Calculable() {}
+};
+
+class X : public Calculable
+{
+public:
+	unsigned char calculate() { return 1; }
+};
+
+class Y : public Calculable
+{
+public:
+	virtual unsigned char calculate() { return 2; }
+};
+
+static void print(X& c)
+{
+	printf("%d\n", c.calculate());
+	printf("+1: %d\n", c.calculate() + 1);
+}
+
+static void print(Y& c)
+{
+	printf("%d\n", c.calculate());
+	printf("+1: %d\n", c.calculate() + 1);
+}
+
+int main()
+{
+	X x;
+	Y y;
+
+	print(x);
+	print(y);
+
+	return 0;
+}
+
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 1\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"\\+1: %d\\\\n\", 2\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 2\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"\\+1: %d\\\\n\", 3\\);" "optimized" } }
diff --git a/gcc/testsuite/g++.dg/ipa/inline-devirt-2.C b/gcc/testsuite/g++.dg/ipa/inline-devirt-2.C
new file mode 100644
index 0000000..78f408d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/inline-devirt-2.C
@@ -0,0 +1,48 @@
+/* Verify that the inliner makes good decisions and the example
+   is optimized to 4 printf()s in main().  */
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-optimized"  }
+
+#include <stdio.h>
+
+class Calculable
+{
+public:
+	virtual unsigned char calculate() = 0;
+	virtual ~Calculable() {}
+};
+
+class X : public Calculable
+{
+public:
+	virtual unsigned char calculate() { return 1; }
+};
+
+class Y : public Calculable
+{
+public:
+	unsigned char calculate() { return 2; }
+};
+
+static void print(Calculable& c)
+{
+	printf("%d\n", c.calculate());
+	printf("+1: %d\n", c.calculate() + 1);
+}
+
+int main()
+{
+	X x;
+	Y y;
+
+	print(x);
+	print(y);
+
+	return 0;
+
+}
+
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 1\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"\\+1: %d\\\\n\", 2\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 2\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"\\+1: %d\\\\n\", 3\\);" "optimized" } }
diff --git a/gcc/testsuite/g++.dg/ipa/inline-devirt-3.C b/gcc/testsuite/g++.dg/ipa/inline-devirt-3.C
new file mode 100644
index 0000000..001f351
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/inline-devirt-3.C
@@ -0,0 +1,48 @@
+/* Verify that the inliner makes good decisions and the example
+   is optimized to 3 printf()s in main().  */
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-optimized"  }
+
+#include <stdio.h>
+
+class Calculable
+{
+public:
+	virtual unsigned char calculate() const = 0;
+	virtual ~Calculable() {}
+};
+
+class X : public Calculable
+{
+public:
+	virtual unsigned char calculate() const { return 0; }
+};
+
+class Y : public Calculable
+{
+public:
+	virtual unsigned char calculate() const { return 3; }
+};
+
+static void print(const Calculable& c)
+{
+	for (int i = 0; i < c.calculate(); i++)
+	{
+		printf("%d\n", c.calculate());
+	}
+}
+
+int main()
+{
+	X x;
+	Y y;
+
+	print(x);
+	print(y);
+
+	return 0;
+}
+
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 3\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 3\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 3\\);" "optimized" } }
diff --git a/gcc/testsuite/g++.dg/ipa/inline-devirt-4.C b/gcc/testsuite/g++.dg/ipa/inline-devirt-4.C
new file mode 100644
index 0000000..9f515cc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/inline-devirt-4.C
@@ -0,0 +1,53 @@
+/* Verify that the inliner makes good decisions and the example
+   is optimized to 2 printf()s in main().  */
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-optimized"  }
+
+#include <stdint.h>
+#include <stdio.h>
+
+class String
+{
+public:
+  virtual uint64_t length() const = 0;
+  virtual char get(uint64_t index) const = 0;
+  virtual void set(uint64_t index, char value) = 0;
+  virtual char& operator[] (uint64_t value) = 0;
+  virtual ~String() {};
+};
+
+template<uint64_t size> class FixedString : public String
+{
+private:
+  char contents[size + 1];
+
+public:
+  virtual uint64_t length() const { return size; }
+  virtual char get(uint64_t index) const { return contents[index]; }
+  virtual void set(uint64_t index, char value) { contents[index] = value; }
+  virtual char& operator[] (uint64_t index) { return contents[index]; } 
+
+  FixedString() { contents[size] = '\0'; }
+};
+
+void print_length (const String& string)
+{
+  for (uint64_t i = 0; i < string.length(); i++)
+    {
+      printf("%d\n", string.get(i));
+    }
+}
+
+int main()
+{
+  FixedString<2> empty;
+  empty[0] = 'a';
+  empty[1] = 'b';
+
+  print_length(empty);
+
+  return 0;
+}
+
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 97\\);" "optimized" { xfail *-*-* } } }
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 98\\);" "optimized" { xfail *-*-* } } }
diff --git a/gcc/testsuite/g++.dg/ipa/inline-devirt-5.C b/gcc/testsuite/g++.dg/ipa/inline-devirt-5.C
new file mode 100644
index 0000000..dbd703d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/inline-devirt-5.C
@@ -0,0 +1,28 @@
+/* Verify that the inliner makes good decisions and the example
+   is optimized to 4 printf()s in main().  */
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-optimized"  }
+
+#include <stdio.h>
+
+typedef unsigned char(*Calculable)(void);
+typedef Calculable(*CalculateStrategy)(void); 
+
+unsigned char one() { return 1; }
+Calculable oneStrategy() { return one; }
+unsigned char two() { return 2; }
+Calculable twoStrategy() { return two; }
+
+int main()
+{
+	printf("%d\n", oneStrategy()());
+	printf("+1: %d\n", oneStrategy()() + 1);
+	printf("%d\n", twoStrategy()());
+	printf("+1: %d\n", twoStrategy()() + 1);
+	return 0;
+}
+
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 1\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"\\+1: %d\\\\n\", 2\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 2\\);" "optimized" } }
+// { dg-final { scan-tree-dump "printf \\(\"\\+1: %d\\\\n\", 3\\);" "optimized" } }
diff --git a/gcc/testsuite/g++.dg/ipa/inline-devirt-6.C b/gcc/testsuite/g++.dg/ipa/inline-devirt-6.C
new file mode 100644
index 0000000..f40728d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/inline-devirt-6.C
@@ -0,0 +1,33 @@
+/* Verify that the inliner makes good decisions and the example
+   is optimized to 4 printf()s in main().  */
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-optimized"  }
+
+#include <stdio.h>
+
+typedef unsigned char(*Calculable)(void);
+typedef Calculable(*CalculateStrategy)(void); 
+
+unsigned char one() { return 1; }
+Calculable oneStrategy() { return one; }
+unsigned char two() { return 2; }
+Calculable twoStrategy() { return two; }
+
+static void print(CalculateStrategy calculateStrategy)
+{
+	printf("%d\n", calculateStrategy()());
+	printf("+1: %d\n", calculateStrategy()() + 1);
+}
+
+int main()
+{
+	print(oneStrategy);
+	print(twoStrategy);
+
+	return 0;
+}
+
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 1\\);" "optimized" { xfail *-*-* } } }
+// { dg-final { scan-tree-dump "printf \\(\"\\+1: %d\\\\n\", 2\\);" "optimized" { xfail *-*-* } } }
+// { dg-final { scan-tree-dump "printf \\(\"%d\\\\n\", 2\\);" "optimized" { xfail *-*-* } } }
+// { dg-final { scan-tree-dump "printf \\(\"\\+1: %d\\\\n\", 3\\);" "optimized" { xfail *-*-* } } }
diff --git a/gcc/testsuite/g++.dg/ipa/inline-devirt-7.C b/gcc/testsuite/g++.dg/ipa/inline-devirt-7.C
new file mode 100644
index 0000000..a1dd4d0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/inline-devirt-7.C
@@ -0,0 +1,69 @@
+/* Verify that the inliner makes good decisions and the example
+   is optimized to 4 printf()s in main().  */
+// { dg-do compile }
+// { dg-options "-O2 -std=c++0x -fdump-tree-optimized"  }
+
+#include <stdio.h>
+
+class Stream
+{
+public:
+	virtual unsigned char read() = 0;
+	virtual ~Stream() {}
+};
+
+class Connection
+{
+public:
+	virtual void open() = 0;
+	virtual void close() = 0;
+	virtual ~Connection() {}
+};
+
+class Socket : public Stream, public Connection
+{
+public:
+	virtual unsigned char read() = 0;
+	virtual void open() = 0;
+	virtual void close() { printf("generic close\n"); }
+};
+
+class LinuxSocket : public Socket
+{
+public:
+	virtual unsigned char read() { return 'l'; }
+	virtual void open() { printf("linux open\n"); }
+};
+
+class CustomSocket : public Socket
+{
+public:
+	virtual unsigned char read() { return 0; }
+	virtual void open() { printf("custom open\n"); }
+	virtual void close() { printf("custom close\n"); }
+};
+
+static void readToEnd(Stream* stream)
+{
+	while (stream->read() == 0) { printf("got it\n"); }
+}
+
+static Socket* createSocket()
+{
+	return new LinuxSocket();
+}
+
+int main()
+{
+	auto socket = createSocket();
+	socket->open();
+	readToEnd(socket);
+	socket->close();
+	
+	delete socket;
+
+	return 0;
+}
+
+// { dg-final { scan-tree-dump "__builtin_puts \\(&\"linux open\[0\]\"\\);$" "optimized" { xfail *-*-* } } }
+// { dg-final { scan-tree-dump "__builtin_puts \\(&\"generic close\[0\]\"\\);$" "optimized" { xfail *-*-* } } }
diff --git a/gcc/testsuite/g++.dg/ipa/inline-devirt-8.C b/gcc/testsuite/g++.dg/ipa/inline-devirt-8.C
new file mode 100644
index 0000000..205fdd4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/inline-devirt-8.C
@@ -0,0 +1,71 @@
+/* Verify that the inliner makes good decisions and the example
+   is optimized to 4 printf()s in main().  */
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-optimized"  }
+
+#include <stdio.h>
+
+template<class TOutput, typename TInput> class Factory
+{
+public:
+	virtual TOutput* createFrom(TInput) = 0;
+	virtual ~Factory() {};
+};
+
+class Calculable
+{
+public:
+	virtual unsigned char calculate() = 0;
+	virtual ~Calculable() {};
+};
+
+class X : public Calculable
+{
+public:
+	virtual unsigned char calculate() { return 1; }
+};
+
+class Y : public Calculable
+{
+public:
+	virtual unsigned char calculate() { throw; }
+};
+
+enum Letter
+{
+	LetterX,
+	LetterY
+};
+
+class CalculableFactory : Factory<Calculable, Letter>
+{
+public:
+      virtual Calculable* createFrom(Letter letter) 
+      { 
+		switch(letter)
+		{
+			case LetterX: return new X();
+			default: return new Y();
+		}
+      }
+};
+
+
+static void print(Calculable* c)
+{
+	printf("+1: %d\n", c->calculate() + 1);
+}
+
+int main()
+{
+	CalculableFactory calcuableFactory;
+	Calculable* calculable = calcuableFactory.createFrom(LetterX);
+
+	print(calculable);
+
+	delete calculable;
+
+	return 0;
+}
+
+// { dg-final { scan-tree-dump "printf \\(\"\\+1: %d\\\\n\", 2\\);" "optimized" { xfail *-*-* } } }
diff --git a/gcc/testsuite/g++.dg/ipa/inline-devirt-9.C b/gcc/testsuite/g++.dg/ipa/inline-devirt-9.C
new file mode 100644
index 0000000..bdd5735
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/inline-devirt-9.C
@@ -0,0 +1,84 @@
+/* Verify that the inliner makes good decisions and the example
+   is optimized to 1 printf() in main().  */
+// { dg-do compile }
+// { dg-options "-O2 -std=c++0x -fdump-tree-optimized"  }
+
+#include <stdio.h>
+#include <memory>
+
+using namespace std;
+
+template<class TOutput, typename TInput> class Factory
+{
+public:
+	virtual shared_ptr<TOutput> createFrom(TInput) = 0;
+	virtual ~Factory() {};
+};
+
+class Calculable
+{
+public:
+	virtual unsigned char calculate() = 0;
+	virtual ~Calculable() {};
+};
+
+enum LetterType
+{
+	LetterX,
+	LetterY
+};
+
+class Letter
+{
+public:
+	Letter(LetterType type) : _type(type) {}
+	virtual ~Letter() {}
+
+protected:
+	LetterType _type;
+};
+
+class X : public Letter, public Calculable
+{
+public:
+	X() : Letter(LetterX) {}
+	virtual unsigned char calculate() { return 1; }
+};
+
+class Y : public Letter, public Calculable
+{
+public:
+	Y() : Letter(LetterY) {}
+	virtual unsigned char calculate() { throw; }
+};
+
+class CalculableFactory : Factory<Calculable, LetterType>
+{
+public:
+      virtual shared_ptr<Calculable> createFrom(LetterType letter) 
+      { 
+		switch(letter)
+		{
+			case LetterX: return make_shared<X>();
+			default: return make_shared<Y>();
+		}
+      }
+};
+
+
+static void print(Calculable& c)
+{
+	printf("+1: %d\n", c.calculate() + 1);
+}
+
+int main()
+{
+	CalculableFactory calcuableFactory;
+	auto calculable = calcuableFactory.createFrom(LetterX);
+
+	print(*calculable);
+
+	return 0;
+}
+
+// { dg-final { scan-tree-dump "printf \\(\"\\+1: %d\\\\n\", 2\\);" "optimized" { xfail *-*-* } } }
-- 
1.6.2.4

