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"); 44c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 45c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesnamespace PR19966 { 46c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines void PR19966(enum Invalid) { // expected-note 2{{forward declaration of}} 47c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // expected-error@-1 {{ISO C++ forbids forward references to 'enum'}} 48c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // expected-error@-2 {{variable has incomplete type}} 49c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines __underlying_type(Invalid) dont_crash; 50c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // expected-error@-1 {{cannot determine underlying type of incomplete enumeration type 'PR19966::Invalid'}} 51c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 52c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines enum E { // expected-note {{forward declaration of 'E'}} 53c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines a = (__underlying_type(E)){} 54c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // expected-error@-1 {{cannot determine underlying type of incomplete enumeration type 'PR19966::E'}} 55c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // expected-error@-2 {{constant expression}} 56c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines }; 57c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 58