mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-27 23:38:59 -04:00

qualifiers from all levels matching a multidimensional array. For example, this allows casting from pointer to array of array of const volatile int to pointer to const pointer to volatile pointer to int because the multidimensional array part of the source type corresponds to a part of the destination type that contains both 'const' and 'volatile'. Differential Revision: https://reviews.llvm.org/D49457 llvm-svn: 337422
1381 lines
40 KiB
C++
1381 lines
40 KiB
C++
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
|
|
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
|
|
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
|
|
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
|
|
|
|
namespace dr300 { // dr300: yes
|
|
template<typename R, typename A> void f(R (&)(A)) {}
|
|
int g(int);
|
|
void h() { f(g); }
|
|
}
|
|
|
|
namespace dr301 { // dr301: yes
|
|
// see also dr38
|
|
struct S;
|
|
template<typename T> void operator+(T, T);
|
|
void operator-(S, S);
|
|
|
|
void f() {
|
|
bool a = (void(*)(S, S))operator+<S> <
|
|
(void(*)(S, S))operator+<S>;
|
|
bool b = (void(*)(S, S))operator- <
|
|
(void(*)(S, S))operator-;
|
|
bool c = (void(*)(S, S))operator+ <
|
|
(void(*)(S, S))operator-; // expected-error {{expected '>'}}
|
|
}
|
|
|
|
template<typename T> void f() {
|
|
typename T::template operator+<int> a; // expected-error {{typename specifier refers to a non-type template}} expected-error +{{}}
|
|
// FIXME: This shouldn't say (null).
|
|
class T::template operator+<int> b; // expected-error {{identifier followed by '<' indicates a class template specialization but (null) refers to a function template}}
|
|
enum T::template operator+<int> c; // expected-error {{expected identifier}} expected-error {{does not declare anything}}
|
|
enum T::template operator+<int>::E d; // expected-error {{qualified name refers into a specialization of function template 'T::template operator +'}} expected-error {{forward reference}}
|
|
enum T::template X<int>::E e;
|
|
T::template operator+<int>::foobar(); // expected-error {{qualified name refers into a specialization of function template 'T::template operator +'}}
|
|
T::template operator+<int>(0); // ok
|
|
}
|
|
|
|
template<typename T> class operator&<T*> {}; // expected-error +{{}}
|
|
template<typename T> class T::operator& {}; // expected-error +{{}}
|
|
template<typename T> class S::operator&<T*> {}; // expected-error +{{}}
|
|
}
|
|
|
|
namespace dr302 { // dr302: yes
|
|
struct A { A(); ~A(); };
|
|
#if __cplusplus < 201103L
|
|
struct B { // expected-error {{implicit default constructor for 'dr302::B' must explicitly initialize the const member 'n'}}
|
|
const int n; // expected-note {{declared here}}
|
|
A a;
|
|
} b = B(); // expected-note {{first required here}}
|
|
// Trivial default constructor C::C() is not called here.
|
|
struct C {
|
|
const int n;
|
|
} c = C();
|
|
#else
|
|
struct B {
|
|
const int n; // expected-note {{deleted because field 'n' of const-qualified type 'const int' would not be initialized}}
|
|
A a;
|
|
} b = B(); // expected-error {{call to implicitly-deleted default constructor}}
|
|
// C::C() is called here, because even though it's trivial, it's deleted.
|
|
struct C {
|
|
const int n; // expected-note {{deleted because field 'n' of const-qualified type 'const int' would not be initialized}}
|
|
} c = C(); // expected-error {{call to implicitly-deleted default constructor}}
|
|
struct D {
|
|
const int n = 0;
|
|
} d = D();
|
|
#endif
|
|
}
|
|
|
|
// dr303: na
|
|
|
|
namespace dr304 { // dr304: yes
|
|
typedef int &a;
|
|
int n = a(); // expected-error {{requires an initializer}}
|
|
|
|
struct S { int &b; };
|
|
int m = S().b;
|
|
#if __cplusplus < 201103L
|
|
// expected-error@-3 {{requires an initializer}}
|
|
// expected-note@-3 {{in value-initialization}}
|
|
#else
|
|
// expected-error@-5 {{deleted}}
|
|
// expected-note@-7 {{reference}}
|
|
#endif
|
|
}
|
|
|
|
namespace dr305 { // dr305: no
|
|
struct A {
|
|
typedef A C;
|
|
};
|
|
void f(A *a) {
|
|
struct A {};
|
|
a->~A();
|
|
a->~C();
|
|
}
|
|
typedef A B;
|
|
void g(B *b) {
|
|
b->~B();
|
|
b->~C();
|
|
}
|
|
void h(B *b) {
|
|
struct B {}; // expected-note {{declared here}}
|
|
b->~B(); // expected-error {{does not match}}
|
|
}
|
|
|
|
template<typename T> struct X {};
|
|
void i(X<int>* x) {
|
|
struct X {};
|
|
x->~X<int>();
|
|
x->~X();
|
|
x->~X<char>(); // expected-error {{no member named}}
|
|
}
|
|
|
|
#if __cplusplus >= 201103L
|
|
struct Y {
|
|
template<typename T> using T1 = Y;
|
|
};
|
|
template<typename T> using T2 = Y;
|
|
void j(Y *y) {
|
|
y->~T1<int>();
|
|
y->~T2<int>();
|
|
}
|
|
struct Z {
|
|
template<typename T> using T2 = T;
|
|
};
|
|
void k(Z *z) {
|
|
z->~T1<int>(); // expected-error {{no member named 'T1' in 'dr305::Z'}} expected-error +{{}}
|
|
z->~T2<int>(); // expected-error {{no member named '~int'}}
|
|
z->~T2<Z>();
|
|
}
|
|
|
|
// FIXME: This is valid.
|
|
namespace Q {
|
|
template<typename A> struct R {};
|
|
}
|
|
template<typename A> using R = Q::R<int>;
|
|
void qr(Q::R<int> x) { x.~R<char>(); } // expected-error {{no member named}}
|
|
#endif
|
|
}
|
|
|
|
namespace dr306 { // dr306: no
|
|
// FIXME: dup 39
|
|
// FIXME: This should be accepted.
|
|
struct A { struct B {}; }; // expected-note 2{{member}}
|
|
struct C { typedef A::B B; }; // expected-note {{member}}
|
|
struct D : A, A::B, C {};
|
|
D::B b; // expected-error {{found in multiple base classes of different types}}
|
|
}
|
|
|
|
// dr307: na
|
|
|
|
namespace dr308 { // dr308: yes
|
|
// This is mostly an ABI library issue.
|
|
struct A {};
|
|
struct B : A {};
|
|
struct C : A {};
|
|
struct D : B, C {};
|
|
void f() {
|
|
try {
|
|
throw D();
|
|
} catch (const A&) { // expected-note {{for type 'const dr308::A &'}}
|
|
// unreachable
|
|
} catch (const B&) { // expected-warning {{exception of type 'const dr308::B &' will be caught by earlier handler}}
|
|
// get here instead
|
|
}
|
|
}
|
|
}
|
|
|
|
// dr309: dup 485
|
|
|
|
namespace dr311 { // dr311: yes
|
|
namespace X { namespace Y {} }
|
|
namespace X::Y {}
|
|
#if __cplusplus <= 201402L
|
|
// expected-error@-2 {{define each namespace separately}}
|
|
#endif
|
|
namespace X {
|
|
namespace X::Y {}
|
|
#if __cplusplus <= 201402L
|
|
// expected-error@-2 {{define each namespace separately}}
|
|
#endif
|
|
}
|
|
// FIXME: The diagnostics here are not very good.
|
|
namespace ::dr311::X {} // expected-error 2+{{}} // expected-warning {{extra qual}}
|
|
}
|
|
|
|
// dr312: dup 616
|
|
|
|
namespace dr313 { // dr313: dup 299 c++11
|
|
struct A { operator int() const; };
|
|
int *p = new int[A()];
|
|
#if __cplusplus < 201103L
|
|
// FIXME: should this be available in c++98 mode? expected-error@-2 {{extension}}
|
|
#endif
|
|
}
|
|
|
|
namespace dr314 { // FIXME 314: dup 1710
|
|
template<typename T> struct A {
|
|
template<typename U> struct B {};
|
|
};
|
|
template<typename T> struct C : public A<T>::template B<T> {
|
|
C() : A<T>::template B<T>() {}
|
|
};
|
|
}
|
|
|
|
// dr315: na
|
|
// dr316: sup 1004
|
|
|
|
namespace dr317 { // dr317: 3.5
|
|
void f() {} // expected-note {{previous}}
|
|
inline void f(); // expected-error {{inline declaration of 'f' follows non-inline definition}}
|
|
|
|
int g();
|
|
int n = g();
|
|
inline int g() { return 0; }
|
|
|
|
int h();
|
|
int m = h();
|
|
int h() { return 0; } // expected-note {{previous}}
|
|
inline int h(); // expected-error {{inline declaration of 'h' follows non-inline definition}}
|
|
}
|
|
|
|
namespace dr318 { // dr318: sup 1310
|
|
struct A {};
|
|
struct A::A a;
|
|
}
|
|
|
|
namespace dr319 { // dr319: no
|
|
// FIXME: dup dr389
|
|
// FIXME: We don't have a diagnostic for a name with linkage
|
|
// having a type without linkage.
|
|
typedef struct {
|
|
int i;
|
|
} *ps;
|
|
extern "C" void f(ps);
|
|
void g(ps); // FIXME: ill-formed, type 'ps' has no linkage
|
|
|
|
static enum { e } a1;
|
|
enum { e2 } a2; // FIXME: ill-formed, enum type has no linkage
|
|
|
|
enum { n1 = 1u };
|
|
typedef int (*pa)[n1];
|
|
pa parr; // ok, type has linkage despite using 'n1'
|
|
|
|
template<typename> struct X {};
|
|
|
|
void f() {
|
|
struct A { int n; };
|
|
extern A a; // FIXME: ill-formed
|
|
X<A> xa;
|
|
|
|
typedef A B;
|
|
extern B b; // FIXME: ill-formed
|
|
X<B> xb;
|
|
|
|
const int n = 1;
|
|
typedef int (*C)[n];
|
|
extern C c; // ok
|
|
X<C> xc;
|
|
}
|
|
#if __cplusplus < 201103L
|
|
// expected-error@-12 {{uses local type 'A'}}
|
|
// expected-error@-9 {{uses local type 'A'}}
|
|
#endif
|
|
}
|
|
|
|
namespace dr320 { // dr320: yes
|
|
#if __cplusplus >= 201103L
|
|
struct X {
|
|
constexpr X() {}
|
|
constexpr X(const X &x) : copies(x.copies + 1) {}
|
|
unsigned copies = 0;
|
|
};
|
|
constexpr X f(X x) { return x; }
|
|
constexpr unsigned g(X x) { return x.copies; }
|
|
static_assert(f(X()).copies == g(X()) + 1, "expected one extra copy for return value");
|
|
#endif
|
|
}
|
|
|
|
namespace dr321 { // dr321: dup 557
|
|
namespace N {
|
|
template<int> struct A {
|
|
template<int> struct B;
|
|
};
|
|
template<> template<> struct A<0>::B<0>;
|
|
void f(A<0>::B<0>);
|
|
}
|
|
template<> template<> struct N::A<0>::B<0> {};
|
|
|
|
template<typename T> void g(T t) { f(t); }
|
|
template void g(N::A<0>::B<0>);
|
|
|
|
namespace N {
|
|
template<typename> struct I { friend bool operator==(const I&, const I&); };
|
|
}
|
|
N::I<int> i, j;
|
|
bool x = i == j;
|
|
}
|
|
|
|
namespace dr322 { // dr322: yes
|
|
struct A {
|
|
template<typename T> operator T&();
|
|
} a;
|
|
int &r = static_cast<int&>(a);
|
|
int &s = a;
|
|
}
|
|
|
|
// dr323: no
|
|
|
|
namespace dr324 { // dr324: yes
|
|
struct S { int n : 1; } s; // expected-note 3{{bit-field is declared here}}
|
|
int &a = s.n; // expected-error {{non-const reference cannot bind to bit-field}}
|
|
int *b = &s.n; // expected-error {{address of bit-field}}
|
|
int &c = (s.n = 0); // expected-error {{non-const reference cannot bind to bit-field}}
|
|
int *d = &(s.n = 0); // expected-error {{address of bit-field}}
|
|
int &e = true ? s.n : s.n; // expected-error {{non-const reference cannot bind to bit-field}}
|
|
int *f = &(true ? s.n : s.n); // expected-error {{address of bit-field}}
|
|
int &g = (void(), s.n); // expected-error {{non-const reference cannot bind to bit-field}}
|
|
int *h = &(void(), s.n); // expected-error {{address of bit-field}}
|
|
int *i = &++s.n; // expected-error {{address of bit-field}}
|
|
}
|
|
|
|
namespace dr326 { // dr326: yes
|
|
struct S {};
|
|
int test[__is_trivially_constructible(S, const S&) ? 1 : -1];
|
|
}
|
|
|
|
namespace dr327 { // dr327: dup 538
|
|
struct A;
|
|
class A {};
|
|
|
|
class B;
|
|
struct B {};
|
|
}
|
|
|
|
namespace dr328 { // dr328: yes
|
|
struct A; // expected-note 3{{forward declaration}}
|
|
struct B { A a; }; // expected-error {{incomplete}}
|
|
template<typename> struct C { A a; }; // expected-error {{incomplete}}
|
|
A *p = new A[0]; // expected-error {{incomplete}}
|
|
}
|
|
|
|
namespace dr329 { // dr329: 3.5
|
|
struct B {};
|
|
template<typename T> struct A : B {
|
|
friend void f(A a) { g(a); }
|
|
friend void h(A a) { g(a); } // expected-error {{undeclared}}
|
|
friend void i(B b) {} // expected-error {{redefinition}} expected-note {{previous}}
|
|
};
|
|
A<int> a;
|
|
A<char> b; // expected-note {{instantiation}}
|
|
|
|
void test() {
|
|
h(a); // expected-note {{instantiation}}
|
|
}
|
|
}
|
|
|
|
namespace dr330 { // dr330: 7
|
|
// Conversions between P and Q will be allowed by P0388.
|
|
typedef int *(*P)[3];
|
|
typedef const int *const (*Q)[3];
|
|
typedef const int *Qinner[3];
|
|
typedef Qinner const *Q2; // same as Q, but 'const' written outside the array type
|
|
typedef const int *const (*R)[4];
|
|
typedef const int *const (*S)[];
|
|
typedef const int *(*T)[];
|
|
void f(P p, Q q, Q2 q2, R r, S s, T t) {
|
|
q = p; // ok
|
|
q2 = p; // ok
|
|
r = p; // expected-error {{incompatible}}
|
|
s = p; // expected-error {{incompatible}} (for now)
|
|
t = p; // expected-error {{incompatible}}
|
|
s = q; // expected-error {{incompatible}}
|
|
s = q2; // expected-error {{incompatible}}
|
|
s = t; // ok, adding const
|
|
t = s; // expected-error {{incompatible}}
|
|
(void) const_cast<P>(q);
|
|
(void) const_cast<P>(q2);
|
|
(void) const_cast<Q>(p);
|
|
(void) const_cast<Q2>(p);
|
|
(void) const_cast<S>(p); // expected-error {{not allowed}} (for now)
|
|
(void) const_cast<P>(s); // expected-error {{not allowed}} (for now)
|
|
(void) const_cast<S>(q); // expected-error {{not allowed}}
|
|
(void) const_cast<S>(q2); // expected-error {{not allowed}}
|
|
(void) const_cast<Q>(s); // expected-error {{not allowed}}
|
|
(void) const_cast<Q2>(s); // expected-error {{not allowed}}
|
|
(void) const_cast<T>(s);
|
|
(void) const_cast<S>(t);
|
|
(void) const_cast<T>(q); // expected-error {{not allowed}}
|
|
(void) const_cast<Q>(t); // expected-error {{not allowed}}
|
|
|
|
(void) reinterpret_cast<P>(q); // expected-error {{casts away qualifiers}}
|
|
(void) reinterpret_cast<P>(q2); // expected-error {{casts away qualifiers}}
|
|
(void) reinterpret_cast<Q>(p);
|
|
(void) reinterpret_cast<Q2>(p);
|
|
(void) reinterpret_cast<S>(p);
|
|
(void) reinterpret_cast<P>(s); // expected-error {{casts away qualifiers}}
|
|
(void) reinterpret_cast<S>(q);
|
|
(void) reinterpret_cast<S>(q2);
|
|
(void) reinterpret_cast<Q>(s);
|
|
(void) reinterpret_cast<Q2>(s);
|
|
(void) reinterpret_cast<T>(s); // expected-error {{casts away qualifiers}}
|
|
(void) reinterpret_cast<S>(t);
|
|
(void) reinterpret_cast<T>(q); // expected-error {{casts away qualifiers}}
|
|
(void) reinterpret_cast<Q>(t);
|
|
}
|
|
|
|
namespace swift_17882 {
|
|
typedef const char P[72];
|
|
typedef int *Q;
|
|
void f(P &pr, P *pp) {
|
|
(void) reinterpret_cast<const Q&>(pr);
|
|
(void) reinterpret_cast<const Q*>(pp);
|
|
}
|
|
|
|
struct X {};
|
|
typedef const volatile int A[1][2][3];
|
|
typedef int *const X::*volatile *B1;
|
|
typedef int *const X::* *B2;
|
|
typedef int *X::* volatile *B3;
|
|
typedef volatile int *(*const B4)[4];
|
|
void f(A *a) {
|
|
(void) reinterpret_cast<B1*>(a);
|
|
(void) reinterpret_cast<B2*>(a); // expected-error {{casts away qualifiers}}
|
|
(void) reinterpret_cast<B3*>(a); // expected-error {{casts away qualifiers}}
|
|
(void) reinterpret_cast<B4*>(a);
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace dr331 { // dr331: yes
|
|
struct A {
|
|
A(volatile A&); // expected-note {{candidate}}
|
|
} const a, b(a); // expected-error {{no matching constructor}}
|
|
}
|
|
|
|
namespace dr332 { // dr332: dup 577
|
|
void f(volatile void); // expected-error {{'void' as parameter must not have type qualifiers}}
|
|
void g(const void); // expected-error {{'void' as parameter must not have type qualifiers}}
|
|
void h(int n, volatile void); // expected-error {{'void' must be the first and only parameter}}
|
|
}
|
|
|
|
namespace dr333 { // dr333: yes
|
|
int n = 0;
|
|
int f(int(n));
|
|
int g((int(n)));
|
|
int h = f(g);
|
|
}
|
|
|
|
namespace dr334 { // dr334: yes
|
|
template<typename T> void f() {
|
|
T x;
|
|
f((x, 123));
|
|
}
|
|
struct S {
|
|
friend S operator,(S, int);
|
|
friend void f(S);
|
|
};
|
|
template void f<S>();
|
|
}
|
|
|
|
// dr335: no
|
|
|
|
namespace dr336 { // dr336: yes
|
|
namespace Pre {
|
|
template<class T1> class A {
|
|
template<class T2> class B {
|
|
template<class T3> void mf1(T3);
|
|
void mf2();
|
|
};
|
|
};
|
|
template<> template<class X> class A<int>::B {};
|
|
template<> template<> template<class T> void A<int>::B<double>::mf1(T t) {} // expected-error {{does not match}}
|
|
template<class Y> template<> void A<Y>::B<double>::mf2() {} // expected-error {{does not refer into a class}}
|
|
}
|
|
namespace Post {
|
|
template<class T1> class A {
|
|
template<class T2> class B {
|
|
template<class T3> void mf1(T3);
|
|
void mf2();
|
|
};
|
|
};
|
|
template<> template<class X> class A<int>::B {
|
|
template<class T> void mf1(T);
|
|
};
|
|
template<> template<> template<class T> void A<int>::B<double>::mf1(T t) {}
|
|
// FIXME: This diagnostic isn't very good.
|
|
template<class Y> template<> void A<Y>::B<double>::mf2() {} // expected-error {{does not refer into a class}}
|
|
}
|
|
}
|
|
|
|
namespace dr337 { // dr337: yes
|
|
template<typename T> void f(T (*)[1]);
|
|
template<typename T> int &f(...);
|
|
|
|
struct A { virtual ~A() = 0; };
|
|
int &r = f<A>(0);
|
|
|
|
// FIXME: The language rules here are completely broken. We cannot determine
|
|
// whether an incomplete type is abstract. See DR1640, which will probably
|
|
// supersede this one and remove this rule.
|
|
struct B;
|
|
int &s = f<B>(0); // expected-error {{of type 'void'}}
|
|
struct B { virtual ~B() = 0; };
|
|
}
|
|
|
|
namespace dr339 { // dr339: yes
|
|
template <int I> struct A { static const int value = I; };
|
|
|
|
char xxx(int);
|
|
char (&xxx(float))[2];
|
|
|
|
template<class T> A<sizeof(xxx((T)0))> f(T) {} // expected-note {{candidate}}
|
|
|
|
void test() {
|
|
A<1> a = f(0);
|
|
A<2> b = f(0.0f);
|
|
A<3> c = f("foo"); // expected-error {{no matching function}}
|
|
}
|
|
|
|
|
|
char f(int);
|
|
int f(...);
|
|
|
|
template <class T> struct conv_int {
|
|
static const bool value = sizeof(f(T())) == 1;
|
|
};
|
|
|
|
template <class T> bool conv_int2(A<sizeof(f(T()))> p);
|
|
|
|
template<typename T> A<sizeof(f(T()))> make_A();
|
|
|
|
int a[conv_int<char>::value ? 1 : -1];
|
|
bool b = conv_int2<char>(A<1>());
|
|
A<1> c = make_A<char>();
|
|
}
|
|
|
|
namespace dr340 { // dr340: yes
|
|
struct A { A(int); };
|
|
struct B { B(A, A, int); };
|
|
int x, y;
|
|
B b(A(x), A(y), 3);
|
|
}
|
|
|
|
namespace dr341 { // dr341: sup 1708
|
|
namespace A {
|
|
int n;
|
|
extern "C" int &dr341_a = n; // expected-note {{previous}} expected-note {{declared with C language linkage here}}
|
|
}
|
|
namespace B {
|
|
extern "C" int &dr341_a = dr341_a; // expected-error {{redefinition}}
|
|
}
|
|
extern "C" void dr341_b(); // expected-note {{declared with C language linkage here}}
|
|
}
|
|
int dr341_a; // expected-error {{declaration of 'dr341_a' in global scope conflicts with declaration with C language linkage}}
|
|
int dr341_b; // expected-error {{declaration of 'dr341_b' in global scope conflicts with declaration with C language linkage}}
|
|
int dr341_c; // expected-note {{declared in global scope here}}
|
|
int dr341_d; // expected-note {{declared in global scope here}}
|
|
namespace dr341 {
|
|
extern "C" int dr341_c; // expected-error {{declaration of 'dr341_c' with C language linkage conflicts with declaration in global scope}}
|
|
extern "C" void dr341_d(); // expected-error {{declaration of 'dr341_d' with C language linkage conflicts with declaration in global scope}}
|
|
|
|
namespace A { extern "C" int dr341_e; } // expected-note {{previous}}
|
|
namespace B { extern "C" void dr341_e(); } // expected-error {{redefinition of 'dr341_e' as different kind of symbol}}
|
|
}
|
|
|
|
// dr342: na
|
|
|
|
namespace dr343 { // FIXME 343: no
|
|
// FIXME: dup 1710
|
|
template<typename T> struct A {
|
|
template<typename U> struct B {};
|
|
};
|
|
// FIXME: In these contexts, the 'template' keyword is optional.
|
|
template<typename T> struct C : public A<T>::B<T> { // expected-error {{use 'template'}}
|
|
C() : A<T>::B<T>() {} // expected-error {{use 'template'}}
|
|
};
|
|
}
|
|
|
|
namespace dr344 { // dr344: dup 1435
|
|
struct A { inline virtual ~A(); };
|
|
struct B { friend A::~A(); };
|
|
}
|
|
|
|
namespace dr345 { // dr345: yes
|
|
struct A {
|
|
struct X {};
|
|
int X; // expected-note {{here}}
|
|
};
|
|
struct B {
|
|
struct X {};
|
|
};
|
|
template <class T> void f(T t) { typename T::X x; } // expected-error {{refers to non-type member 'X'}}
|
|
void f(A a, B b) {
|
|
f(b);
|
|
f(a); // expected-note {{instantiation}}
|
|
}
|
|
}
|
|
|
|
// dr346: na
|
|
|
|
namespace dr347 { // dr347: yes
|
|
struct base {
|
|
struct nested;
|
|
static int n;
|
|
static void f();
|
|
void g();
|
|
};
|
|
|
|
struct derived : base {};
|
|
|
|
struct derived::nested {}; // expected-error {{no struct named 'nested'}}
|
|
int derived::n; // expected-error {{no member named 'n'}}
|
|
void derived::f() {} // expected-error {{does not match any}}
|
|
void derived::g() {} // expected-error {{does not match any}}
|
|
}
|
|
|
|
// dr348: na
|
|
|
|
namespace dr349 { // dr349: no
|
|
struct A {
|
|
template <class T> operator T ***() {
|
|
int ***p = 0;
|
|
return p; // expected-error {{cannot initialize return object of type 'const int ***' with an lvalue of type 'int ***'}}
|
|
}
|
|
};
|
|
|
|
// FIXME: This is valid.
|
|
A a;
|
|
const int *const *const *p1 = a; // expected-note {{in instantiation of}}
|
|
|
|
struct B {
|
|
template <class T> operator T ***() {
|
|
const int ***p = 0;
|
|
return p;
|
|
}
|
|
};
|
|
|
|
// FIXME: This is invalid.
|
|
B b;
|
|
const int *const *const *p2 = b;
|
|
}
|
|
|
|
// dr351: na
|
|
|
|
namespace dr352 { // dr352: yes
|
|
namespace example1 {
|
|
namespace A {
|
|
enum E {};
|
|
template<typename R, typename A> void foo(E, R (*)(A)); // expected-note 2{{couldn't infer template argument 'R'}}
|
|
}
|
|
|
|
template<typename T> void arg(T);
|
|
template<typename T> int arg(T) = delete; // expected-note {{here}} expected-error 0-1{{extension}}
|
|
|
|
void f(A::E e) {
|
|
foo(e, &arg); // expected-error {{no matching function}}
|
|
|
|
using A::foo;
|
|
foo<int, int>(e, &arg); // expected-error {{deleted}}
|
|
}
|
|
|
|
int arg(int);
|
|
|
|
void g(A::E e) {
|
|
foo(e, &arg); // expected-error {{no matching function}}
|
|
|
|
using A::foo;
|
|
foo<int, int>(e, &arg); // ok, uses non-template
|
|
}
|
|
}
|
|
|
|
namespace contexts {
|
|
template<int I> void f1(int (&)[I]);
|
|
template<int I> void f2(int (&)[I+1]); // expected-note {{couldn't infer}}
|
|
template<int I> void f3(int (&)[I+1], int (&)[I]);
|
|
void f() {
|
|
int a[4];
|
|
int b[3];
|
|
f1(a);
|
|
f2(a); // expected-error {{no matching function}}
|
|
f3(a, b);
|
|
}
|
|
|
|
template<int I> struct S {};
|
|
template<int I> void g1(S<I>);
|
|
template<int I> void g2(S<I+1>); // expected-note {{couldn't infer}}
|
|
template<int I> void g3(S<I+1>, S<I>);
|
|
void g() {
|
|
S<4> a;
|
|
S<3> b;
|
|
g1(a);
|
|
g2(a); // expected-error {{no matching function}}
|
|
g3(a, b);
|
|
}
|
|
|
|
template<typename T> void h1(T = 0); // expected-note {{couldn't infer}}
|
|
template<typename T> void h2(T, T = 0);
|
|
void h() {
|
|
h1(); // expected-error {{no matching function}}
|
|
h1(0);
|
|
h1<int>();
|
|
h2(0);
|
|
}
|
|
|
|
template<typename T> int tmpl(T);
|
|
template<typename R, typename A> void i1(R (*)(A)); // expected-note 3{{couldn't infer}}
|
|
template<typename R, typename A> void i2(R, A, R (*)(A)); // expected-note {{not viable}}
|
|
void i() {
|
|
extern int single(int);
|
|
i1(single);
|
|
i2(0, 0, single);
|
|
|
|
extern int ambig(float), ambig(int);
|
|
i1(ambig); // expected-error {{no matching function}}
|
|
i2(0, 0, ambig);
|
|
|
|
extern void no_match(float), no_match(int);
|
|
i1(no_match); // expected-error {{no matching function}}
|
|
i2(0, 0, no_match); // expected-error {{no matching function}}
|
|
|
|
i1(tmpl); // expected-error {{no matching function}}
|
|
i2(0, 0, tmpl);
|
|
}
|
|
}
|
|
|
|
template<typename T> struct is_int;
|
|
template<> struct is_int<int> {};
|
|
|
|
namespace example2 {
|
|
template<typename T> int f(T (*p)(T)) { is_int<T>(); }
|
|
int g(int);
|
|
int g(char);
|
|
int i = f(g);
|
|
}
|
|
|
|
namespace example3 {
|
|
template<typename T> int f(T, T (*p)(T)) { is_int<T>(); }
|
|
int g(int);
|
|
char g(char);
|
|
int i = f(1, g);
|
|
}
|
|
|
|
namespace example4 {
|
|
template <class T> int f(T, T (*p)(T)) { is_int<T>(); }
|
|
char g(char);
|
|
template <class T> T g(T);
|
|
int i = f(1, g);
|
|
}
|
|
|
|
namespace example5 {
|
|
template<int I> class A {};
|
|
template<int I> void g(A<I+1>); // expected-note {{couldn't infer}}
|
|
template<int I> void f(A<I>, A<I+1>);
|
|
void h(A<1> a1, A<2> a2) {
|
|
g(a1); // expected-error {{no matching function}}
|
|
g<0>(a1);
|
|
f(a1, a2);
|
|
}
|
|
}
|
|
}
|
|
|
|
// dr353 needs an IRGen test.
|
|
|
|
namespace dr354 { // dr354: yes c++11
|
|
// FIXME: Should we allow this in C++98 too?
|
|
struct S {};
|
|
|
|
template<int*> struct ptr {}; // expected-note 0-4{{here}}
|
|
ptr<0> p0;
|
|
ptr<(int*)0> p1;
|
|
ptr<(float*)0> p2;
|
|
ptr<(int S::*)0> p3;
|
|
#if __cplusplus < 201103L
|
|
// expected-error@-5 {{does not refer to any decl}}
|
|
// expected-error@-5 {{does not refer to any decl}}
|
|
// expected-error@-5 {{does not refer to any decl}}
|
|
// expected-error@-5 {{does not refer to any decl}}
|
|
#elif __cplusplus <= 201402L
|
|
// expected-error@-10 {{must be cast}}
|
|
// ok
|
|
// expected-error@-10 {{does not match}}
|
|
// expected-error@-10 {{does not match}}
|
|
#else
|
|
// expected-error@-15 {{conversion from 'int' to 'int *' is not allowed}}
|
|
// ok
|
|
// expected-error@-15 {{'float *' is not implicitly convertible to 'int *'}}
|
|
// expected-error@-15 {{'int dr354::S::*' is not implicitly convertible to 'int *'}}
|
|
#endif
|
|
|
|
template<int*> int both();
|
|
template<int> int both();
|
|
int b0 = both<0>();
|
|
int b1 = both<(int*)0>();
|
|
#if __cplusplus < 201103L
|
|
// expected-error@-2 {{no matching function}}
|
|
// expected-note@-6 {{candidate}}
|
|
// expected-note@-6 {{candidate}}
|
|
#endif
|
|
|
|
template<int S::*> struct ptr_mem {}; // expected-note 0-4{{here}}
|
|
ptr_mem<0> m0;
|
|
ptr_mem<(int S::*)0> m1;
|
|
ptr_mem<(float S::*)0> m2;
|
|
ptr_mem<(int *)0> m3;
|
|
#if __cplusplus < 201103L
|
|
// expected-error@-5 {{cannot be converted}}
|
|
// expected-error@-5 {{is not a pointer to member constant}}
|
|
// expected-error@-5 {{cannot be converted}}
|
|
// expected-error@-5 {{cannot be converted}}
|
|
#elif __cplusplus <= 201402L
|
|
// expected-error@-10 {{must be cast}}
|
|
// ok
|
|
// expected-error@-10 {{does not match}}
|
|
// expected-error@-10 {{does not match}}
|
|
#else
|
|
// expected-error@-15 {{conversion from 'int' to 'int dr354::S::*' is not allowed}}
|
|
// ok
|
|
// expected-error@-15 {{'float dr354::S::*' is not implicitly convertible to 'int dr354::S::*'}}
|
|
// expected-error@-15 {{'int *' is not implicitly convertible to 'int dr354::S::*'}}
|
|
#endif
|
|
}
|
|
|
|
struct dr355_S; // dr355: yes
|
|
struct ::dr355_S {}; // expected-warning {{extra qualification}}
|
|
namespace dr355 { struct ::dr355_S s; }
|
|
|
|
// dr356: na
|
|
|
|
namespace dr357 { // dr357: yes
|
|
template<typename T> struct A {
|
|
void f() const; // expected-note {{const qualified}}
|
|
};
|
|
template<typename T> void A<T>::f() {} // expected-error {{does not match}}
|
|
|
|
struct B {
|
|
template<typename T> void f();
|
|
};
|
|
template<typename T> void B::f() const {} // expected-error {{does not match}}
|
|
}
|
|
|
|
namespace dr358 { // dr358: yes
|
|
extern "C" void dr358_f();
|
|
namespace N {
|
|
int var;
|
|
extern "C" void dr358_f() { var = 10; }
|
|
}
|
|
}
|
|
|
|
namespace dr359 { // dr359: yes
|
|
// Note, the example in the DR is wrong; it doesn't contain an anonymous
|
|
// union.
|
|
struct E {
|
|
union {
|
|
struct {
|
|
int x;
|
|
} s;
|
|
} v;
|
|
|
|
union {
|
|
struct { // expected-error {{extension}}
|
|
int x;
|
|
} s;
|
|
|
|
struct S { // expected-error {{types cannot be declared in an anonymous union}}
|
|
int x;
|
|
} t;
|
|
|
|
union { // expected-error {{extension}}
|
|
int u;
|
|
};
|
|
};
|
|
};
|
|
}
|
|
|
|
// dr362: na
|
|
// dr363: na
|
|
|
|
namespace dr364 { // dr364: yes
|
|
struct S {
|
|
static void f(int);
|
|
void f(char);
|
|
};
|
|
|
|
void g() {
|
|
S::f('a'); // expected-error {{call to non-static}}
|
|
S::f(0);
|
|
}
|
|
}
|
|
|
|
#if "foo" // expected-error {{invalid token}} dr366: yes
|
|
#endif
|
|
|
|
namespace dr367 { // dr367: yes
|
|
// FIXME: These diagnostics are terrible. Don't diagnose an ill-formed global
|
|
// array as being a VLA!
|
|
int a[true ? throw 0 : 4]; // expected-error 2{{variable length array}}
|
|
int b[true ? 4 : throw 0];
|
|
int c[true ? *new int : 4]; // expected-error 2{{variable length array}}
|
|
int d[true ? 4 : *new int];
|
|
#if __cplusplus < 201103L
|
|
// expected-error@-4 {{variable length array}} expected-error@-4 {{constant expression}}
|
|
// expected-error@-3 {{variable length array}} expected-error@-3 {{constant expression}}
|
|
#endif
|
|
}
|
|
|
|
namespace dr368 { // dr368: yes
|
|
template<typename T, T> struct S {}; // expected-note {{here}}
|
|
template<typename T> int f(S<T, T()> *); // expected-error {{function type}}
|
|
//template<typename T> int g(S<T, (T())> *); // FIXME: crashes clang
|
|
template<typename T> int g(S<T, true ? T() : T()> *); // expected-note {{cannot have type 'dr368::X'}}
|
|
struct X {};
|
|
int n = g<X>(0); // expected-error {{no matching}}
|
|
}
|
|
|
|
// dr370: na
|
|
|
|
namespace dr372 { // dr372: no
|
|
namespace example1 {
|
|
template<typename T> struct X {
|
|
protected:
|
|
typedef T Type; // expected-note 2{{protected}}
|
|
};
|
|
template<typename T> struct Y {};
|
|
|
|
// FIXME: These two are valid; deriving from T1<T> gives Z1 access to
|
|
// the protected member T1<T>::Type.
|
|
template<typename T,
|
|
template<typename> class T1,
|
|
template<typename> class T2> struct Z1 :
|
|
T1<T>,
|
|
T2<typename T1<T>::Type> {}; // expected-error {{protected}}
|
|
|
|
template<typename T,
|
|
template<typename> class T1,
|
|
template<typename> class T2> struct Z2 :
|
|
T2<typename T1<T>::Type>, // expected-error {{protected}}
|
|
T1<T> {};
|
|
|
|
Z1<int, X, Y> z1; // expected-note {{instantiation of}}
|
|
Z2<int, X, Y> z2; // expected-note {{instantiation of}}
|
|
}
|
|
|
|
namespace example2 {
|
|
struct X {
|
|
private:
|
|
typedef int Type; // expected-note {{private}}
|
|
};
|
|
template<typename T> struct A {
|
|
typename T::Type t; // expected-error {{private}}
|
|
};
|
|
A<X> ax; // expected-note {{instantiation of}}
|
|
}
|
|
|
|
namespace example3 {
|
|
struct A {
|
|
protected:
|
|
typedef int N; // expected-note 2{{protected}}
|
|
};
|
|
|
|
template<typename T> struct B {};
|
|
template<typename U> struct C : U, B<typename U::N> {}; // expected-error {{protected}}
|
|
template<typename U> struct D : B<typename U::N>, U {}; // expected-error {{protected}}
|
|
|
|
C<A> x; // expected-note {{instantiation of}}
|
|
D<A> y; // expected-note {{instantiation of}}
|
|
}
|
|
|
|
namespace example4 {
|
|
class A {
|
|
class B {};
|
|
friend class X;
|
|
};
|
|
|
|
struct X : A::B {
|
|
A::B mx;
|
|
class Y {
|
|
A::B my;
|
|
};
|
|
};
|
|
}
|
|
|
|
// FIXME: This is valid: deriving from A gives D access to A::B
|
|
namespace std_example {
|
|
class A {
|
|
protected:
|
|
struct B {}; // expected-note {{here}}
|
|
};
|
|
struct D : A::B, A {}; // expected-error {{protected}}
|
|
}
|
|
|
|
// FIXME: This is valid: deriving from A::B gives access to A::B!
|
|
namespace badwolf {
|
|
class A {
|
|
protected:
|
|
struct B; // expected-note {{here}}
|
|
};
|
|
struct A::B : A {};
|
|
struct C : A::B {}; // expected-error {{protected}}
|
|
}
|
|
}
|
|
|
|
namespace dr373 { // dr373: 5
|
|
namespace X { int dr373; }
|
|
struct dr373 { // expected-note {{here}}
|
|
void f() {
|
|
using namespace dr373::X;
|
|
int k = dr373; // expected-error {{does not refer to a value}}
|
|
|
|
namespace Y = dr373::X;
|
|
k = Y::dr373;
|
|
}
|
|
};
|
|
|
|
struct A { struct B {}; }; // expected-note 2{{here}}
|
|
namespace X = A::B; // expected-error {{expected namespace name}}
|
|
using namespace A::B; // expected-error {{expected namespace name}}
|
|
}
|
|
|
|
namespace dr374 { // dr374: yes
|
|
namespace N {
|
|
template<typename T> void f();
|
|
template<typename T> struct A { void f(); };
|
|
}
|
|
template<> void N::f<char>() {}
|
|
template<> void N::A<char>::f() {}
|
|
template<> struct N::A<int> {};
|
|
}
|
|
|
|
// dr375: dup 345
|
|
// dr376: na
|
|
|
|
namespace dr377 { // dr377: yes
|
|
enum E { // expected-error {{enumeration values exceed range of largest integer}}
|
|
a = -__LONG_LONG_MAX__ - 1, // expected-error 0-1{{extension}}
|
|
b = 2 * (unsigned long long)__LONG_LONG_MAX__ // expected-error 0-2{{extension}}
|
|
};
|
|
}
|
|
|
|
// dr378: dup 276
|
|
// dr379: na
|
|
|
|
namespace dr381 { // dr381: yes
|
|
struct A {
|
|
int a;
|
|
};
|
|
struct B : virtual A {};
|
|
struct C : B {};
|
|
struct D : B {};
|
|
struct E : public C, public D {};
|
|
struct F : public A {};
|
|
void f() {
|
|
E e;
|
|
e.B::a = 0; // expected-error {{ambiguous conversion}}
|
|
F f;
|
|
f.A::a = 1;
|
|
}
|
|
}
|
|
|
|
namespace dr382 { // dr382: yes c++11
|
|
// FIXME: Should we allow this in C++98 mode?
|
|
struct A { typedef int T; };
|
|
typename A::T t;
|
|
typename dr382::A a;
|
|
#if __cplusplus < 201103L
|
|
// expected-error@-3 {{occurs outside of a template}}
|
|
// expected-error@-3 {{occurs outside of a template}}
|
|
#endif
|
|
typename A b; // expected-error {{expected a qualified name}}
|
|
}
|
|
|
|
namespace dr383 { // dr383: yes
|
|
struct A { A &operator=(const A&); };
|
|
struct B { ~B(); };
|
|
union C { C &operator=(const C&); };
|
|
union D { ~D(); };
|
|
int check[(__is_pod(A) || __is_pod(B) || __is_pod(C) || __is_pod(D)) ? -1 : 1];
|
|
}
|
|
|
|
namespace dr384 { // dr384: yes
|
|
namespace N1 {
|
|
template<typename T> struct Base {};
|
|
template<typename T> struct X {
|
|
struct Y : public Base<T> {
|
|
Y operator+(int) const;
|
|
};
|
|
Y f(unsigned i) { return Y() + i; }
|
|
};
|
|
}
|
|
|
|
namespace N2 {
|
|
struct Z {};
|
|
template<typename T> int *operator+(T, unsigned);
|
|
}
|
|
|
|
int main() {
|
|
N1::X<N2::Z> v;
|
|
v.f(0);
|
|
}
|
|
}
|
|
|
|
namespace dr385 { // dr385: yes
|
|
struct A { protected: void f(); };
|
|
struct B : A { using A::f; };
|
|
struct C : A { void g(B b) { b.f(); } };
|
|
void h(B b) { b.f(); }
|
|
|
|
struct D { int n; }; // expected-note {{member}}
|
|
struct E : protected D {}; // expected-note 2{{protected}}
|
|
struct F : E { friend int i(E); };
|
|
int i(E e) { return e.n; } // expected-error {{protected base}} expected-error {{protected member}}
|
|
}
|
|
|
|
namespace dr387 { // dr387: yes
|
|
namespace old {
|
|
template<typename T> class number {
|
|
number(int); // expected-note 2{{here}}
|
|
friend number gcd(number &x, number &y) {}
|
|
};
|
|
|
|
void g() {
|
|
number<double> a(3), b(4); // expected-error 2{{private}}
|
|
a = gcd(a, b);
|
|
b = gcd(3, 4); // expected-error {{undeclared}}
|
|
}
|
|
}
|
|
|
|
namespace newer {
|
|
template <typename T> class number {
|
|
public:
|
|
number(int);
|
|
friend number gcd(number x, number y) { return 0; }
|
|
};
|
|
|
|
void g() {
|
|
number<double> a(3), b(4);
|
|
a = gcd(a, b);
|
|
b = gcd(3, 4); // expected-error {{undeclared}}
|
|
}
|
|
}
|
|
}
|
|
|
|
// FIXME: dr388 needs codegen test
|
|
|
|
namespace dr389 { // dr389: no
|
|
struct S {
|
|
typedef struct {} A;
|
|
typedef enum {} B;
|
|
typedef struct {} const C; // expected-note 0-2{{here}}
|
|
typedef enum {} const D; // expected-note 0-1{{here}}
|
|
};
|
|
template<typename> struct T {};
|
|
|
|
struct WithLinkage1 {};
|
|
enum WithLinkage2 {};
|
|
typedef struct {} *WithLinkage3a, WithLinkage3b;
|
|
typedef enum {} WithLinkage4a, *WithLinkage4b;
|
|
typedef S::A WithLinkage5;
|
|
typedef const S::B WithLinkage6;
|
|
typedef int WithLinkage7;
|
|
typedef void (*WithLinkage8)(WithLinkage2 WithLinkage1::*, WithLinkage5 *);
|
|
typedef T<WithLinkage5> WithLinkage9;
|
|
|
|
typedef struct {} *WithoutLinkage1; // expected-note 0-1{{here}}
|
|
typedef enum {} const WithoutLinkage2; // expected-note 0-1{{here}}
|
|
// These two types don't have linkage even though they are externally visible
|
|
// and the ODR requires them to be merged across TUs.
|
|
typedef S::C WithoutLinkage3;
|
|
typedef S::D WithoutLinkage4;
|
|
typedef void (*WithoutLinkage5)(int (WithoutLinkage3::*)(char));
|
|
|
|
#if __cplusplus >= 201103L
|
|
// This has linkage even though its template argument does not.
|
|
// FIXME: This is probably a defect.
|
|
typedef T<WithoutLinkage1> WithLinkage10;
|
|
#else
|
|
typedef int WithLinkage10; // dummy
|
|
|
|
typedef T<WithLinkage1> GoodArg1;
|
|
typedef T<WithLinkage2> GoodArg2;
|
|
typedef T<WithLinkage3a> GoodArg3a;
|
|
typedef T<WithLinkage3b> GoodArg3b;
|
|
typedef T<WithLinkage4a> GoodArg4a;
|
|
typedef T<WithLinkage4b> GoodArg4b;
|
|
typedef T<WithLinkage5> GoodArg5;
|
|
typedef T<WithLinkage6> GoodArg6;
|
|
typedef T<WithLinkage7> GoodArg7;
|
|
typedef T<WithLinkage8> GoodArg8;
|
|
typedef T<WithLinkage9> GoodArg9;
|
|
|
|
typedef T<WithoutLinkage1> BadArg1; // expected-error{{template argument uses}}
|
|
typedef T<WithoutLinkage2> BadArg2; // expected-error{{template argument uses}}
|
|
typedef T<WithoutLinkage3> BadArg3; // expected-error{{template argument uses}}
|
|
typedef T<WithoutLinkage4> BadArg4; // expected-error{{template argument uses}}
|
|
typedef T<WithoutLinkage5> BadArg5; // expected-error{{template argument uses}}
|
|
#endif
|
|
|
|
extern WithLinkage1 withLinkage1;
|
|
extern WithLinkage2 withLinkage2;
|
|
extern WithLinkage3a withLinkage3a;
|
|
extern WithLinkage3b withLinkage3b;
|
|
extern WithLinkage4a withLinkage4a;
|
|
extern WithLinkage4b withLinkage4b;
|
|
extern WithLinkage5 withLinkage5;
|
|
extern WithLinkage6 withLinkage6;
|
|
extern WithLinkage7 withLinkage7;
|
|
extern WithLinkage8 withLinkage8;
|
|
extern WithLinkage9 withLinkage9;
|
|
extern WithLinkage10 withLinkage10;
|
|
|
|
// FIXME: These are all ill-formed.
|
|
extern WithoutLinkage1 withoutLinkage1;
|
|
extern WithoutLinkage2 withoutLinkage2;
|
|
extern WithoutLinkage3 withoutLinkage3;
|
|
extern WithoutLinkage4 withoutLinkage4;
|
|
extern WithoutLinkage5 withoutLinkage5;
|
|
|
|
// OK, extern "C".
|
|
extern "C" {
|
|
extern WithoutLinkage1 dr389_withoutLinkage1;
|
|
extern WithoutLinkage2 dr389_withoutLinkage2;
|
|
extern WithoutLinkage3 dr389_withoutLinkage3;
|
|
extern WithoutLinkage4 dr389_withoutLinkage4;
|
|
extern WithoutLinkage5 dr389_withoutLinkage5;
|
|
}
|
|
|
|
// OK, defined.
|
|
WithoutLinkage1 withoutLinkageDef1;
|
|
WithoutLinkage2 withoutLinkageDef2 = WithoutLinkage2();
|
|
WithoutLinkage3 withoutLinkageDef3 = {};
|
|
WithoutLinkage4 withoutLinkageDef4 = WithoutLinkage4();
|
|
WithoutLinkage5 withoutLinkageDef5;
|
|
|
|
void use(const void *);
|
|
void use_all() {
|
|
use(&withLinkage1); use(&withLinkage2); use(&withLinkage3a); use(&withLinkage3b);
|
|
use(&withLinkage4a); use(&withLinkage4b); use(&withLinkage5); use(&withLinkage6);
|
|
use(&withLinkage7); use(&withLinkage8); use(&withLinkage9); use(&withLinkage10);
|
|
|
|
use(&withoutLinkage1); use(&withoutLinkage2); use(&withoutLinkage3);
|
|
use(&withoutLinkage4); use(&withoutLinkage5);
|
|
|
|
use(&dr389_withoutLinkage1); use(&dr389_withoutLinkage2);
|
|
use(&dr389_withoutLinkage3); use(&dr389_withoutLinkage4);
|
|
use(&dr389_withoutLinkage5);
|
|
|
|
use(&withoutLinkageDef1); use(&withoutLinkageDef2); use(&withoutLinkageDef3);
|
|
use(&withoutLinkageDef4); use(&withoutLinkageDef5);
|
|
}
|
|
|
|
void local() {
|
|
// FIXME: This is ill-formed.
|
|
extern WithoutLinkage1 withoutLinkageLocal;
|
|
}
|
|
}
|
|
|
|
namespace dr390 { // dr390: yes
|
|
template<typename T>
|
|
struct A {
|
|
A() { f(); } // expected-warning {{call to pure virt}}
|
|
virtual void f() = 0; // expected-note {{here}}
|
|
virtual ~A() = 0;
|
|
};
|
|
template<typename T> A<T>::~A() { T::error; } // expected-error {{cannot be used prior to}}
|
|
template<typename T> void A<T>::f() { T::error; } // ok, not odr-used
|
|
struct B : A<int> { // expected-note 2{{in instantiation of}}
|
|
void f() {}
|
|
} b;
|
|
}
|
|
|
|
namespace dr391 { // dr391: yes c++11
|
|
// FIXME: Should this apply to C++98 too?
|
|
class A { A(const A&); }; // expected-note 0-1{{here}}
|
|
A fa();
|
|
const A &a = fa();
|
|
#if __cplusplus < 201103L
|
|
// expected-error@-2 {{C++98 requires an accessible copy constructor}}
|
|
#endif
|
|
|
|
struct B { B(const B&) = delete; }; // expected-error 0-1{{extension}} expected-note 0-1{{here}}
|
|
B fb();
|
|
const B &b = fb();
|
|
#if __cplusplus < 201103L
|
|
// expected-error@-2 {{deleted}}
|
|
#endif
|
|
|
|
template<typename T>
|
|
struct C {
|
|
C(const C&) { T::error; }
|
|
};
|
|
C<int> fc();
|
|
const C<int> &c = fc();
|
|
}
|
|
|
|
// dr392 FIXME write codegen test
|
|
// dr394: na
|
|
|
|
namespace dr395 { // dr395: yes
|
|
struct S {
|
|
template <typename T, int N>(&operator T())[N]; // expected-error {{cannot specify any part of a return type}}
|
|
template <typename T, int N> operator(T (&)[N])(); // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error +{{}}
|
|
template <typename T> operator T *() const { return 0; }
|
|
template <typename T, typename U> operator T U::*() const { return 0; }
|
|
template <typename T, typename U> operator T (U::*)()() const { return 0; } // expected-error +{{}}
|
|
};
|
|
|
|
struct null1_t {
|
|
template <class T, class U> struct ptr_mem_fun_t {
|
|
typedef T (U::*type)();
|
|
};
|
|
|
|
template <class T, class U>
|
|
operator typename ptr_mem_fun_t<T, U>::type() const { // expected-note {{couldn't infer}}
|
|
return 0;
|
|
}
|
|
} null1;
|
|
int (S::*p)() = null1; // expected-error {{no viable conversion}}
|
|
|
|
template <typename T> using id = T; // expected-error 0-1{{extension}}
|
|
|
|
struct T {
|
|
template <typename T, int N> operator id<T[N]> &();
|
|
template <typename T, typename U> operator id<T (U::*)()>() const;
|
|
};
|
|
|
|
struct null2_t {
|
|
template<class T, class U> using ptr_mem_fun_t = T (U::*)(); // expected-error 0-1{{extension}}
|
|
template<class T, class U> operator ptr_mem_fun_t<T, U>() const { return 0; };
|
|
} null2;
|
|
int (S::*q)() = null2;
|
|
}
|
|
|
|
namespace dr396 { // dr396: yes
|
|
void f() {
|
|
auto int a(); // expected-error {{storage class on function}}
|
|
int (i); // expected-note {{previous}}
|
|
auto int (i); // expected-error {{redefinition}}
|
|
#if __cplusplus >= 201103L
|
|
// expected-error@-4 {{'auto' storage class}} expected-error@-2 {{'auto' storage class}}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
// dr397: sup 1823
|
|
|
|
namespace dr398 { // dr398: yes
|
|
namespace example1 {
|
|
struct S {
|
|
static int const I = 42;
|
|
};
|
|
template <int N> struct X {};
|
|
template <typename T> void f(X<T::I> *) {}
|
|
template <typename T> void f(X<T::J> *) {}
|
|
void foo() { f<S>(0); }
|
|
}
|
|
|
|
namespace example2 {
|
|
template <int I> struct X {};
|
|
template <template <class T> class> struct Z {};
|
|
template <class T> void f(typename T::Y *) {} // expected-note 2{{substitution failure}}
|
|
template <class T> void g(X<T::N> *) {} // expected-note {{substitution failure}}
|
|
template <class T> void h(Z<T::template TT> *) {} // expected-note {{substitution failure}}
|
|
struct A {};
|
|
struct B {
|
|
int Y;
|
|
};
|
|
struct C {
|
|
typedef int N;
|
|
};
|
|
struct D {
|
|
typedef int TT;
|
|
};
|
|
|
|
void test() {
|
|
f<A>(0); // expected-error {{no matching function}}
|
|
f<B>(0); // expected-error {{no matching function}}
|
|
g<C>(0); // expected-error {{no matching function}}
|
|
h<D>(0); // expected-error {{no matching function}}
|
|
}
|
|
}
|
|
}
|