llvm/clang/test/CXX/drs/cwg4xx.cpp

// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++98 %s -verify=expected,cxx98-14,cxx98-17,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++11 %s -verify=expected,cxx98-14,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++14 %s -verify=expected,cxx98-14,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++17 %s -verify=expected,since-cxx17,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++20 %s -verify=expected,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++23 %s -verify=expected,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++2c %s -verify=expected,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors

#if __cplusplus == 199711L
#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
// cxx98-error@-1 {{variadic macros are a C99 feature}}
#endif

// FIXME: __SIZE_TYPE__ expands to 'long long' on some targets.
__extension__ typedef __SIZE_TYPE__ size_t;

namespace std { struct type_info; }

namespace cwg400 { // cwg400: yes
  struct A { int a; struct a {}; }; // #cwg400-A
  struct B { int a; struct a {}; }; // #cwg400-B
  struct C : A, B { using A::a; struct a b; };
  struct D : A, B { 
    using A::a;
    // FIXME: we should issue a single diagnostic
    using B::a; // #cwg400-using-B-a
    // expected-error@#cwg400-using-B-a {{target of using declaration conflicts with declaration already in scope}}
    //   expected-note@#cwg400-B {{target of using declaration}}
    //   expected-note@#cwg400-A {{conflicting declaration}}
    // expected-error@#cwg400-using-B-a {{target of using declaration conflicts with declaration already in scope}}
    //   expected-note@#cwg400-B {{target of using declaration}}
    //   expected-note@#cwg400-A {{conflicting declaration}}
    struct a b;
  };
  struct E : A, B { struct a b; };
  // expected-error@-1 {{member 'a' found in multiple base classes of different types}}
  //   expected-note@#cwg400-A {{member type 'cwg400::A::a' found by ambiguous name lookup}}
  //   expected-note@#cwg400-B {{member type 'cwg400::B::a' found by ambiguous name lookup}}
}

namespace cwg401 { // cwg401: 2.8
  template<class T, class U = typename T::type> class A : public T {}; // #cwg401-A
  // expected-error@#cwg401-A {{'type' is a private member of 'cwg401::C'}}
  //   expected-note@#cwg402-friend-A-C {{in instantiation of default argument for 'A<C>' required here}}
  //   expected-note@#cwg402-C-type {{implicitly declared private here}}
  // expected-error@#cwg401-A {{'type' is a protected member of 'cwg401::B'}}
  //   expected-note@#cwg402-b {{in instantiation of default argument for 'A<B>' required here}}
  //   expected-note@#cwg402-B-type {{declared protected here}}
  // expected-error@#cwg401-A {{'type' is a private member of 'cwg401::D'}}
  //   expected-note@#cwg402-d {{in instantiation of default argument for 'A<D>' required here}}
  //   expected-note@#cwg402-D-type {{implicitly declared private here}}
  class B {
  protected:
    typedef int type; // #cwg402-B-type
  };

  class C {
    typedef int type; // #cwg402-C-type
    friend class A<C>; // #cwg402-friend-A-C
  };

  class D {
    typedef int type; // #cwg402-D-type
    friend class A<D, int>;
  };

  A<B> *b; // #cwg402-b
  A<D> *d; // #cwg402-d

  struct E {
    template<class T, class U = typename T::type> class A : public T {};
  };
  class F {
    typedef int type;
    friend class E;
  };
  E::A<F> eaf; // ok, default argument is in befriended context

  // FIXME: Why do we get different diagnostics in C++11 onwards here? We seem
  // to not treat the default template argument as a SFINAE context in C++98.
  template<class T, class U = typename T::type> void f(T) {} // #cwg402-f
  // cxx98-error@-1 {{default template arguments for a function template are a C++11 extension}}
  // cxx98-error@-2 {{'type' is a protected member of 'cwg401::B'}}
  //   cxx98-note@-3 {{in instantiation of default argument for 'f<B>' required here}}
  //   cxx98-note@#cwg402-f-b {{while substituting deduced template arguments into function template 'f' [with T = B, U = (no value)]}}
  //   cxx98-note@#cwg402-B-type {{declared protected here}}
  void g(B b) { f(b); } // #cwg402-f-b
  // since-cxx11-error@-1 {{no matching function for call to 'f'}}
  //   since-cxx11-note@#cwg402-f {{candidate template ignored: substitution failure [with T = B, U = typename B::type]: 'type' is a protected member of 'cwg401::B'}}
}

namespace cwg403 { // cwg403: yes
  namespace A {
    struct S {};
    int f(void*);
  }
  template<typename T> struct X {};
  typedef struct X<A::S>::X XS;
  XS *p;
  int k = f(p); // ok, finds A::f, even though type XS is a typedef-name
                // referring to an elaborated-type-specifier naming a
                // injected-class-name, which is about as far from a
                // template-id as we can make it.
}

// cwg404: na
// (NB: also sup 594)

namespace cwg405 { // cwg405: yes
                  // NB: also dup 218
  namespace A {
    struct S {};
    void f(S);
  }
  namespace B {
    struct S {};
    void f(S);
  }

  struct C {
    int f;
    void test1(A::S as) { f(as); }
    // expected-error@-1 {{called object type 'int' is not a function or function pointer}}
    void test2(A::S as) { void f(); f(as); }
    // expected-error@-1 {{too many arguments to function call, expected 0, have 1}}
    //   expected-note@-2 {{'f' declared here}}
    void test3(A::S as) { using A::f; f(as); } // ok
    void test4(A::S as) { using B::f; f(as); } // ok
    void test5(A::S as) { int f; f(as); }
    // expected-error@-1 {{called object type 'int' is not a function or function pointer}}
    void test6(A::S as) { struct f {}; (void) f(as); }
    // expected-error@-1 {{no matching conversion for functional-style cast from 'A::S' to 'f'}}
    //   expected-note@-2 {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'A::S' to 'const f' for 1st argument}}
    //   since-cxx11-note@-3 {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'A::S' to 'f' for 1st argument}}
    //   expected-note@-4 {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}}
  };

  namespace D {
    struct S {};
    struct X { void operator()(S); } f;
  }
  void testD(D::S ds) { f(ds); }
  // expected-error@-1 {{use of undeclared identifier 'f'}}

  namespace E {
    struct S {};
    struct f { f(S); };
  }
  void testE(E::S es) { f(es); }
  // expected-error@-1 {{use of undeclared identifier 'f'}}
}

