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