===================================================================
@@ -10532,21 +10532,22 @@ grokdeclarator (const cp_declarator *dec
array_parameter_p = true;
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
type = build_pointer_type (type);
}
if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticp < 2
&& !NEW_DELETE_OPNAME_P (unqualified_id))
{
cp_cv_quals real_quals = memfn_quals;
- if (constexpr_p && sfk != sfk_constructor && sfk != sfk_destructor)
+ if (cxx_dialect < cxx14 && constexpr_p
+ && sfk != sfk_constructor && sfk != sfk_destructor)
real_quals |= TYPE_QUAL_CONST;
type = build_memfn_type (type, ctype, real_quals, rqual);
}
{
tree decl;
if (decl_context == PARM)
{
decl = cp_build_parm_decl (unqualified_id, type);
===================================================================
@@ -17,12 +17,12 @@ struct Defer {
}
};
template <typename Function>
constexpr Defer<Function> make_deferred(const Function f) {
return Defer<Function>(f);
}
int main() {
constexpr auto deferred = make_deferred(&fibonacci);
- static_assert(deferred(25) == 75025, "Static fibonacci call failed");
+ static_assert(deferred(25) == 75025, "Static fibonacci call failed"); // { dg-error "no match for call" "" { target c++14 } }
}
===================================================================
@@ -10,11 +10,11 @@ struct S
constexpr T
S::foo ()
{
return *(T *) (s1 + 10);
}
constexpr S s = { 0,1,2,3,4,5,6,7,8,9,10 };
#define SA(X) static_assert ((X), #X)
-SA(s.foo() == 10);
+SA(s.foo() == 10); // { dg-error "discards qualifiers" "" { target c++14 } }
===================================================================
@@ -1,18 +1,18 @@
// Test that we explain why a template instantiation isn't constexpr
// { dg-do compile { target c++11 } }
template <class T>
struct A
{
T t;
- constexpr int f() { return 42; } // { dg-error "enclosing class" }
+ constexpr int f() const { return 42; } // { dg-error "enclosing class" }
};
struct B { B(); operator int(); };
constexpr A<int> ai = { 42 };
constexpr int i = ai.f();
constexpr int b = A<B>().f(); // { dg-error "non-constexpr function" }
template <class T>
===================================================================
@@ -9,21 +9,21 @@ constexpr T g(T t) { return f(t); } // {
int main()
{
constexpr int i = g(1); // { dg-error "g.T" }
}
// --------------------
struct complex // { dg-message "no constexpr constructor" }
{
complex(double r, double i) : re(r), im(i) { }
- constexpr double real() { return re; } // { dg-error "not a literal type" }
+ constexpr double real() const { return re; } // { dg-error "not a literal type" }
double imag() const { return im; }
private:
double re;
double im;
};
constexpr complex co1(0, 1); // { dg-error "not literal" }
constexpr double dd2 = co1.real(); // { dg-error "non-constexpr function" }
===================================================================
@@ -5,27 +5,27 @@
// 4.1 constant-expression functions
// 1 examples
// 2 defined before first use
// NOTE: this is only needed in contexts that require a constant-expression
struct S {
- constexpr int twice();
- constexpr int t(); // { dg-message "used but never defined" }
+ constexpr int twice() const;
+ constexpr int t() const; // { dg-message "used but never defined" }
private:
static constexpr int val = 7; // constexpr variable
};
-constexpr int S::twice() { return val + val; }
+constexpr int S::twice() const { return val + val; }
constexpr S s = { };
int x1 = s.twice(); // ok
int x2 = s.t(); // error: S::t() not defined
constexpr int x2a = s.t(); // { dg-error "S::t" } error: S::t() not defined
constexpr int ff(); // ok
constexpr int gg(); // ok
int x3 = ff(); // error: ff() not defined
constexpr int x3a = ff(); // { dg-error "ff" } error: ff() not defined
constexpr int ff() { return 1; } // too late
constexpr int gg() { return 2; }
@@ -37,22 +37,22 @@ int x4 = gg(); // ok
// 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; }
+ constexpr double real() const { return re; }
+ constexpr double imag() const { return im; }
private:
double re;
double im;
};
constexpr complex I(0, 1); // OK -- literal complex
// 2 invoked with non-const args
double x5 = 1.0; // { dg-message "not declared .constexpr" }
constexpr complex unit(x5, 0); // { dg-error "x5|argument" } error: x5 non-constant
===================================================================
@@ -1,21 +1,21 @@
// { dg-do compile { target c++11 } }
// 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 -1; }
+ constexpr operator int() const { return val; }
+ constexpr operator long() const { return -1; }
private:
int val;
};
template<int I> struct X { static const int i = I; };
constexpr A a = 42;
X<a> x; // OK: unique conversion to int
int ar[X<a>::i]; // also OK
int ary[a]; // { dg-error "ambiguous|conversion|array" } ambiguous conversion
===================================================================
@@ -1,16 +1,16 @@
// { dg-do compile { target c++11 } }
struct A
{
constexpr A(int) { }
- constexpr operator int() { return 1; };
+ constexpr operator int() const { return 1; };
};
template <class T>
struct B
{
static constexpr A a = A(1);
int ar[a];
};
B<int> b;
===================================================================
@@ -16,25 +16,25 @@ public:
typedef const E& const_reference;
typedef size_t size_type;
typedef const E* iterator;
typedef const E* const_iterator;
constexpr initializer_list() : sz(), start(nullptr) {}
template<size_t N>
constexpr initializer_list(const E(&array)[N]) : sz(N), start(array) {}
- constexpr size_t size() { return sz; }
+ constexpr size_t size() const { return sz; }
- constexpr const E* begin() { return start; }
+ constexpr const E* begin() const { return start; }
- constexpr const E* end() { return start + sz; }
+ constexpr const E* end() const { return start + sz; }
};
template<class E, size_t N>
constexpr initializer_list<E> make_list(const E(&array)[N]) {
return initializer_list<E>(array);
}
template<class E>
E min(initializer_list<E> list)
{
===================================================================
@@ -1,17 +1,17 @@
// { dg-do compile { target c++11 } }
struct C { // literal type
int m;
int n;
constexpr C(int m) : m(m), n(-m) {}
- constexpr bool is_neg() { return m < 0; }
+ constexpr bool is_neg() const { return m < 0; }
};
constexpr bool check1(const C& c, int C:: *pm) { return c.*pm < 0; } // #1
constexpr bool check2(const C* pc, bool (C::*pm)() const) { return
(pc->*pm)(); } // #2
constexpr C c(-1);
static_assert(!check1(c, &C::n), "Error");
===================================================================
@@ -1,14 +1,14 @@
// PR c++/51489
// DR 1313
// { dg-do compile { target c++11 } }
struct array
{
constexpr array() :x(0) {}
- constexpr int const* begin() { return &x; }
+ constexpr int const* begin() const { return &x; }
int x;
};
constexpr array aa;
constexpr auto b = aa.begin();
static_assert(b-b == 0, "compiles just fine");
static_assert(aa.begin()-aa.begin() == 0, "compiler thinks it's not a constant expression");
===================================================================
@@ -1,18 +1,18 @@
// PR c++/54777
// { dg-do compile { target c++11 } }
struct S
{
int s[1];
- constexpr const int &foo (unsigned i) { return (i < 1 ? 0 : throw 1), s[i]; }
- constexpr const int &bar (unsigned i) { return i < 1 ? s[i] : (throw 0, s[i]); }
+ constexpr const int &foo (unsigned i) const { return (i < 1 ? 0 : throw 1), s[i]; }
+ constexpr const int &bar (unsigned i) const { return i < 1 ? s[i] : (throw 0, s[i]); }
};
int
main ()
{
constexpr S a {};
constexpr int i = a.foo (0);
constexpr int j = a.bar (0);
static_assert (i == j, "Ouch");
}
===================================================================
@@ -1,15 +1,15 @@
// { dg-do compile { target c++11 } }
struct B
{
- constexpr operator int() { return 4; }
+ constexpr operator int() const { return 4; }
};
template <int I>
struct C;
template<>
struct C<4> { typedef int TP; };
template <class T>
struct A