namespace cwg406 { // cwg406: 2.9
  typedef struct {
    static int n;
    // expected-error@-1 {{static data member 'n' not allowed in anonymous struct}}
  } A;
  typedef union {
    static int n;
    // expected-error@-1 {{static data member 'n' not allowed in anonymous union}}
  } B;
}

namespace cwg407 { // cwg407: 3.8
                  // NB: reused by cwg1894 and cwg2199
  struct S;
  typedef struct S S;
  void f() {
    struct S *p;
    {
      typedef struct S S; // #cwg407-typedef-S
      struct S *p;
      // expected-error@-1 {{typedef 'S' cannot be referenced with the 'struct' specifier}}
      //   expected-note@#cwg407-typedef-S {{declared here}}
    }
  }
  struct S {};

  namespace UsingDir {
    namespace A {
      struct S {}; // #cwg407-A-S
    }
    namespace B {
      typedef int S; // #cwg407-B-S
    }
    namespace C {
      using namespace A;
      using namespace B;
      struct S s;
      // expected-error@-1 {{ambiguous}}
      //   expected-note@#cwg407-A-S {{candidate found by name lookup is 'cwg407::UsingDir::A::S'}}
      //   expected-note@#cwg407-B-S {{candidate found by name lookup is 'cwg407::UsingDir::B::S'}}
    }
    namespace D {
      using A::S;
      typedef struct S S;
      struct S s;
    }
    namespace E {
      // The standard doesn't say whether this is valid. We interpret
      // CWG407 as meaning "if lookup finds both a tag and a typedef with the
      // same type, then it's OK in an elaborated-type-specifier".
      typedef A::S S;
      using A::S;
      struct S s;
    }
    namespace F {
      typedef A::S S;
    }
    // The standard doesn't say what to do in these cases either.
    namespace G {
      using namespace A;
      using namespace F;
      struct S s;
    }
    namespace H {
      using namespace F;
      using namespace A;
      struct S s;
    }
  }
}

namespace cwg408 { // cwg408: 3.4
  template<int N> void g() { static_assert(N != 1, ""); }
  template<> void g<2>() { }

  template<typename T> struct S {
    static int i[];
    void f();
  };
  template<typename T> int S<T>::i[] = { 1 };

  template<typename T> void S<T>::f() {
    g<sizeof (i) / sizeof (int)>();
  }
  template<> int S<int>::i[] = { 1, 2 };
  template void S<int>::f(); // uses g<2>(), not g<1>().


  template<typename T> struct R {
    static int arr[];
    void f();
  };
  template<typename T> int R<T>::arr[1];
  template<typename T> void R<T>::f() {
    static_assert(sizeof(arr) != sizeof(int), "");
  }
  template<> int R<int>::arr[2];
  template void R<int>::f();
}

namespace cwg409 { // cwg409: yes
  template<typename T> struct A {
    typedef int B;
    B b1;
    A::B b2;
    A<T>::B b3;
    A<T*>::B b4;
    // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name A<T *>::B; implicit 'typename' is a C++20 extension}}
  };
}

namespace cwg410 { // cwg410: no
  template<class T> void f(T);
  void g(int);
  namespace M {
    template<class T> void h(T);
    template<class T> void i(T);
    struct A {
      friend void f<>(int);
      friend void h<>(int);
      friend void g(int);
      template<class T> void i(T);
      friend void i<>(int);
    private:
      static void z(); // #cwg410-z
    };

    template<> void h(int) { A::z(); }
    // FIXME: This should be ill-formed. The member A::i<> is befriended,
    // not this function.
    template<> void i(int) { A::z(); }
  }
  template<> void f(int) { M::A::z(); }
  void g(int) { M::A::z(); }
  // expected-error@-1 {{'z' is a private member of 'cwg410::M::A'}}
  //   expected-note@#cwg410-z {{declared private here}}
}

// cwg412 is in cwg412.cpp

namespace cwg413 { // cwg413: yes
  struct S {
    int a;
    int : 17;
    int b;
  };
  S s = { 1, 2, 3 };
  // expected-error@-1 {{excess elements in struct initializer}}

  struct E {};
  struct T { // #cwg413-T
    int a;
    E e;
    int b;
  };
  T t1 = { 1, {}, 2 };
  T t2 = { 1, 2 };
  // expected-error@-1 {{initializer for aggregate with no elements requires explicit braces}}
  //   expected-note@#cwg413-T {{'cwg413::T' declared here}}
}

namespace cwg414 { // cwg414: dup 305
  struct X {};
  void f() {
    X x;
    struct X {};
    x.~X();
  }
}

namespace cwg415 { // cwg415: yes
  template<typename T> void f(T, ...) { T::error; }
  void f(int, int);
  void g() { f(0, 0); } // ok
}

namespace cwg416 { // cwg416: yes
  extern struct A a;
  int &operator+(const A&, const A&);
  int &k = a + a;
  struct A { float &operator+(A&); };
  float &f = a + a;
}

namespace cwg417 { // cwg417: no
  struct A;
  struct cwg417::A {};
  // expected-warning@-1 {{extra qualification on member 'A'}}
  struct B { struct X; };
  struct C : B {};
  struct C::X {};
  // expected-error@-1 {{no struct named 'X' in 'cwg417::C'}}
  struct B::X { struct Y; };
  struct C::X::Y {}; // ok!
  namespace N {
    struct D;
    struct E;
    struct F;
    struct H;
  }
  // FIXME: This is ill-formed.
  using N::D;
  struct cwg417::D {};
  // expected-warning@-1 {{extra qualification on member 'D'}}
  using namespace N;
  struct cwg417::E {};
  // expected-error@-1 {{no struct named 'E' in namespace 'cwg417'}}
  // expected-warning@-2 {{extra qualification on member 'E'}}
  struct N::F {};
  struct G;
  using N::H;
  namespace M {
    struct cwg417::G {};
    // expected-error@-1 {{cannot define or redeclare 'G' here because namespace 'M' does not enclose namespace 'cwg417'}}
    struct cwg417::H {};
    // expected-error@-1 {{cannot define or redeclare 'H' here because namespace 'M' does not enclose namespace 'cwg417'}}
  }
}

