This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[C++] constexpr testsuite


> > The patch is also missing testcases. ÂI assume you have some?
> 
> Yes.

I thought I'd start in on this part, starting with the code examples in
N2235. Then I started to add things that looked like it might be legal,
illegal, or should warn.

In particular, I wanted to make sure that all template use
could stand up to specialization, instantiation, etc. At least at the
parsing phase.

Gaby, not trying to step on your toes here but thought instead that
you'd appreciate the extra hands. 

Results wise, I am using the latest Nov 29 patch, which passes
bootstrap and regression testing testing for me on x86_linux. These new
tests are not especially marked up for dg-error, because I ran into
other issues before this.

best,
benjamin

2009-12-03  Benjamin Kosnik  <bkoz@redhat.com>
	    Gabriel Dos Reis  <gdr@cs.tamu.edu>

	* constexpr-data1.C: New.
	* constexpr-data2.C: New.
	* constexpr-ex1.C: New.
	* constexpr-ex2.C: New.
	* constexpr-function1.C: New.
	* constexpr-function2.C: New.
	* constexpr-function3.C: New.
	* constexpr-object1.C: New.
	* constexpr-object2.C: New.

Index: g++.dg/cpp0x/constexpr-object1.C
===================================================================
--- g++.dg/cpp0x/constexpr-object1.C	(revision 0)
+++ g++.dg/cpp0x/constexpr-object1.C	(revision 0)
@@ -0,0 +1,31 @@
+// { dg-do "compile" }
+// { dg-options "-std=gnu++0x" }
+
+// From N2235
+
+// 4.5.2 semantics
+
+// p 1 constexpr specifier
+// objects, static const data
+struct A1 { };
+
+constexpr int i1 = 1024;
+constexpr A1 a1 = A1();
+
+// error: not a definition
+extern constexpr int i2; // { dg-error "invalid" }
+
+// error: missing initializer
+constexpr A1 a2; // { dg-error "missing initializer for constexpr" }
+
+// error: duplicate cv
+const constexpr A1 a3 = A1(); // { dg-error "both â??constâ?? and â??constexprâ?? cannot" }
+
+volatile constexpr A1 a4 = A1(); // { dg-error "both â??volatileâ?? and â??constexprâ?? cannot" }
+
+// error: on type declaration
+constexpr struct pixel // { dg-error "cannot be used for type declarations" }
+{
+  int x;
+  int y;
+};
Index: g++.dg/cpp0x/constexpr-data1.C
===================================================================
--- g++.dg/cpp0x/constexpr-data1.C	(revision 0)
+++ g++.dg/cpp0x/constexpr-data1.C	(revision 0)
@@ -0,0 +1,43 @@
+// { dg-do "compile" }
+// { dg-options "-std=gnu++0x" }
+
+// From N2235
+
+// 1
+struct A2
+{
+  static const int eights = 888;
+  static constexpr int nines = 999;
+};
+
+A2 a;
+
+// 2
+struct pixel
+{
+  int x, y;
+};
+constexpr pixel ur = { 1294, 1024 }; // OK
+
+// p4
+struct Length
+{
+   explicit constexpr Length(int i = 0) : val(i) { }
+private:
+   int val;
+};
+
+constexpr int abs(int x)
+{ return x < 0 ? -x : x; }    // OK
+
+Length l(abs(-97)); // OK
+
+// p6
+class debug_flag
+{
+public:
+   explicit debug_flag(bool);
+   constexpr bool is_on(); // error: debug_flag not literal type
+private:
+   bool flag;
+};
Index: g++.dg/cpp0x/constexpr-ex1.C
===================================================================
--- g++.dg/cpp0x/constexpr-ex1.C	(revision 0)
+++ g++.dg/cpp0x/constexpr-ex1.C	(revision 0)
@@ -0,0 +1,90 @@
+// { dg-do "compile" }
+// { dg-options "-std=gnu++0x" }
+
+// From N2235
+
+// 4.1 constant-expression functions
+// 1 examples
+
+
+
+
+
+// 2 defined before first use
+struct S {
+    constexpr int twice();
+    constexpr int t();
+private:
+    static constexpr int val;  // constexpr variable
+};
+constexpr int S::val = 7;
+constexpr int S::twice() { return val + val; }
+constexpr S s = { };
+int x1 = s.twice();     // ok
+int x2 = s.t();         // error: S::t() not defined
+constexpr int ff();     // ok
+constexpr int gg();     // ok
+int x3 = ff();          // error: ff() not defined
+constexpr int ff() { return 1; }        // too late
+constexpr int gg() { return 2; }
+int x4 = gg();  // ok
+
+
+// 4.2 const-expression data
+
+// 2
+// storage  not allocated untill address taken
+constexpr double x = 9484.748;
+const double* p = &x;          // the &x forces x into memory
+
+// 4.3 constant-expression constructors
+
+// 1
+struct complex {
+   constexpr complex(double r, double i) : re(r), im(i) { }
+   constexpr double real() { return re; }
+   constexpr double imag() { return im; }
+private:
+   double re;
+   double im;
+};
+constexpr complex I(0, 1);  // OK -- literal complex
+
+
+// 2 invoked with non-const args
+double x = 1.0;
+constexpr complex unit(x, 0); // error: x non-constant
+const complex one(x, 0);   // OK, â??â??ordinary constâ??â?? -- dynamic
+                           //   initialization
+constexpr double xx = I.real(); // OK
+complex z(2, 4);           // OK -- ordinary variable
+
+// 3
+constexpr complex v[] = {
+     complex(0, 0), complex(1, 1), complex(2, 2)
+};
+constexpr double x = v[2].real(); // OK
+
+// 4 
+  constexpr int i = 98;
+  const int p = (int) &i;           // ERROR
+
+// 4.3.2 copy-constructor
+constexpr complex operator+(complex z, complex w)
+{
+  return complex(z.real() + w.real(), z.imag() + w.imag()); // fine
+}
+constexpr complex I2 = I + I;                 // OK
+struct resource {
+  int id;
+  constexpr resource(int i) : id(i) { }       // fine
+  resource(const resource& r) : id(r.id)
+  {
+    cout << id << " copied" << endl;
+  }
+};
+constexpr resource f(resource d)
+{ return d; }                  // error: copy-constructor not trivial
+constexpr resource d = f(9);
+
+// 4.4 floating-point constant expressions
Index: g++.dg/cpp0x/constexpr-object2.C
===================================================================
--- g++.dg/cpp0x/constexpr-object2.C	(revision 0)
+++ g++.dg/cpp0x/constexpr-object2.C	(revision 0)
@@ -0,0 +1,14 @@
+// { dg-do "compile" }
+// { dg-options "-std=gnu++0x" }
+
+constexpr int verysquare(int x) { return x * x; }
+
+const double mass = 9.8;
+constexpr double energy = mass * verysquare(56.6); // OK
+
+float array[verysquare(9)];         // OK -- not C99 VLA
+
+extern const int medium;
+const int high = verysquare(medium); // OK -- dynamic initialization
+
+enum { Max = verysquare(7) };      // OK
Index: g++.dg/cpp0x/constexpr-data2.C
===================================================================
--- g++.dg/cpp0x/constexpr-data2.C	(revision 0)
+++ g++.dg/cpp0x/constexpr-data2.C	(revision 0)
@@ -0,0 +1,47 @@
+// { dg-do "compile" }
+// { dg-options "-std=gnu++0x" }
+
+template<typename _Tp, _Tp v>
+  struct A3
+  {
+    typedef _Tp value_type;
+    typedef A3<value_type,v> type;
+
+    static constexpr value_type value = v;
+
+    constexpr operator value_type() { return value; }
+  };
+
+// Partial specialization.
+template<typename _Tp, _Tp v>
+  struct A3<_Tp*, v>
+  {
+    typedef _Tp* value_type;
+    typedef A3<value_type,v> type;
+
+    static constexpr value_type value = v;
+
+    constexpr operator value_type() { return value; }
+  };
+
+// Explicit specialization.
+template<>
+  struct A3<unsigned short, 0>
+  {
+    typedef unsigned short value_type;
+    typedef A3<value_type, 0> type;
+
+    static constexpr value_type value = 0;
+
+    constexpr operator value_type() { return value; }
+  };
+
+// Explicitly instantiate.
+template struct A3<int, 415>;
+
+// Extern explicitly instantiate.
+extern template struct A3<int, 510>;
+
+// Use.
+A3<int, 1111> a31;
+A3<char, 9999> a32; // Truncate? Overflow?
Index: g++.dg/cpp0x/constexpr-ex2.C
===================================================================
--- g++.dg/cpp0x/constexpr-ex2.C	(revision 0)
+++ g++.dg/cpp0x/constexpr-ex2.C	(revision 0)
@@ -0,0 +1,35 @@
+// { dg-do "compile" }
+// { dg-options "-std=gnu++0x" }
+
+// From N2235
+
+// 4.5.3 constant expressions
+
+// p 4
+struct A {
+  constexpr A(int i) : val(i) { }
+  constexpr operator int() { return val; }
+  constexpr operator long() { return 43; }
+private:
+  int val;
+};
+
+template<int> struct X { };
+constexpr A a = 42;
+
+X<a> x;            // OK: unique conversion to int
+int ary[a];        // error: ambiguous conversion
+
+// p 5
+struct Z {
+  operator int() const { return 42; }
+  operator unsigned char() const { return 43; }
+};
+const Z z = { };
+const int n = z; // OK: n is initialized with 42
+const long m = z; // error: ambiguous conversion
+enum E { v1 = 2, v2 = 10 };
+E operator+(E, E);
+float array[v1 + v2];   // error: v1+v2 not constant
+
+
Index: g++.dg/cpp0x/constexpr-function1.C
===================================================================
--- g++.dg/cpp0x/constexpr-function1.C	(revision 0)
+++ g++.dg/cpp0x/constexpr-function1.C	(revision 0)
@@ -0,0 +1,10 @@
+// { dg-do "compile" }
+// { dg-options "-std=gnu++0x" }
+
+// From N2235
+
+constexpr int veryabs(int x) { return x < 0 ? -x : x; }
+
+constexpr long long_max() { return 2147483647; }
+
+constexpr int verysquare(int x) { return x * x; }
Index: g++.dg/cpp0x/constexpr-function2.C
===================================================================
--- g++.dg/cpp0x/constexpr-function2.C	(revision 0)
+++ g++.dg/cpp0x/constexpr-function2.C	(revision 0)
@@ -0,0 +1,51 @@
+// { dg-do "compile" }
+// { dg-options "-std=gnu++0x" }
+
+// From N2235
+
+// Mess with the builtin by redeclaring.
+constexpr int abs(int x) { return x < 0 ? -x : x; }
+
+extern "C"
+{
+  constexpr float
+  squaref(float x) { return x * x; }
+}
+
+// implicitly inline, already: warn?
+inline constexpr double
+squared(double x) { return x * x; }
+
+constexpr int squarei(int x) { return x * x; }
+extern const int side;
+constexpr int area = squarei(side); // error: squarei(side) is not a
+				    //   constant expression
+
+int next(constexpr int x) // error: argument
+{ return x + 1; }
+
+constexpr void f(int x)       // error: return type is void
+{ /* ... */ }
+
+constexpr int prev(int x)
+{ return --x; }               // error: use of decrement
+
+constexpr int g(int x, int n) // error: body not just â??â??return exprâ??â??
+{
+   int r = 1;
+   while (--n > 0) r *= x;
+   return r;
+}
+
+constexpr int
+bar(int x, int y) { return x + y + x * y; }
+
+int bar(int x, int y)      // error: redefinition of bar
+{ return x * 2 + 3 * y; }
+
+constexpr int twice(int x);
+enum { bufsz = twice(256) };    // error: twice() isnâ??t (yet) defined
+
+constexpr int fac(int x)
+{ return x > 2 ? x * fac(x - 1) : 1; } // error: fac() not defined
+					// before use
Index: g++.dg/cpp0x/constexpr-function3.C
===================================================================
--- g++.dg/cpp0x/constexpr-function3.C	(revision 0)
+++ g++.dg/cpp0x/constexpr-function3.C	(revision 0)
@@ -0,0 +1,30 @@
+// { dg-do "compile" }
+// { dg-options "-std=gnu++0x" }
+
+// From N2235
+
+// function template 1
+template<typename T>
+  constexpr int bytesize(T t)
+  { return sizeof (t); }        // OK
+
+char buf[bytesize(0)];          // OK -- not C99 VLA
+
+
+// function template 2
+template<typename _Tp>
+  constexpr _Tp
+  square(_Tp x) { return x; }
+
+// Explicit specialization
+template<>
+  constexpr unsigned long
+  square(unsigned long x) { return x * x; }
+
+// Explicit instantiation
+template int square(int);
+
+class A { };
+template A square(A);
+
+template constexpr long square(long); // { dg-error "specifier cannot be used in a function declaration that is not a definition" }

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