Home | History | Annotate | Download | only in stmt.ranged
      1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
      2 
      3 struct pr12960 {
      4   int begin;
      5   void foo(int x) {
      6     for (int& it : x) { // expected-error {{invalid range expression of type 'int'; no viable 'begin' function available}}
      7     }
      8   }
      9 };
     10 
     11 struct null_t {
     12   operator int*();
     13 };
     14 
     15 namespace X {
     16   template<typename T>
     17     auto begin(T &&t) -> decltype(t.begin()) { return t.begin(); } // expected-note 2{{ignored: substitution failure}}
     18   template<typename T>
     19     auto end(T &&t) -> decltype(t.end()) { return t.end(); } // expected-note {{candidate template ignored: substitution failure [with T = }}
     20 
     21   template<typename T>
     22     auto begin(T &&t) -> decltype(t.alt_begin()) { return t.alt_begin(); } // expected-note {{selected 'begin' template [with T = }} \
     23                                                                               expected-note 2{{candidate template ignored: substitution failure [with T = }}
     24   template<typename T>
     25     auto end(T &&t) -> decltype(t.alt_end()) { return t.alt_end(); } // expected-note {{candidate template ignored: substitution failure [with T = }}
     26 
     27   namespace inner {
     28     // These should never be considered.
     29     int begin(int);
     30     int end(int);
     31   }
     32 
     33   using namespace inner;
     34 
     35   struct A { // expected-note 2 {{candidate constructor}}
     36     A();
     37     int *begin(); // expected-note 3{{selected 'begin' function with iterator type 'int *'}} expected-note {{'begin' declared here}}
     38     int *end();
     39   };
     40 
     41   struct B {
     42     B();
     43     int *alt_begin();
     44     int *alt_end();
     45   };
     46 
     47   struct NoBeginADL {
     48     null_t alt_end();
     49   };
     50   struct NoEndADL {
     51     null_t alt_begin();
     52   };
     53 }
     54 
     55 using X::A;
     56 
     57 void f();
     58 void f(int);
     59 
     60 void g() {
     61   for (int a : A())
     62     A __begin;
     63   for (char *a : A()) { // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'int'}}
     64   }
     65   for (char *a : X::B()) { // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'int'}}
     66   }
     67   // FIXME: Terrible diagnostic here. auto deduction should fail, but does not!
     68   for (double a : f) { // expected-error {{cannot use type '<overloaded function type>' as a range}}
     69   }
     70   for (auto a : A()) {
     71   }
     72   for (auto a : X::B()) {
     73   }
     74   for (auto *a : A()) { // expected-error {{variable 'a' with type 'auto *' has incompatible initializer of type 'int'}}
     75   }
     76   // : is not a typo for :: here.
     77   for (A NS:A()) { // expected-error {{no viable conversion from 'int' to 'X::A'}}
     78   }
     79   for (auto not_in_scope : not_in_scope) { // expected-error {{use of undeclared identifier 'not_in_scope'}}
     80   }
     81 
     82   for (auto a : A())
     83     for (auto b : A()) {
     84       __range.begin(); // expected-error {{use of undeclared identifier '__range'}}
     85       ++__begin; // expected-error {{use of undeclared identifier '__begin'}}
     86       --__end; // expected-error {{use of undeclared identifier '__end'}}
     87     }
     88 
     89   for (char c : "test")
     90     ;
     91   for (auto a : f()) // expected-error {{cannot use type 'void' as a range}}
     92     ;
     93 
     94   extern int incomplete[];
     95   for (auto a : incomplete) // expected-error {{cannot use incomplete type 'int []' as a range}}
     96     ;
     97   extern struct Incomplete also_incomplete[2]; // expected-note {{forward declaration}}
     98   for (auto &a : also_incomplete) // expected-error {{cannot use incomplete type 'struct Incomplete [2]' as a range}}
     99     ;
    100 
    101   struct VoidBegin {
    102     void begin(); // expected-note {{selected 'begin' function with iterator type 'void'}}
    103     void end();
    104   };
    105   for (auto a : VoidBegin()) // expected-error {{cannot use type 'void' as an iterator}}
    106     ;
    107 
    108   struct Differ {
    109     int *begin(); // expected-note {{selected 'begin' function with iterator type 'int *'}}
    110     null_t end(); // expected-note {{selected 'end' function with iterator type 'null_t'}}
    111   };
    112   for (auto a : Differ()) // expected-error {{'begin' and 'end' must return the same type (got 'int *' and 'null_t')}}
    113     ;
    114 
    115   for (void f() : "error") // expected-error {{for range declaration must declare a variable}}
    116     ;
    117 
    118   for (extern int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'extern'}}
    119   for (static int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'static'}}
    120   for (register int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'register'}} expected-warning {{deprecated}}
    121   for (constexpr int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'constexpr'}}
    122 
    123   for (auto u : X::NoBeginADL()) { // expected-error {{invalid range expression of type 'X::NoBeginADL'; no viable 'begin' function available}}
    124   }
    125   for (auto u : X::NoEndADL()) { // expected-error {{invalid range expression of type 'X::NoEndADL'; no viable 'end' function available}}
    126   }
    127 
    128   struct NoBegin {
    129     null_t end();
    130   };
    131   struct NoEnd {
    132     null_t begin();
    133   };
    134   for (auto u : NoBegin()) { // expected-error {{range type 'NoBegin' has 'end' member but no 'begin' member}}
    135   }
    136   for (auto u : NoEnd()) { // expected-error {{range type 'NoEnd' has 'begin' member but no 'end' member}}
    137   }
    138 
    139   struct NoIncr {
    140     void *begin(); // expected-note {{selected 'begin' function with iterator type 'void *'}}
    141     void *end();
    142   };
    143   for (auto u : NoIncr()) { // expected-error {{arithmetic on a pointer to void}}\
    144     expected-note {{in implicit call to 'operator++' for iterator of type 'NoIncr'}}
    145   }
    146 
    147   struct NoNotEq {
    148     NoNotEq begin(); // expected-note {{selected 'begin' function with iterator type 'NoNotEq'}}
    149     NoNotEq end();
    150     void operator++();
    151   };
    152   for (auto u : NoNotEq()) { // expected-error {{invalid operands to binary expression}}\
    153     expected-note {{in implicit call to 'operator!=' for iterator of type 'NoNotEq'}}
    154   }
    155 
    156   struct NoDeref {
    157     NoDeref begin(); // expected-note {{selected 'begin' function}}
    158     NoDeref end();
    159     void operator++();
    160     bool operator!=(NoDeref &);
    161   };
    162 
    163   for (auto u : NoDeref()) { // expected-error {{indirection requires pointer operand}} \
    164     expected-note {{in implicit call to 'operator*' for iterator of type 'NoDeref'}}
    165   }
    166 
    167   struct NoCopy {
    168     NoCopy();
    169     NoCopy(const NoCopy &) = delete;
    170     int *begin();
    171     int *end();
    172   };
    173   for (int n : NoCopy()) { // ok
    174   }
    175 
    176   for (int n : 42) { // expected-error {{invalid range expression of type 'int'; no viable 'begin' function available}}
    177   }
    178 
    179   for (auto a : *also_incomplete) { // expected-error {{cannot use incomplete type 'struct Incomplete' as a range}}
    180   }
    181 }
    182 
    183 template<typename T, typename U>
    184 void h(T t) {
    185   for (U u : t) { // expected-error {{no viable conversion from 'X::A' to 'int'}}
    186   }
    187   for (auto u : t) {
    188   }
    189 }
    190 
    191 template void h<A, int>(A);
    192 template void h<A(&)[4], A &>(A(&)[4]);
    193 template void h<A(&)[13], A>(A(&)[13]);
    194 template void h<A(&)[13], int>(A(&)[13]); // expected-note {{requested here}}
    195 
    196 template<typename T>
    197 void i(T t) {
    198   for (auto u : t) { // expected-error {{invalid range expression of type 'X::A *'; no viable 'begin' function available}} \
    199                         expected-error {{member function 'begin' not viable}} \
    200                         expected-note {{when looking up 'begin' function}}
    201 
    202   }
    203 }
    204 template void i<A[13]>(A*); // expected-note {{requested here}}
    205 template void i<const A>(const A); // expected-note {{requested here}}
    206 
    207 struct StdBeginEnd {};
    208 namespace std {
    209   int *begin(StdBeginEnd);
    210   int *end(StdBeginEnd);
    211 }
    212 void DR1442() {
    213   for (auto a : StdBeginEnd()) {} // expected-error {{invalid range expression of type 'StdBeginEnd'; no viable 'begin'}}
    214 }
    215 
    216 namespace NS {
    217   class ADL {};
    218   int *begin(ADL); // expected-note {{no known conversion from 'NS::NoADL' to 'NS::ADL'}}
    219   int *end(ADL);
    220 
    221   class NoADL {};
    222 }
    223 int *begin(NS::NoADL);
    224 int *end(NS::NoADL);
    225 
    226 struct VoidBeginADL {};
    227 void begin(VoidBeginADL); // expected-note {{selected 'begin' function with iterator type 'void'}}
    228 void end(VoidBeginADL);
    229 
    230 void j() {
    231   for (auto u : NS::ADL()) {
    232   }
    233   for (auto u : NS::NoADL()) { // expected-error {{invalid range expression of type 'NS::NoADL'; no viable 'begin' function available}}
    234   }
    235   for (auto a : VoidBeginADL()) { // expected-error {{cannot use type 'void' as an iterator}}
    236 
    237   }
    238 }
    239 
    240 void example() {
    241   int array[5] = { 1, 2, 3, 4, 5 };
    242   for (int &x : array)
    243     x *= 2;
    244 }
    245 
    246 namespace rdar13712739 {
    247   template<typename T>
    248   void foo(const T& t) {
    249     auto &x = t.get(); // expected-error{{member reference base type 'const int' is not a structure or union}}
    250     for (auto &blah : x) { }
    251   }
    252 
    253   template void foo(const int&); // expected-note{{in instantiation of function template specialization}}
    254 }
    255