namespace cwg418 { // cwg418: no
namespace example1 {
void f1(int, int = 0);
void f1(int = 0, int);

void g() { f1(); }
} // namespace example1

namespace example2 {
namespace A {
void f2(int); // #cwg418-f2
}
namespace B {
using A::f2;
}
namespace A {
void f2(int = 3);
}
void g2() {
  using B::f2;
  f2();
  // expected-error@-1 {{no matching function for call to 'f2'}}
  //   expected-note@#cwg418-f2 {{candidate function not viable: requires 1 argument, but 0 were provided}}
}
} // namespace example2

// example from [over.match.best]/4
namespace example3 {
namespace A {
extern "C" void f(int = 5);
}
namespace B {
extern "C" void f(int = 5);
}

using A::f;
using B::f;

void use() {
  f(3);
  f(); // FIXME: this should fail
}
} // namespace example3
} // namespace cwg418

namespace cwg420 { // cwg420: 9
  template<typename T> struct ptr {
    T *operator->() const;
    T &operator*() const;
  };
  template<typename T, typename P> void test(P p) {
    p->~T();
    p->T::~T();
    (*p).~T();
    (*p).T::~T();
  }
  struct X {};
  template void test<int>(int*);
  template void test<int>(ptr<int>);
  template void test<X>(X*);
  template void test<X>(ptr<X>);

  template<typename T>
  void test2(T p) {
    p->template Y<int>::~Y<int>();
    p->~Y<int>();
    p->template ~Y<int>();
    // expected-error@-1 {{'template' keyword not permitted in destructor name}}
  }
  template<typename T> struct Y {};
  template void test2(Y<int>*);
  template void test2(ptr<Y<int> >);

  void test3(int *p, ptr<int> q) {
    typedef int Int;
    p->~Int();
    q->~Int();
    p->Int::~Int();
    q->Int::~Int();
  }

#if __cplusplus >= 201103L
  template<typename T> using id = T;
  struct A { template<typename T> using id = T; };
  void test4(int *p, ptr<int> q) {
    p->~id<int>();
    q->~id<int>();
    p->id<int>::~id<int>();
    q->id<int>::~id<int>();
    p->template id<int>::~id<int>(); // OK since cwg2292
    q->template id<int>::~id<int>(); // OK since cwg2292
    p->A::template id<int>::~id<int>();
    q->A::template id<int>::~id<int>();
  }
#endif
}

namespace cwg421 { // cwg421: yes
  struct X { X(); int n; int &r; };
  int *p = &X().n;
  // cxx98-error@-1 {{taking the address of a temporary object of type 'int'}}
  // since-cxx11-error@-2 {{cannot take the address of an rvalue of type 'int'}}
  int *q = &X().r;
}

namespace cwg422 { // cwg422: yes
  template<typename T, typename U> void f() {
    typedef T type; // #cwg422-typedef-T
    typedef U type;
    // expected-error@-1 {{typedef redefinition with different types ('char' vs 'int')}}
    //   expected-note@#cwg422-f-int-char {{in instantiation of function template specialization 'cwg422::f<int, char>' requested here}}
    //   expected-note@#cwg422-typedef-T {{previous definition is here}}
  }
  template void f<int, int>();
  template void f<int, char>(); // #cwg422-f-int-char
}

namespace cwg423 { // cwg423: yes
  template<typename T> struct X { operator T&(); };
  void f(X<int> x) { x += 1; }
}

namespace cwg424 { // cwg424: yes
  struct A {
    typedef int N; // #cwg424-N
    typedef int N;
    // expected-error@-1 {{redefinition of 'N'}}
    //   expected-note@#cwg424-N {{previous definition is here}}

    struct X;
    typedef X X; // #cwg424-X
    struct X {};

    struct X *p;
    struct A::X *q;
    X *r;

    typedef X X;
    // expected-error@-1 {{redefinition of 'X'}}
    //   expected-note@#cwg424-X {{previous definition is here}}
  };
  struct B {
    typedef int M;
  };
  struct C : B {
    typedef int M; // #cwg424-M
    typedef int M;
    // expected-error@-1 {{redefinition of 'M'}}
    //   expected-note@#cwg424-M {{previous definition is here}}
  };
}

namespace cwg425 { // cwg425: yes
  struct A { template<typename T> operator T() const; } a;
  float f = 1.0f * a;
  // expected-error@-1 {{use of overloaded operator '*' is ambiguous (with operand types 'float' and 'struct A')}}
  //   expected-note@-2 +{{built-in candidate}}

  template<typename T> struct is_float;
  template<> struct is_float<float> { typedef void type; };

  struct B {
    template<typename T, typename U = typename is_float<T>::type> operator T() const;
    // cxx98-error@-1 {{default template arguments for a function template are a C++11 extension}}
  } b;
  float g = 1.0f * b; // ok
}

namespace cwg427 { // cwg427: yes
  struct B {};
  struct D : public B {
    D(B &) = delete; // #cwg427-D
    // cxx98-error@-1 {{deleted function definitions are a C++11 extension}}
  };

  extern D d1;
  B &b = d1;
  const D &d2 = static_cast<const D&>(b);
  const D &d3 = (const D&)b;
  const D &d4(b);
  // expected-error@-1 {{conversion function from 'B' to 'const D' invokes a deleted function}}
  //   expected-note@#cwg427-D {{'D' has been explicitly marked deleted here}}
}

namespace cwg428 { // cwg428: yes
  template<typename T> T make();
  extern struct X x; // #cwg428-X
  void f() {
    throw void();
    // expected-error@-1 {{cannot throw}}
    throw make<void*>();
    throw make<const volatile void*>();
    throw x;
    // expected-error@-1 {{cannot throw}}
    //   expected-note@#cwg428-X {{forward declaration of 'cwg428::X'}}
    throw make<X&>();
    // expected-error@-1 {{cannot throw}}
    //   expected-note@#cwg428-X {{forward declaration of 'cwg428::X'}}
    throw make<X*>();
    // expected-error@-1 {{cannot throw}}
    //   expected-note@#cwg428-X {{forward declaration of 'cwg428::X'}}
    throw make<const volatile X&>();
    // expected-error@-1 {{cannot throw}}
    //   expected-note@#cwg428-X {{forward declaration of 'cwg428::X'}}
    throw make<const volatile X*>();
    // expected-error@-1 {{cannot throw}}
    //   expected-note@#cwg428-X {{forward declaration of 'cwg428::X'}}
  }
}

