1762bb9d0ad20320b9f97a841dce57ba5e8e48b07Richard Smith// RUN: %clang_cc1 -ffreestanding -fsyntax-only -verify -std=c++11 %s
2c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Hunt
3c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Hunt#include "limits.h"
4c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Hunt
5c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Hunttemplate<typename T, typename U>
6c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Huntstruct is_same_type {
7c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Hunt  static const bool value = false;
8c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Hunt};
9c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Hunttemplate <typename T>
10c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Huntstruct is_same_type<T, T> {
11c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Hunt  static const bool value = true;
12c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Hunt};
13c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Hunt
14c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Hunt__underlying_type(int) a; // expected-error {{only enumeration types}}
15c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Hunt__underlying_type(struct b) c; // expected-error {{only enumeration types}}
16c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Hunt
17c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Huntenum class f : char;
18c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Huntstatic_assert(is_same_type<char, __underlying_type(f)>::value,
19c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Hunt              "f has the wrong underlying type");
20c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Hunt
21c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Huntenum g {d = INT_MIN };
22c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Huntstatic_assert(is_same_type<int, __underlying_type(g)>::value,
23c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Hunt              "g has the wrong underlying type");
24c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Hunt
25c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Hunt__underlying_type(f) h;
26c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Huntstatic_assert(is_same_type<char, decltype(h)>::value,
27c9858bcf499078f58ebe7dcbede928cc0fa7a203Sean Hunt              "h has the wrong type");
28ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt
29ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunttemplate <typename T>
30ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Huntstruct underlying_type {
31ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt  typedef __underlying_type(T) type; // expected-error {{only enumeration types}}
32ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt};
33ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt
34ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Huntstatic_assert(is_same_type<underlying_type<f>::type, char>::value,
35ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt              "f has the wrong underlying type in the template");
36ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt
37ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Huntunderlying_type<int>::type e; // expected-note {{requested here}}
3812fc4b0624706b474fa10308631fa8daf92f340fPeter Collingbourne
3912fc4b0624706b474fa10308631fa8daf92f340fPeter Collingbourneusing uint = unsigned;
4012fc4b0624706b474fa10308631fa8daf92f340fPeter Collingbourneenum class foo : uint { bar };
4112fc4b0624706b474fa10308631fa8daf92f340fPeter Collingbourne
4212fc4b0624706b474fa10308631fa8daf92f340fPeter Collingbournestatic_assert(is_same_type<underlying_type<foo>::type, unsigned>::value,
4312fc4b0624706b474fa10308631fa8daf92f340fPeter Collingbourne              "foo has the wrong underlying type");
44ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
45ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesnamespace PR19966 {
46ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  void PR19966(enum Invalid) { // expected-note 2{{forward declaration of}}
47ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    // expected-error@-1 {{ISO C++ forbids forward references to 'enum'}}
48ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    // expected-error@-2 {{variable has incomplete type}}
49ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    __underlying_type(Invalid) dont_crash;
50ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    // expected-error@-1 {{cannot determine underlying type of incomplete enumeration type 'PR19966::Invalid'}}
51ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  }
52ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  enum E { // expected-note {{forward declaration of 'E'}}
53ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    a = (__underlying_type(E)){}
54ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    // expected-error@-1 {{cannot determine underlying type of incomplete enumeration type 'PR19966::E'}}
55ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    // expected-error@-2 {{constant expression}}
56ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  };
57ef8225444452a1486bd721f3285301fe84643b00Stephen Hines}
58