brintos

brintos / llvm-project-archived public Read only

0
0
Text · 19.2 KiB · 0af8bb7 Raw
695 lines · cpp
1// RUN: %clang_cc1 %s -verify -fno-builtin -std=c++142// RUN: %clang_cc1 %s -verify -fno-builtin -std=c++20 -verify=expected,cxx203// RUN: %clang_cc1 %s -verify -fno-builtin -std=c++14 -fexperimental-new-constant-interpreter4// RUN: %clang_cc1 %s -verify -fno-builtin -std=c++20 -verify=expected,cxx20 -fexperimental-new-constant-interpreter5 6#define _diagnose_if(...) __attribute__((diagnose_if(__VA_ARGS__)))7 8using size_t = decltype(sizeof(int));9 10namespace type_dependent {11template <typename T>12void neverok() _diagnose_if(!T(), "oh no", "error") {} // expected-note 4{{from 'diagnose_if'}}13 14template <typename T>15void alwaysok() _diagnose_if(T(), "oh no", "error") {}16 17template <typename T>18void alwayswarn() _diagnose_if(!T(), "oh no", "warning") {} // expected-note 4{{from 'diagnose_if'}}19 20template <typename T>21void neverwarn() _diagnose_if(T(), "oh no", "warning") {}22 23void runAll() {24  alwaysok<int>();25  alwaysok<int>();26 27  {28    void (*pok)() = alwaysok<int>;29    pok = &alwaysok<int>;30  }31 32  neverok<int>(); // expected-error{{oh no}}33  neverok<short>(); // expected-error{{oh no}}34 35  {36    void (*pok)() = neverok<int>; // expected-error{{oh no}}37  }38  {39    void (*pok)();40    pok = &neverok<int>; // expected-error{{oh no}}41  }42 43  alwayswarn<int>(); // expected-warning{{oh no}}44  alwayswarn<short>(); // expected-warning{{oh no}}45  {46    void (*pok)() = alwayswarn<int>; // expected-warning{{oh no}}47    pok = &alwayswarn<int>; // expected-warning{{oh no}}48  }49 50  neverwarn<int>();51  neverwarn<short>();52  {53    void (*pok)() = neverwarn<int>;54    pok = &neverwarn<int>;55  }56}57 58template <typename T>59void errorIf(T a) _diagnose_if(T() != a, "oh no", "error") {} // expected-note{{from 'diagnose_if'}}60 61template <typename T>62void warnIf(T a) _diagnose_if(T() != a, "oh no", "warning") {} // expected-note{{from 'diagnose_if'}}63 64void runIf() {65  errorIf(0);66  errorIf(1); // expected-error{{oh no}}67 68  warnIf(0);69  warnIf(1); // expected-warning{{oh no}}70}71}72 73namespace value_dependent {74template <int N>75void neverok() _diagnose_if(N == 0 || N != 0, "oh no", "error") {} // expected-note 4{{from 'diagnose_if'}}76 77template <int N>78void alwaysok() _diagnose_if(N == 0 && N != 0, "oh no", "error") {}79 80template <int N>81void alwayswarn() _diagnose_if(N == 0 || N != 0, "oh no", "warning") {} // expected-note 4{{from 'diagnose_if'}}82 83template <int N>84void neverwarn() _diagnose_if(N == 0 && N != 0, "oh no", "warning") {}85 86void runAll() {87  alwaysok<0>();88  alwaysok<1>();89 90  {91    void (*pok)() = alwaysok<0>;92    pok = &alwaysok<0>;93  }94 95  neverok<0>(); // expected-error{{oh no}}96  neverok<1>(); // expected-error{{oh no}}97 98  {99    void (*pok)() = neverok<0>; // expected-error{{oh no}}100  }101  {102    void (*pok)();103    pok = &neverok<0>; // expected-error{{oh no}}104  }105 106  alwayswarn<0>(); // expected-warning{{oh no}}107  alwayswarn<1>(); // expected-warning{{oh no}}108  {109    void (*pok)() = alwayswarn<0>; // expected-warning{{oh no}}110    pok = &alwayswarn<0>; // expected-warning{{oh no}}111  }112 113  neverwarn<0>();114  neverwarn<1>();115  {116    void (*pok)() = neverwarn<0>;117    pok = &neverwarn<0>;118  }119}120 121template <int N>122void errorIf(int a) _diagnose_if(N != a, "oh no", "error") {} // expected-note{{from 'diagnose_if'}}123 124template <int N>125void warnIf(int a) _diagnose_if(N != a, "oh no", "warning") {} // expected-note{{from 'diagnose_if'}}126 127void runIf() {128  errorIf<0>(0);129  errorIf<0>(1); // expected-error{{oh no}}130 131  warnIf<0>(0);132  warnIf<0>(1); // expected-warning{{oh no}}133}134}135 136namespace no_overload_interaction {137void foo(int) _diagnose_if(1, "oh no", "error"); // expected-note{{from 'diagnose_if'}}138void foo(short);139 140void bar(int);141void bar(short) _diagnose_if(1, "oh no", "error");142 143void fooArg(int a) _diagnose_if(a, "oh no", "error"); // expected-note{{from 'diagnose_if'}}144void fooArg(short);145 146void barArg(int);147void barArg(short a) _diagnose_if(a, "oh no", "error");148 149void runAll() {150  foo(1); // expected-error{{oh no}}151  bar(1);152 153  fooArg(1); // expected-error{{oh no}}154  barArg(1);155 156  auto p = foo; // expected-error{{incompatible initializer of type '<overloaded function type>'}}157}158}159 160namespace with_default_args {161void foo(int a = 0) _diagnose_if(a, "oh no", "warning"); // expected-note 1{{from 'diagnose_if'}}162void bar(int a = 1) _diagnose_if(a, "oh no", "warning"); // expected-note 2{{from 'diagnose_if'}}163 164void runAll() {165  foo();166  foo(0);167  foo(1); // expected-warning{{oh no}}168 169  bar(); // expected-warning{{oh no}}170  bar(0);171  bar(1); // expected-warning{{oh no}}172}173}174 175namespace naked_mem_expr {176struct Foo {177  void foo(int a) _diagnose_if(a, "should warn", "warning"); // expected-note{{from 'diagnose_if'}}178  void bar(int a) _diagnose_if(a, "oh no", "error"); // expected-note{{from 'diagnose_if'}}179};180 181void runFoo() {182  Foo().foo(0);183  Foo().foo(1); // expected-warning{{should warn}}184 185  Foo().bar(0);186  Foo().bar(1); // expected-error{{oh no}}187}188}189 190namespace class_template {191template <typename T>192struct Errors {193  void foo(int i) _diagnose_if(i, "bad i", "error"); // expected-note{{from 'diagnose_if'}}194  void bar(int i) _diagnose_if(i != T(), "bad i", "error"); // expected-note{{from 'diagnose_if'}}195 196  void fooOvl(int i) _diagnose_if(i, "int bad i", "error"); // expected-note{{from 'diagnose_if'}}197  void fooOvl(short i) _diagnose_if(i, "short bad i", "error"); // expected-note{{from 'diagnose_if'}}198 199  void barOvl(int i) _diagnose_if(i != T(), "int bad i", "error"); // expected-note{{from 'diagnose_if'}}200  void barOvl(short i) _diagnose_if(i != T(), "short bad i", "error"); // expected-note{{from 'diagnose_if'}}201};202 203void runErrors() {204  Errors<int>().foo(0);205  Errors<int>().foo(1); // expected-error{{bad i}}206 207  Errors<int>().bar(0);208  Errors<int>().bar(1); // expected-error{{bad i}}209 210  Errors<int>().fooOvl(0);211  Errors<int>().fooOvl(1); // expected-error{{int bad i}}212  Errors<int>().fooOvl(short(0));213  Errors<int>().fooOvl(short(1)); // expected-error{{short bad i}}214 215  Errors<int>().barOvl(0);216  Errors<int>().barOvl(1); // expected-error{{int bad i}}217  Errors<int>().barOvl(short(0));218  Errors<int>().barOvl(short(1)); // expected-error{{short bad i}}219}220 221template <typename T>222struct Warnings {223  void foo(int i) _diagnose_if(i, "bad i", "warning"); // expected-note{{from 'diagnose_if'}}224  void bar(int i) _diagnose_if(i != T(), "bad i", "warning"); // expected-note{{from 'diagnose_if'}}225 226  void fooOvl(int i) _diagnose_if(i, "int bad i", "warning"); // expected-note{{from 'diagnose_if'}}227  void fooOvl(short i) _diagnose_if(i, "short bad i", "warning"); // expected-note{{from 'diagnose_if'}}228 229  void barOvl(int i) _diagnose_if(i != T(), "int bad i", "warning"); // expected-note{{from 'diagnose_if'}}230  void barOvl(short i) _diagnose_if(i != T(), "short bad i", "warning"); // expected-note{{from 'diagnose_if'}}231};232 233void runWarnings() {234  Warnings<int>().foo(0);235  Warnings<int>().foo(1); // expected-warning{{bad i}}236 237  Warnings<int>().bar(0);238  Warnings<int>().bar(1); // expected-warning{{bad i}}239 240  Warnings<int>().fooOvl(0);241  Warnings<int>().fooOvl(1); // expected-warning{{int bad i}}242  Warnings<int>().fooOvl(short(0));243  Warnings<int>().fooOvl(short(1)); // expected-warning{{short bad i}}244 245  Warnings<int>().barOvl(0);246  Warnings<int>().barOvl(1); // expected-warning{{int bad i}}247  Warnings<int>().barOvl(short(0));248  Warnings<int>().barOvl(short(1)); // expected-warning{{short bad i}}249}250}251 252namespace template_specialization {253template <typename T>254struct Foo {255  void foo() _diagnose_if(1, "override me", "error"); // expected-note{{from 'diagnose_if'}}256  void bar(int i) _diagnose_if(i, "bad i", "error"); // expected-note{{from 'diagnose_if'}}257  void baz(int i);258};259 260template <>261struct Foo<int> {262  void foo();263  void bar(int i);264  void baz(int i) _diagnose_if(i, "bad i", "error"); // expected-note{{from 'diagnose_if'}}265};266 267void runAll() {268  Foo<double>().foo(); // expected-error{{override me}}269  Foo<int>().foo();270 271  Foo<double>().bar(1); // expected-error{{bad i}}272  Foo<int>().bar(1);273 274  Foo<double>().baz(1);275  Foo<int>().baz(1); // expected-error{{bad i}}276}277}278 279namespace late_constexpr {280constexpr int foo();281constexpr int foo(int a);282 283void bar() _diagnose_if(foo(), "bad foo", "error"); // expected-note{{from 'diagnose_if'}}284void bar(int a) _diagnose_if(foo(a), "bad foo", "error"); // expected-note{{from 'diagnose_if'}}285 286void early() {287  bar();288  bar(0);289  bar(1);290}291 292constexpr int foo() { return 1; }293constexpr int foo(int a) { return a; }294 295void late() {296  bar(); // expected-error{{bad foo}}297  bar(0);298  bar(1); // expected-error{{bad foo}}299}300}301 302namespace late_parsed {303struct Foo {304  int i;305  constexpr Foo(int i): i(i) {}306  constexpr bool isFooable() const { return i; }307 308  void go() const _diagnose_if(isFooable(), "oh no", "error") {} // expected-note{{from 'diagnose_if'}}309  operator int() const _diagnose_if(isFooable(), "oh no", "error") { return 1; } // expected-note{{from 'diagnose_if'}}310 311  void go2() const _diagnose_if(isFooable(), "oh no", "error") // expected-note{{from 'diagnose_if'}}312      __attribute__((enable_if(true, ""))) {}313  void go2() const _diagnose_if(isFooable(), "oh no", "error") {}314 315  constexpr int go3() const _diagnose_if(isFooable(), "oh no", "error")316      __attribute__((enable_if(true, ""))) {317    return 1;318  }319 320  constexpr int go4() const _diagnose_if(isFooable(), "oh no", "error") {321    return 1;322  }323  constexpr int go4() const _diagnose_if(isFooable(), "oh no", "error")324      __attribute__((enable_if(true, ""))) {325    return 1;326  }327 328  // We hope to support emitting these errors in the future. For now, though...329  constexpr int runGo() const {330    return go3() + go4();331  }332};333 334void go(const Foo &f) _diagnose_if(f.isFooable(), "oh no", "error") {} // expected-note{{from 'diagnose_if'}}335 336void run() {337  Foo(0).go();338  Foo(1).go(); // expected-error{{oh no}}339 340  (void)int(Foo(0));341  (void)int(Foo(1)); // expected-error{{oh no}}342 343  Foo(0).go2();344  Foo(1).go2(); // expected-error{{oh no}}345 346  go(Foo(0));347  go(Foo(1)); // expected-error{{oh no}}348}349}350 351namespace member_templates {352struct Foo {353  int i;354  constexpr Foo(int i): i(i) {}355  constexpr bool bad() const { return i; }356 357  template <typename T> T getVal() _diagnose_if(bad(), "oh no", "error") { // expected-note{{from 'diagnose_if'}}358    return T();359  }360 361  template <typename T>362  constexpr T getVal2() const _diagnose_if(bad(), "oh no", "error") { // expected-note{{from 'diagnose_if'}}363    return T();364  }365 366  template <typename T>367  constexpr operator T() const _diagnose_if(bad(), "oh no", "error") { // expected-note{{from 'diagnose_if'}}368    return T();369  }370 371  // We hope to support emitting these errors in the future.372  int run() { return getVal<int>() + getVal2<int>() + int(*this); }373};374 375void run() {376  Foo(0).getVal<int>();377  Foo(1).getVal<int>(); // expected-error{{oh no}}378 379  Foo(0).getVal2<int>();380  Foo(1).getVal2<int>(); // expected-error{{oh no}}381 382  (void)int(Foo(0));383  (void)int(Foo(1)); // expected-error{{oh no}}384}385}386 387namespace special_member_operators {388struct Bar { int j; };389struct Foo {390  int i;391  constexpr Foo(int i): i(i) {}392  constexpr bool bad() const { return i; }393  const Bar *operator->() const _diagnose_if(bad(), "oh no", "error") { // expected-note{{from 'diagnose_if'}}394    return nullptr;395  }396  void operator()() const _diagnose_if(bad(), "oh no", "error") {} // expected-note{{from 'diagnose_if'}}397};398 399struct ParenOverload {400  int i;401  constexpr ParenOverload(int i): i(i) {}402  constexpr bool bad() const { return i; }403  void operator()(double) const _diagnose_if(bad(), "oh no", "error") {} // expected-note{{from 'diagnose_if'}}404  void operator()(int) const _diagnose_if(bad(), "oh no", "error") {} // expected-note{{from 'diagnose_if'}}405};406 407struct ParenTemplate {408  int i;409  constexpr ParenTemplate(int i): i(i) {}410  constexpr bool bad() const { return i; }411  template <typename T>412  void operator()(T) const _diagnose_if(bad(), "oh no", "error") {} // expected-note 2{{from 'diagnose_if'}}413};414 415void run() {416  (void)Foo(0)->j;417  (void)Foo(1)->j; // expected-error{{oh no}}418 419  Foo(0)();420  Foo(1)(); // expected-error{{oh no}}421 422  ParenOverload(0)(1);423  ParenOverload(0)(1.);424 425  ParenOverload(1)(1); // expected-error{{oh no}}426  ParenOverload(1)(1.); // expected-error{{oh no}}427 428  ParenTemplate(0)(1);429  ParenTemplate(0)(1.);430 431  ParenTemplate(1)(1); // expected-error{{oh no}}432  ParenTemplate(1)(1.); // expected-error{{oh no}}433}434 435void runLambda() {436  auto L1 = [](int i) _diagnose_if(i, "oh no", "error") {}; // expected-note{{from 'diagnose_if'}}437  L1(0);438  L1(1); // expected-error{{oh no}}439}440 441struct Brackets {442  int i;443  constexpr Brackets(int i): i(i) {}444  void operator[](int) _diagnose_if(i == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}445    _diagnose_if(i == 2, "oh no", "error"); // expected-note{{from 'diagnose_if'}}446};447 448void runBrackets(int i) {449  Brackets{0}[i];450  Brackets{1}[i]; // expected-warning{{oh no}}451  Brackets{2}[i]; // expected-error{{oh no}}452}453 454struct Unary {455  int i;456  constexpr Unary(int i): i(i) {}457  void operator+() _diagnose_if(i == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}458    _diagnose_if(i == 2, "oh no", "error"); // expected-note{{from 'diagnose_if'}}459};460 461void runUnary() {462  +Unary{0};463  +Unary{1}; // expected-warning{{oh no}}464  +Unary{2}; // expected-error{{oh no}}465}466 467struct PostInc {468  void operator++(int i) _diagnose_if(i == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}469    _diagnose_if(i == 2, "oh no", "error"); // expected-note{{from 'diagnose_if'}}470};471 472void runPostInc() {473  PostInc{}++;474  PostInc{}.operator++(1); // expected-warning{{oh no}}475  PostInc{}.operator++(2); // expected-error{{oh no}}476}477}478 479namespace ctors {480struct Foo {481  int I;482  constexpr Foo(int I): I(I) {}483 484  constexpr const Foo &operator=(const Foo &) const485      _diagnose_if(I, "oh no", "error") {  // expected-note{{from 'diagnose_if'}}486    return *this;487  }488 489  constexpr const Foo &operator=(const Foo &&) const490      _diagnose_if(I, "oh no", "error") { // expected-note{{from 'diagnose_if'}}491    return *this;492  }493};494 495struct Bar {496  int I;497  constexpr Bar(int I) _diagnose_if(I == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}498    _diagnose_if(I == 2, "oh no", "error"): I(I) {} // expected-note{{from 'diagnose_if'}}499};500 501void run() {502  constexpr Foo F{0};503  constexpr Foo F2{1};504 505  F2 = F; // expected-error{{oh no}}506  F2 = Foo{2}; // expected-error{{oh no}}507 508  Bar{0};509  Bar{1}; // expected-warning{{oh no}}510  Bar{2}; // expected-error{{oh no}}511}512}513 514namespace ref_init {515struct Bar {};516struct Baz {};517struct Foo {518  int i;519  constexpr Foo(int i): i(i) {}520  operator const Bar &() const _diagnose_if(i, "oh no", "warning"); // expected-note{{from 'diagnose_if'}}521  operator const Baz &() const _diagnose_if(i, "oh no", "error"); // expected-note{{from 'diagnose_if'}}522};523void fooBar(const Bar &b);524void fooBaz(const Baz &b);525 526void run() {527  fooBar(Foo{0});528  fooBar(Foo{1}); // expected-warning{{oh no}}529  fooBaz(Foo{0});530  fooBaz(Foo{1}); // expected-error{{oh no}}531}532}533 534namespace udl {535void operator""_fn(char c)_diagnose_if(c == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}536    _diagnose_if(c == 2, "oh no", "error"); // expected-note{{from 'diagnose_if'}}537 538void run() {539  '\0'_fn;540  '\1'_fn; // expected-warning{{oh no}}541  '\2'_fn; // expected-error{{oh no}}542}543}544 545namespace PR31638 {546struct String {547  String(char const* __s) _diagnose_if(__s == nullptr, "oh no ptr", "warning"); // expected-note{{from 'diagnose_if'}}548  String(int __s) _diagnose_if(__s != 0, "oh no int", "warning"); // expected-note{{from 'diagnose_if'}}549};550 551void run() {552  String s(nullptr); // expected-warning{{oh no ptr}}553  String ss(42); // expected-warning{{oh no int}}554}555}556 557namespace PR31639 {558struct Foo {559  Foo(int I) __attribute__((diagnose_if(I, "oh no", "error"))); // expected-note{{from 'diagnose_if'}}560};561 562void bar() { Foo f(1); } // expected-error{{oh no}}563}564 565namespace user_defined_conversion {566struct Foo {567  int i;568  constexpr Foo(int i): i(i) {}569  operator size_t() const _diagnose_if(i == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}570      _diagnose_if(i == 2, "oh no", "error"); // expected-note{{from 'diagnose_if'}}571};572 573void run() {574  // `new T[N]`, where N is implicitly convertible to size_t, calls575  // PerformImplicitConversion directly. This lets us test the diagnostic logic576  // in PerformImplicitConversion.577  new int[Foo{0}];578  new int[Foo{1}]; // expected-warning{{oh no}}579  new int[Foo{2}]; // expected-error{{oh no}}580}581}582 583namespace std {584  template <typename T>585  struct initializer_list {586    const T *ptr;587    size_t elems;588 589    constexpr size_t size() const { return elems; }590  };591}592 593namespace initializer_lists {594struct Foo {595  Foo(std::initializer_list<int> l)596    _diagnose_if(l.size() == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}597    _diagnose_if(l.size() == 2, "oh no", "error") {} // expected-note{{from 'diagnose_if'}}598};599 600void run() {601  Foo{std::initializer_list<int>{}};602  Foo{std::initializer_list<int>{1}}; // expected-warning{{oh no}}603  Foo{std::initializer_list<int>{1, 2}}; // expected-error{{oh no}}604  Foo{std::initializer_list<int>{1, 2, 3}};605}606}607 608namespace range_for_loop {609  namespace adl {610    struct Foo {611      int i;612      constexpr Foo(int i): i(i) {}613    };614    void **begin(const Foo &f) _diagnose_if(f.i, "oh no", "warning");615    void **end(const Foo &f) _diagnose_if(f.i, "oh no", "warning");616 617    struct Bar {618      int i;619      constexpr Bar(int i): i(i) {}620    };621    void **begin(const Bar &b) _diagnose_if(b.i, "oh no", "error");622    void **end(const Bar &b) _diagnose_if(b.i, "oh no", "error");623  }624 625  void run() {626    for (void *p : adl::Foo(0)) {}627    // FIXME: This should emit diagnostics. It seems that our constexpr628    // evaluator isn't able to evaluate `adl::Foo(1)` as a constant, though.629    for (void *p : adl::Foo(1)) {}630 631    for (void *p : adl::Bar(0)) {}632    // FIXME: Same thing.633    for (void *p : adl::Bar(1)) {}634  }635}636 637namespace operator_new {638struct Foo {639  int j;640  static void *operator new(size_t i) _diagnose_if(i, "oh no", "warning"); // expected-note{{from 'diagnose_if'}}641};642 643struct Bar {644  int j;645  static void *operator new(size_t i) _diagnose_if(!i, "oh no", "warning");646};647 648void run() {649  new Foo(); // expected-warning{{oh no}}650  new Bar();651}652}653 654namespace contextual_implicit_conv {655struct Foo {656  int i;657  constexpr Foo(int i): i(i) {}658  constexpr operator int() const _diagnose_if(i == 1, "oh no", "warning") // expected-note{{from 'diagnose_if'}}659      _diagnose_if(i == 2, "oh no", "error") { // expected-note{{from 'diagnose_if'}}660    return i;661  }662};663 664void run() {665  switch (constexpr Foo i = 0) { default: break; }666  switch (constexpr Foo i = 1) { default: break; } // expected-warning{{oh no}}667  switch (constexpr Foo i = 2) { default: break; } // expected-error{{oh no}}668}669}670 671namespace GH160776 {672 673struct ConstructorTemplate {674  template <class T>675  explicit ConstructorTemplate(T x)676      _diagnose_if(sizeof(T) == sizeof(char), "oh no", "error") {} // expected-note {{diagnose_if}}677 678  template <class T>679#if __cplusplus >= 202002L680  requires (sizeof(T) == 1) // cxx20-note {{evaluated to false}}681#endif682  operator T() _diagnose_if(sizeof(T) == sizeof(char), "oh no", "error") { // expected-note {{diagnose_if}} \683                                                                           // cxx20-note {{constraints not satisfied}}684    return T{};685  }686};687 688void run() {689  ConstructorTemplate x('1'); // expected-error {{oh no}}690  char y = x; // expected-error {{oh no}}691  int z = x; // cxx20-error {{no viable conversion}}692}693 694}695