namespace cwg429 { // cwg429: 2.8 c++11
  // FIXME: This rule is obviously intended to apply to C++98 as well.
  struct A {
    static void *operator new(size_t, size_t);
    static void operator delete(void*, size_t); // #cwg429-delete
  } *a = new (0) A;
  // since-cxx11-error@-1 {{'new' expression with placement arguments refers to non-placement 'operator delete'}}
  //   since-cxx11-note@#cwg429-delete {{here}}
  struct B {
    static void *operator new(size_t, size_t);
    static void operator delete(void*);
    static void operator delete(void*, size_t);
  } *b = new (0) B; // ok, second delete is not a non-placement deallocation function
}

namespace cwg430 { // cwg430: yes c++11
  // resolved by n2239
  // FIXME: This should apply in C++98 too.
  void f(int n) {
    int a[] = { n++, n++, n++ };
    // cxx98-warning@-1 {{multiple unsequenced modifications to 'n'}}
  }
}

namespace cwg431 { // cwg431: yes
  struct A {
    template<typename T> T *get();
    template<typename T> struct B {
      template<typename U> U *get();
    };
  };

  template<typename T> void f(A a) {
    a.get<A>()->get<T>();
    a.get<T>()
        ->get<T>();
        // expected-error@-1 {{use 'template' keyword to treat 'get' as a dependent template name}}
    a.get<T>()->template get<T>();
    a.A::get<T>();
    A::B<int> *b = a.get<A::B<int> >();
    b->get<int>();
    b->A::B<int>::get<int>();
    b->A::B<int>::get<T>();
    b->A::B<T>::get<int>();
    // expected-error@-1 {{use 'template' keyword to treat 'get' as a dependent template name}}
    b->A::B<T>::template get<int>();
    b->A::B<T>::get<T>();
    // expected-error@-1 {{use 'template' keyword to treat 'get' as a dependent template name}}
    b->A::B<T>::template get<T>();
    A::B<T> *c = a.get<A::B<T> >();
    c->get<int>();
    // expected-error@-1 {{use 'template' keyword to treat 'get' as a dependent template name}}
    c->template get<int>();
  }
}

namespace cwg432 { // cwg432: 3.0
  template<typename T> struct A {};
  template<typename T> struct B : A<B> {};
  // expected-error@-1 {{use of class template 'B' requires template arguments}}
  //   expected-note@-2 {{template is declared here}}
  template<typename T> struct C : A<C<T> > {};
#if __cplusplus >= 201103L
  template<typename T> struct D : decltype(A<D>()) {};
  // since-cxx11-error@-1 {{use of class template 'D' requires template arguments}}
  //   since-cxx11-note@-2 {{template is declared here}}
#endif
}

namespace cwg433 { // cwg433: yes
  template<class T> struct S {
    void f(union U*);
  };
  U *p;
  template<class T> void S<T>::f(union U*) {}

  S<int> s;
}

namespace cwg434 { // cwg434: sup 2352
  void f() {
    const int ci = 0;
    int *pi = 0;
    const int *&rpci = pi;
    // expected-error@-1 {{binding reference of type 'const int *' to value of type 'int *' not permitted due to incompatible qualifiers}}
    const int * const &rcpci = pi; // OK
    rpci = &ci;
    *pi = 1;
  }

#if __cplusplus >= 201103L
  int *pi = 0;
  const int * const &rcpci = pi;
  static_assert(&rcpci == &pi, "");
#endif
}

// cwg435: na

namespace cwg436 { // cwg436: yes
  enum E { f }; // #cwg436-f
  void f();
  // expected-error@-1 {{redefinition of 'f' as different kind of symbol}}
  //   expected-note@#cwg436-f {{previous definition is here}}
}

namespace cwg437 { // cwg437: sup 1308
  // This is superseded by 1308, which is in turn superseded by 1330,
  // which restores this rule.
  template<typename U> struct T : U {};
  struct S {
    void f() throw(S);
    // since-cxx17-error@-1 {{ISO C++17 does not allow dynamic exception specifications}}
    //   since-cxx17-note@-2 {{use 'noexcept(false)' instead}}
    void g() throw(T<S>);
    // since-cxx17-error@-1 {{ISO C++17 does not allow dynamic exception specifications}}
    //   since-cxx17-note@-2 {{use 'noexcept(false)' instead}}
    struct U;
    void h() throw(U);
    // since-cxx17-error@-1 {{ISO C++17 does not allow dynamic exception specifications}}
    //   since-cxx17-note@-2 {{use 'noexcept(false)' instead}}
    struct U {};
  };
}

// cwg438 is in cwg438.cpp
// cwg439 is in cwg439.cpp
// cwg441 is in cwg441.cpp
// cwg442: sup 348
// cwg443: na

namespace cwg444 { // cwg444: yes
  struct D;
  struct B { // #cwg444-B
    D &operator=(D &) = delete; // #cwg444-deleted
    // cxx98-error@-1 {{deleted function definitions are a C++11 extension}}
  };
  struct D : B { // #cwg444-D
    using B::operator=;
  } extern d;
  void f() {
    d = d;
    // expected-error@-1 {{overload resolution selected deleted operator '='}}
    //   expected-note@#cwg444-deleted {{candidate function has been explicitly deleted}}
    //   expected-note@#cwg444-D {{candidate function (the implicit copy assignment operator)}}
    //   expected-note@#cwg444-B {{candidate function (the implicit copy assignment operator)}}
    //   since-cxx11-note@#cwg444-B {{candidate function (the implicit move assignment operator) not viable: expects an rvalue for 1st argument}}
    //   since-cxx11-note@#cwg444-D {{candidate function (the implicit move assignment operator) not viable: expects an rvalue for 1st argument}}
  }
}

namespace cwg445 { // cwg445: 3.2
  class A { void f(); }; // #cwg445-f
  struct B {
    friend void A::f();
    // expected-error@-1 {{friend function 'f' is a private member of 'cwg445::A'}}
    //   expected-note@#cwg445-f {{implicitly declared private here}}
  };
}

