13003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -fcxx-exceptions %s
26180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith
36180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith// An explicitly-defaulted function may be declared constexpr only if it would
46180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith// have been implicitly declared as constexpr.
56180245e9f63d2927b185ec251fb75aba30f1cacRichard Smithstruct S1 {
66180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  constexpr S1() = default; // expected-error {{defaulted definition of default constructor is not constexpr}}
76180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  constexpr S1(const S1&) = default;
86180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  constexpr S1(S1&&) = default;
9840462670ba7a6bc26265a2306b35f2f0f01f51cRichard Smith  constexpr S1 &operator=(const S1&) const = default; // expected-error {{explicitly-defaulted copy assignment operator may not have}}
10840462670ba7a6bc26265a2306b35f2f0f01f51cRichard Smith  constexpr S1 &operator=(S1&&) const = default; // expected-error {{explicitly-defaulted move assignment operator may not have}}
116180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  constexpr ~S1() = default; // expected-error {{destructor cannot be marked constexpr}}
126180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  int n;
136180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith};
146180245e9f63d2927b185ec251fb75aba30f1cacRichard Smithstruct NoCopyMove {
156180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  constexpr NoCopyMove() {}
166180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  NoCopyMove(const NoCopyMove&);
176180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  NoCopyMove(NoCopyMove&&);
186180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith};
196180245e9f63d2927b185ec251fb75aba30f1cacRichard Smithstruct S2 {
206180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  constexpr S2() = default;
216180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  constexpr S2(const S2&) = default; // expected-error {{defaulted definition of copy constructor is not constexpr}}
226180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  constexpr S2(S2&&) = default; // expected-error {{defaulted definition of move constructor is not constexpr}}
236180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  NoCopyMove ncm;
246180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith};
256180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith
266180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith// If a function is explicitly defaulted on its first declaration
276180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith//   -- it is implicitly considered to be constexpr if the implicit declaration
286180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith//      would be
296180245e9f63d2927b185ec251fb75aba30f1cacRichard Smithstruct S3 {
305121781d756e7814168b4255a57545d5ca497ec3Aaron Ballman  S3() = default;
316180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  S3(const S3&) = default;
326180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  S3(S3&&) = default;
336180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  constexpr S3(int n) : n(n) {}
346180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  int n;
356180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith};
366180245e9f63d2927b185ec251fb75aba30f1cacRichard Smithconstexpr S3 s3a = S3(0);
376180245e9f63d2927b185ec251fb75aba30f1cacRichard Smithconstexpr S3 s3b = s3a;
38e653ba2f3b6d993b5d410554c12416c03ec7775bRichard Smithconstexpr S3 s3c = S3();
39176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesconstexpr S3 s3d; // expected-error {{default initialization of an object of const type 'const S3' without a user-provided default constructor}} expected-note{{add an explicit initializer to initialize 's3d'}}
406180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith
416180245e9f63d2927b185ec251fb75aba30f1cacRichard Smithstruct S4 {
426180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  S4() = default;
436180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  S4(const S4&) = default; // expected-note {{here}}
446180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  S4(S4&&) = default; // expected-note {{here}}
456180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  NoCopyMove ncm;
466180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith};
475121781d756e7814168b4255a57545d5ca497ec3Aaron Ballmanconstexpr S4 s4a{}; // ok
486180245e9f63d2927b185ec251fb75aba30f1cacRichard Smithconstexpr S4 s4b = S4(); // expected-error {{constant expression}} expected-note {{non-constexpr constructor}}
496180245e9f63d2927b185ec251fb75aba30f1cacRichard Smithconstexpr S4 s4c = s4a; // expected-error {{constant expression}} expected-note {{non-constexpr constructor}}
506180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith
516180245e9f63d2927b185ec251fb75aba30f1cacRichard Smithstruct S5 {
526180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  constexpr S5();
536180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith  int n = 1, m = n + 3;
546180245e9f63d2927b185ec251fb75aba30f1cacRichard Smith};
556180245e9f63d2927b185ec251fb75aba30f1cacRichard Smithconstexpr S5::S5() = default;
566180245e9f63d2927b185ec251fb75aba30f1cacRichard Smithstatic_assert(S5().m == 4, "");
573003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith
583003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith
593003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith// An explicitly-defaulted function may have an exception specification only if
603003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith// it is compatible with the exception specification on an implicit declaration.
613003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smithstruct E1 {
623003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E1() noexcept = default;
633003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E1(const E1&) noexcept = default;
643003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E1(E1&&) noexcept = default;
653003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E1 &operator=(const E1&) noexcept = default;
663003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E1 &operator=(E1&&) noexcept = default;
673003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  ~E1() noexcept = default;
683003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith};
693003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smithstruct E2 {
703003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E2() noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted default constructor does not match the calculated one}}
713003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E2(const E2&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted copy constructor does not match the calculated one}}
723003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E2(E2&&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted move constructor does not match the calculated one}}
733003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E2 &operator=(const E2&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted copy assignment operator does not match the calculated one}}
743003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E2 &operator=(E2&&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted move assignment operator does not match the calculated one}}
753003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  ~E2() noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted destructor does not match the calculated one}}
763003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith};
773003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith
783003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith// If a function is explicitly defaulted on its first declaration
793003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith//   -- it is implicitly considered to have the same exception-specification as
803003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith//      if it had been implicitly declared
813003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smithstruct E3 {
823003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E3() = default;
833003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E3(const E3&) = default;
843003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E3(E3&&) = default;
853003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E3 &operator=(const E3&) = default;
863003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E3 &operator=(E3&&) = default;
873003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  ~E3() = default;
883003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith};
893003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard SmithE3 e3;
903003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smithstatic_assert(noexcept(E3(), E3(E3()), E3(e3), e3 = E3(), e3 = e3), "");
913003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smithstruct E4 {
923003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E4() noexcept(false);
933003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E4(const E4&) noexcept(false);
943003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E4(E4&&) noexcept(false);
953003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E4 &operator=(const E4&) noexcept(false);
963003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E4 &operator=(E4&&) noexcept(false);
973003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  ~E4() noexcept(false);
983003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith};
993003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smithstruct E5 {
1003003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E5() = default;
1013003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E5(const E5&) = default;
1023003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E5(E5&&) = default;
1033003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E5 &operator=(const E5&) = default;
1043003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E5 &operator=(E5&&) = default;
1053003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  ~E5() = default;
1063003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith
1073003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith  E4 e4;
1083003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smith};
1093003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard SmithE5 e5;
1103003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smithstatic_assert(!noexcept(E5()), "");
1113003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smithstatic_assert(!noexcept(E5(static_cast<E5&&>(e5))), "");
1123003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smithstatic_assert(!noexcept(E5(e5)), "");
1133003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smithstatic_assert(!noexcept(e5 = E5()), "");
1143003e1d6626d07e8fc4af95fad95b3a5d4c4af98Richard Smithstatic_assert(!noexcept(e5 = e5), "");
1155121781d756e7814168b4255a57545d5ca497ec3Aaron Ballman
1165121781d756e7814168b4255a57545d5ca497ec3Aaron Ballmannamespace PR13492 {
1175121781d756e7814168b4255a57545d5ca497ec3Aaron Ballman  struct B {
1185121781d756e7814168b4255a57545d5ca497ec3Aaron Ballman    B() = default;
1195121781d756e7814168b4255a57545d5ca497ec3Aaron Ballman  };
1205121781d756e7814168b4255a57545d5ca497ec3Aaron Ballman
1215121781d756e7814168b4255a57545d5ca497ec3Aaron Ballman  void f() {
122176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    const B b; // expected-error {{default initialization of an object of const type 'const PR13492::B' without a user-provided default constructor}} expected-note {{add an explicit initializer to initialize 'b'}}
1235121781d756e7814168b4255a57545d5ca497ec3Aaron Ballman  }
1245121781d756e7814168b4255a57545d5ca497ec3Aaron Ballman}
125