namespace cwg446 { // cwg446: 2.8
  struct C;
  struct A {
    A();
    A(const A&) = delete; // #cwg446-deleted
    // cxx98-error@-1 {{deleted function definitions are a C++11 extension}}
    A(const C&);
  };
  struct C : A {};
  void f(A a, bool b, C c) {
    void(b ? a : a);
    b ? A() : a;
    // expected-error@-1 {{call to deleted constructor of 'A'}}
    //   expected-note@#cwg446-deleted {{'A' has been explicitly marked deleted here}}
    b ? a : A();
    // expected-error@-1 {{call to deleted constructor of 'A'}}
    //   expected-note@#cwg446-deleted {{'A' has been explicitly marked deleted here}}
    b ? A() : A();
    // cxx98-14-error@-1 {{call to deleted constructor of 'A'}}
    //   expected-note@#cwg446-deleted {{'A' has been explicitly marked deleted here}}

    void(b ? a : c);
    b ? a : C();
    // expected-error@-1 {{call to deleted constructor of 'A'}}
    //   cxx98-14-note@#cwg446-deleted {{'A' has been explicitly marked deleted here}}
    b ? c : A();
    // cxx98-14-error@-1 {{call to deleted constructor of 'A'}}
    //   cxx98-14-note@#cwg446-deleted {{'A' has been explicitly marked deleted here}}
    b ? A() : C();
    // cxx98-14-error@-1 {{call to deleted constructor of 'A'}}
    //   cxx98-14-note@#cwg446-deleted {{'A' has been explicitly marked deleted here}}
  }
}

namespace cwg447 { // cwg447: yes
  struct A { int n; int a[4]; };
  template<int> struct U {
    typedef int type;
    template<typename V> static void h();
  };
  template<typename T> U<sizeof(T)> g(T);
  template<typename T, int N> void f(int n) {
    // ok, not type dependent
    g(__builtin_offsetof(A, n)).h<int>();
    g(__builtin_offsetof(T, n)).h<int>();
    // value dependent if first argument is a dependent type
    U<__builtin_offsetof(A, n)>::type a;
    // FIXME: instead of ";", we should be suggesting "typename"
    U<__builtin_offsetof(T, n)>::type b;
    // expected-error@-1 {{expected ';' after expression}}
    // expected-error@-2 {{use of undeclared identifier 'b'}}
    // as an extension, we allow the member-designator to include array indices
    g(__builtin_offsetof(A, a[0])).h<int>();
    g(__builtin_offsetof(A, a[N])).h<int>();
    U<__builtin_offsetof(A, a[0])>::type c;
    // FIXME: instead of ";", we should be suggesting "typename"
    U<__builtin_offsetof(A, a[N])>::type d;
    // expected-error@-1 {{expected ';' after expression}}
    // expected-error@-2 {{use of undeclared identifier 'd'}}
  }
}

namespace cwg448 { // cwg448: 2.8
  template<typename T = int> void f(int); // #cwg448-f-int
  // cxx98-error@-1 {{default template arguments for a function template are a C++11 extension}}
  template<typename T> void g(T t) {
    f<T>(t);
    // expected-error@-1 {{call to function 'f' that is neither visible in the template definition nor found by argument-dependent lookup}}
    //   expected-note@#cwg448-g {{in instantiation of function template specialization 'cwg448::g<cwg448::HideFromADL::X>' requested here}}
    //   expected-note@#cwg448-f-T {{'f' should be declared prior to the call site or in namespace 'cwg448::HideFromADL'}}
    cwg448::f(t);
    // expected-error@-1 {{no matching function for call to 'f'}}
    //   expected-note@#cwg448-f-int {{candidate function template not viable: no known conversion from 'cwg448::HideFromADL::X' to 'int' for 1st argument}}
  }
  template<typename T> void f(T); // #cwg448-f-T
  namespace HideFromADL { struct X {}; }
  template void g(int); // ok
  template void g(HideFromADL::X); // #cwg448-g
}

// cwg449: na

namespace cwg450 { // cwg450: yes
  typedef int A[3];
  void f1(const A &);
  void f2(A &); // #cwg450-f2
  struct S { A n; };
  void g() {
    f1(S().n);
    f2(S().n);
    // expected-error@-1 {{no matching function for call to 'f2'}}}
    //   expected-note@#cwg450-f2 {{candidate function not viable: expects an lvalue for 1st argument}}
  }
#if __cplusplus >= 201103L
  void h() {
    f1(A{});
    f2(A{});
    // expected-error@-1 {{no matching function for call to 'f2'}}}
    //   expected-note@#cwg450-f2 {{candidate function not viable: expects an lvalue for 1st argument}}
  }
#endif
}

namespace cwg451 { // cwg451: yes
  const int a = 1 / 0;
  // expected-warning@-1 {{division by zero is undefined}}
  const int b = 1 / 0; // #cwg451-b
  // expected-warning@-1 {{division by zero is undefined}}
  static_assert(b, "");
  // expected-error@-1 {{expression is not an integral constant expression}}
  //   expected-note@-2 {{initializer of 'b' is not a constant expression}}
  //   expected-note@#cwg451-b {{declared here}}
}

namespace cwg452 { // cwg452: yes
  struct A {
    int a, b, c;
    A *p;
    int f();
    A() : a(f()), b(this->f() + a), c(this->a), p(this) {}
  };
}

// cwg454 FIXME write a codegen test

namespace cwg456 { // cwg456: yes
  // sup 903 c++11
  const int null = 0;
  void *p = null;
  // cxx98-warning@-1 {{expression which evaluates to zero treated as a null pointer constant of type 'void *'}}
  // since-cxx11-error@-2 {{cannot initialize a variable of type 'void *' with an lvalue of type 'const int'}}

  const bool f = false;
  void *q = f;
  // cxx98-warning@-1 {{initialization of pointer of type 'void *' to null from a constant boolean}}
  // since-cxx11-error@-2 {{cannot initialize a variable of type 'void *' with an lvalue of type 'const bool'}}
}

namespace cwg457 { // cwg457: yes
  const int a = 1;
  const volatile int b = 1;
  static_assert(a, "");
  static_assert(b, "");
  // expected-error@-1 {{expression is not an integral constant expression}}
  //   expected-note@-2 {{read of volatile-qualified type 'const volatile int' is not allowed in a constant expression}}

  enum E {
    ea = a,
    eb = b
    // expected-error@-1 {{expression is not an integral constant expression}}
    //   expected-note@-2 {{read of volatile-qualified type 'const volatile int' is not allowed in a constant expression}}
  };
}

namespace cwg458 { // cwg458: 11
  struct A {
    int T;
    int f();
    template<typename> int g();
  };

  template<typename> struct B : A {
    int f();
    template<typename> int g();
    template<typename> int h();
  };

  int A::f() {
    return T;
  }
  template<typename T> // #cwg458-g-T
  int A::g() {
    return T;
    // expected-error@-1 {{'T' does not refer to a value}}
    //   expected-note@#cwg458-g-T {{declared here}}
  }

  template<typename T>
  int B<T>::f() {
    return T;
  }
  template<typename T>
  template<typename U>
  int B<T>::g() {
    return T;
  }
  template<typename U>
  template<typename T> // #cwg458-h-T
  int B<U>::h() {
    return T;
    // expected-error@-1 {{'T' does not refer to a value}}
    //   expected-note@#cwg458-h-T {{declared here}}
  }
}

namespace cwg460 { // cwg460: yes
  namespace X { namespace Q { int n; } }
  namespace Y {
    using X;
    // expected-error@-1 {{using declaration requires a qualified name}}
    using cwg460::X;
    // expected-error@-1 {{using declaration cannot refer to a namespace}}
    // expected-note@-2 {{did you mean 'using namespace'?}}
    using X::Q;
    // expected-error@-1 {{using declaration cannot refer to a namespace}}
    // expected-note@-2 {{did you mean 'using namespace'?}}
  }
}

// cwg461: na
// cwg462 is in cwg462.cpp
// cwg463: na
// cwg464: na
// cwg465: na

namespace cwg466 { // cwg466: 2.8
typedef int I;
typedef const int CI;
typedef volatile int VI;
void g(int a, CI b, VI c) {
// since-cxx20-warning@-1 {{volatile-qualified parameter type 'VI' (aka 'volatile int') is deprecated}}
  a.~I();
  a.~CI();
  a.~VI();
  a.I::~I();
  a.CI::~CI();
  a.VI::~VI();

  a.CI::~VI(); // allowed by changes to [expr.id.prim.qual]/2 introduced in P1131R2

  b.~I();
  b.~CI();
  b.~VI();
  b.I::~I();
  b.CI::~CI();
  b.VI::~VI();

  c.~I();
  c.~CI();
  c.~VI();
  c.I::~I();
  c.CI::~CI();
  c.VI::~VI();
}
}

namespace cwg467 { // cwg467: yes
  int stuff();

  int f() {
    static bool done;
    if (done)
      goto later;
    static int k = stuff();
    done = true;
  later:
    return k;
  }
  int g() {
    goto later;
    // expected-error@-1 {{cannot jump from this goto statement to its label}}
    //   expected-note@#cwg467-k {{jump bypasses variable initialization}}
    int k = stuff(); // #cwg467-k
  later:
    return k;
  }
}

namespace cwg468 { // cwg468: yes c++11
  // FIXME: Should we allow this in C++98 too?
  template<typename> struct A {
    template<typename> struct B {
      static int C;
    };
  };
  int k = cwg468::template A<int>::template B<char>::C;
  // cxx98-error@-1 {{'template' keyword outside of a template}}
  // cxx98-error@-2 {{'template' keyword outside of a template}}
}

namespace cwg469 { // cwg469: no
  template<typename T> struct X; // #cwg469-X
  template<typename T> struct X<const T> {};
  X<int&> x;
  // expected-error@-1 {{implicit instantiation of undefined template 'cwg469::X<int &>'}}
  //   expected-note@#cwg469-X {{template is declared here}}
}

namespace cwg470 { // cwg470: yes
  template<typename T> struct A {
    struct B {};
  };
  template<typename T> struct C {
  };

  template struct A<int>; // #cwg470-A-int
  template struct A<int>::B;
  // expected-error@-1 {{duplicate explicit instantiation of 'B'}}
  //   expected-note@#cwg470-A-int {{previous explicit instantiation is here}}

  // ok, instantiating C<char> doesn't instantiate base class members.
  template struct A<char>;
  template struct C<char>;
}

namespace cwg471 { // cwg471: 2.8
  struct A { int n; };
  struct B : private virtual A {};
  struct C : protected virtual A {};
  struct D : B, C { int f() { return n; } };
  struct E : private virtual A {
    using A::n;
  };
  struct F : E, B { int f() { return n; } };
  struct G : virtual A {
  private:
    using A::n; // #cwg471-G-using
  };
  struct H : B, G { int f() { return n; } };
  // expected-error@-1 {{'n' is a private member of 'cwg471::G'}}
  //   expected-note@#cwg471-G-using {{declared private here}}
}

namespace cwg472 { // cwg472: no drafting 2011-04
struct B {
  int i; // #cwg472-i
};
struct I : protected B {}; // #cwg472-struct-I
struct D : public I {
  void f(I *ip) {
    ip->i = 0;
    // expected-error@-1 {{'i' is a protected member of 'cwg472::B'}}
    //   expected-note@#cwg472-struct-I {{constrained by protected inheritance here}}
    //   expected-note@#cwg472-i {{member is declared here}}
    B *bp = ip;
    bp->i = 5;
  }
};
}

namespace cwg474 { // cwg474: 3.4
  namespace N {
    struct S {
      void f();
    };
  }
  void N::S::f() {
    void g(); // #cwg474-g
  }
  int g();
  namespace N {
    int g();
    // expected-error@-1 {{functions that differ only in their return type cannot be overloaded}}
    //   expected-note@#cwg474-g {{previous declaration is here}}
  }
}

// cwg475 FIXME write a libc++abi test

namespace cwg477 { // cwg477: 3.5
  struct A {
    explicit A();
    virtual void f();
  };
  struct B {
    friend explicit A::A();
    // expected-error@-1 {{'explicit' is invalid in friend declarations}}
    friend virtual void A::f();
    // expected-error@-1 {{'virtual' is invalid in friend declarations}}
  };
  explicit A::A() {}
  // expected-error@-1 {{can only be specified inside the class definition}}
  virtual void A::f() {}
  // expected-error@-1 {{can only be specified inside the class definition}}
}

namespace cwg478 { // cwg478: yes
  struct A { virtual void f() = 0; }; // #cwg478-f
  void f(A *a);
  void f(A a[10]);
  // expected-error@-1 {{array of abstract class type 'A'}}
  //   expected-note@#cwg478-f {{unimplemented pure virtual method 'f' in 'A'}}
}

namespace cwg479 { // cwg479: 2.8
  struct S {
    S();
  private:
    S(const S&); // #cwg479-S-copy-ctor
    ~S(); // #cwg479-S-dtor
  };
  void f() {
    throw S();
    // expected-error@-1 {{temporary of type 'S' has private destructor}}
    //   expected-note@#cwg479-S-dtor {{declared private here}}
    // expected-error@-3 {{exception object of type 'S' has private destructor}}
    //   expected-note@#cwg479-S-dtor {{declared private here}}
    // cxx98-error@-5 {{C++98 requires an accessible copy constructor for class 'cwg479::S' when binding a reference to a temporary; was private}}
    //   cxx98-note@#cwg479-S-copy-ctor {{declared private here}}
    // cxx98-14-error@-7 {{calling a private constructor of class 'cwg479::S'}}
    //   cxx98-14-note@#cwg479-S-copy-ctor {{declared private here}}
  }
  void g() {
    S s;
    // expected-error@-1 {{variable of type 'S' has private destructor}}
    //   expected-note@#cwg479-S-dtor {{declared private here}}
    throw s;
    // expected-error@-1 {{exception object of type 'S' has private destructor}}
    //   expected-note@#cwg479-S-dtor {{declared private here}}
    // expected-error@-3 {{calling a private constructor of class 'cwg479::S'}}
    //   expected-note@#cwg479-S-copy-ctor {{declared private here}}
  }
  void h() {
    try {
      f();
      g();
    } catch (S s) {
      // expected-error@-1 {{calling a private constructor of class 'cwg479::S'}}
      //   expected-note@#cwg479-S-copy-ctor {{declared private here}}
      // expected-error@-3 {{variable of type 'S' has private destructor}}
      //   expected-note@#cwg479-S-dtor {{declared private here}}
    }
  }
}

namespace cwg480 { // cwg480: yes
  struct A { int n; };
  struct B : A {};
  struct C : virtual B {};
  struct D : C {};

  int A::*a = &A::n;
  int D::*b = a;
  // expected-error@-1 {{conversion from pointer to member of class 'cwg480::A' to pointer to member of class 'cwg480::D' via virtual base 'cwg480::B' is not allowed}}

  extern int D::*c;
  int A::*d = static_cast<int A::*>(c);
  // expected-error@-1 {{conversion from pointer to member of class 'cwg480::D' to pointer to member of class 'cwg480::A' via virtual base 'cwg480::B' is not allowed}}

  D *e;
  A *f = e;
  D *g = static_cast<D*>(f);
  // expected-error@-1 {{cannot cast 'cwg480::A *' to 'D *' via virtual base 'cwg480::B'}}

  extern D &i;
  A &j = i;
  D &k = static_cast<D&>(j);
  // expected-error@-1 {{cannot cast 'A' to 'D &' via virtual base 'cwg480::B'}}
}

namespace cwg481 { // cwg481: 2.8
  template<class T, T U> class A { T *x; };
  T *x;
  // expected-error@-1 {{unknown type name 'T'}}

  template<class T *U> class B { T *x; };
  T *y; // ok

  struct C {
    template<class T> void f(class D *p);
  };
  D *z; // ok

  template<typename A = C, typename C = A> struct E {
    void f() {
      typedef ::cwg481::C c; // #cwg481-c
      typedef C c;
      // expected-error@-1 {{typedef redefinition with different types ('int' vs '::cwg481::C')}}
      //   expected-note@#cwg481-E-int {{in instantiation of member function 'cwg481::E<int>::f' requested here}}
      //   expected-note@#cwg481-c {{previous definition is here}}
    }
  };
  template struct E<>; // ok
  template struct E<int>; // #cwg481-E-int

  template<template<typename U_no_typo_correction> class A,
           A<int> *B,
           U_no_typo_correction *C>
           // expected-error@-1 {{unknown type name 'U_no_typo_correction'}}
  struct F {
    U_no_typo_correction *x;
    // expected-error@-1 {{unknown type name 'U_no_typo_correction'}}
  };

  template<template<class H *> class> struct G {
    H *x;
  };
  H *q;

  typedef int N;
  template<N X, typename N, template<N Y> class T> struct I;
  template<char*> struct J;
  I<123, char*, J> *j;
}

namespace cwg482 { // cwg482: 3.5
  extern int a;
  void f();

  int cwg482::a = 0;
  // expected-warning@-1 {{extra qualification on member 'a'}}
  void cwg482::f() {}
  // expected-warning@-1 {{extra qualification on member 'f'}}

  inline namespace X {
  // cxx98-error@-1 {{inline namespaces are a C++11 feature}}
    extern int b;
    void g();
    struct S;
  }
  int cwg482::b = 0;
  // expected-warning@-1 {{extra qualification on member 'b'}}
  void cwg482::g() {}
  // expected-warning@-1 {{extra qualification on member 'g'}}
  struct cwg482::S {};
  // expected-warning@-1 {{extra qualification on member 'S'}}

  void cwg482::f();
  // expected-warning@-1 {{extra qualification on member 'f'}}
  void cwg482::g();
  // expected-warning@-1 {{extra qualification on member 'g'}}

  // FIXME: The following are valid in CWG482's wording, but these are bugs in
  // the wording which we deliberately don't implement.
  namespace N { typedef int type; }
  typedef int N::type;
  // expected-error@-1 {{typedef declarator cannot be qualified}}
  struct A {
    struct B;
    struct A::B {};
    // expected-error@-1 {{extra qualification on member 'B'}}

#if __cplusplus >= 201103L
    enum class C;
    enum class A::C {};
    // expected-error@-1 {{extra qualification on member 'C'}}
#endif
  };
}

namespace cwg483 { // cwg483: yes
  namespace climits {
    static_assert(__SCHAR_MAX__ >= 127, "");
    static_assert(__SHRT_MAX__ >= 32767, "");
    static_assert(__INT_MAX__ >= 32767, "");
    static_assert(__LONG_MAX__ >= 2147483647, "");
    static_assert(__LONG_LONG_MAX__ >= 9223372036854775807, "");
  }
  namespace cstdint {
    static_assert(__PTRDIFF_WIDTH__ >= 16, "");
    static_assert(__SIG_ATOMIC_WIDTH__ >= 8, "");
    static_assert(__SIZE_WIDTH__ >= 16, "");
    static_assert(__WCHAR_WIDTH__ >= 8, "");
    static_assert(__WINT_WIDTH__ >= 16, "");
  }
}

namespace cwg484 { // cwg484: yes
  struct A {
    A();
    void f();
  };
  typedef const A CA;
  void CA::f() {
    this->~CA();
    this->CA::~A();
    this->CA::A::~A();
  }
  CA::A() {}

  struct B : CA {
    B() : CA() {}
    void f() { return CA::f(); }
  };

  struct C;
  typedef C CT; // #cwg484-typedef-CT
  struct CT {};
  // expected-error@-1 {{definition of type 'CT' conflicts with typedef of the same name}}
  //   expected-note@#cwg484-typedef-CT {{'CT' declared here}}

  namespace N {
    struct D;
    typedef D DT; // #cwg484-typedef-DT
  }
  struct N::DT {};
  // expected-error@-1 {{definition of type 'DT' conflicts with typedef of the same name}}
  //   expected-note@#cwg484-typedef-DT {{'DT' declared here}}

  typedef struct {
    S();
    // expected-error@-1 {{a type specifier is required for all declarations}}
  } S;
}

namespace cwg485 { // cwg485: yes
  namespace N {
    struct S {};
    int operator+(S, S);
    template<typename T> int f(S);
  }
  template<typename T> int f();

  N::S s;
  int a = operator+(s, s);
  int b = f<int>(s);
}

namespace cwg486 { // cwg486: yes
  template<typename T> T f(T *); // #cwg486-f
  int &f(...);

  void g();
  int n[10];

  void h() {
    int &a = f(&g);
    int &b = f(&n);
    f<void()>(&g);
    // expected-error@-1 {{no matching function for call to 'f'}}
    //   expected-note@#cwg486-f {{candidate template ignored: substitution failure [with T = void ()]: function cannot return function type 'void ()'}}
    f<int[10]>(&n);
    // expected-error@-1 {{no matching function for call to 'f'}}
    //   expected-note@#cwg486-f {{candidate template ignored: substitution failure [with T = int[10]]: function cannot return array type 'int[10]'}}
  }
}

namespace cwg487 { // cwg487: yes
  enum E { e };
  int operator+(int, E); // #cwg487-operator-plus
  static_assert(4 + e, "");
  // expected-error@-1 {{expression is not an integral constant expression}}
  //   since-cxx11-note@-2 {{non-constexpr function 'operator+' cannot be used in a constant expression}}
  //   since-cxx11-note@#cwg487-operator-plus {{declared here}}
}

namespace cwg488 { // cwg488: yes c++11
  template <typename T> void f(T);
  void f(int);
  void g() {
    // FIXME: It seems CWG thought this should be a SFINAE failure prior to
    // allowing local types as template arguments. In C++98, we should either
    // allow local types as template arguments or treat this as a SFINAE
    // failure.
    enum E { e };
    f(e);
    // cxx98-error@-1 {{template argument uses local type 'E'}}
  }
}

// cwg489: na

namespace cwg490 { // cwg490: 2.8
  template<typename T> struct X {};

  struct A {
    typedef int T;
    struct K {}; // #cwg490-k

    int f(T);
    int g(T);
    int h(X<T>);
    int X<T>::*i(); // #cwg490-i
    int K::*j();

    template<typename T> T k();

    operator X<T>();
  };

  struct B {
    typedef char T;
    typedef int U;
    friend int A::f(T);
    friend int A::g(U);
    friend int A::h(X<T>);

    // FIXME: Per this DR, these two are valid! That is another defect
    // (no number yet...) which will eventually supersede this one.
    friend int X<T>::*A::i();
    // expected-error@-1 {{return type of out-of-line definition of 'cwg490::A::i' differs from that in the declaration}}
    //   expected-note@#cwg490-i {{previous declaration is here}}
    friend int K::*A::j();
    // expected-error@-1 {{use of undeclared identifier 'K'; did you mean 'A::K'?}}
    //   expected-note@#cwg490-k {{'A::K' declared here}}

    // ok, lookup finds B::T, not A::T, so return type matches
    friend char A::k<T>();
    friend int A::k<U>();

    // A conversion-type-id in a conversion-function-id is always looked up in
    // the class of the conversion function first.
    friend A::operator X<T>();
  };
}

namespace cwg491 { // cwg491: dup 413
  struct A {} a, b[3] = { a, {} };
  A c[2] = { a, {}, b[1] };
  // expected-error@-1 {{excess elements in array initializer}}
}

// cwg492 is in cwg492.cpp

namespace cwg493 { // cwg493: dup 976
  struct X {
    template <class T> operator const T &() const;
  };
  void f() {
    if (X()) {
    }
  }
}

namespace cwg494 { // cwg494: dup 372
  class A {
    class B {};
    friend class C;
  };
  class C : A::B {
    A::B x;
    class D : A::B {
      A::B y;
    };
  };
}

namespace cwg495 { // cwg495: 3.5
  template<typename T>
  struct S {
    operator int() { return T::error; }
    template<typename U> operator U();
  };
  S<int> s;
  long n = s;

  template<typename T>
  struct S2 {
    template<typename U> operator U();
    operator int() { return T::error; }
  };
  S2<int> s2;
  long n2 = s2;
}

namespace cwg496 { // cwg496: sup 2094
  struct A { int n; };
  struct B { volatile int n; };
  static_assert(__is_trivially_copyable(const int), "");
  // This checks the cwg2094 behavior, not cwg496
  static_assert(__is_trivially_copyable(volatile int), "");
  static_assert(__is_trivially_constructible(A, const A&), "");
  static_assert(__is_trivially_constructible(B, const B&), "");
  static_assert(__is_trivially_assignable(A, const A&), "");
  static_assert(__is_trivially_assignable(B, const B&), "");
}

namespace cwg497 { // cwg497: sup 253
  void before() {
    struct S {
      mutable int i;
    };
    const S cs;
    int S::*pm = &S::i;
    cs.*pm = 88;
    // expected-error@-1 {{read-only variable is not assignable}}
  }

  void after() {
    struct S {
      S() : i(0) {}
      mutable int i;
    };
    const S cs;
    int S::*pm = &S::i;
    cs.*pm = 88;
    // expected-error@-1 {{read-only variable is not assignable}}
  }
}

namespace cwg499 { // cwg499: yes
  extern char str[];
  void f() { throw str; }
}