ms-delayed-default-template-args.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // RUN: %clang_cc1 -fms-compatibility -std=c++11 %s -verify
  2. // MSVC should compile this file without errors.
  3. namespace test_basic {
  4. template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}}
  5. struct Foo { T x; };
  6. typedef int Baz;
  7. template struct Foo<>;
  8. }
  9. namespace test_namespace {
  10. namespace nested {
  11. template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}}
  12. struct Foo {
  13. static_assert(sizeof(T) == 4, "should get int, not double");
  14. };
  15. typedef int Baz;
  16. }
  17. typedef double Baz;
  18. template struct nested::Foo<>;
  19. }
  20. namespace test_inner_class_template {
  21. struct Outer {
  22. template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}}
  23. struct Foo {
  24. static_assert(sizeof(T) == 4, "should get int, not double");
  25. };
  26. typedef int Baz;
  27. };
  28. typedef double Baz;
  29. template struct Outer::Foo<>;
  30. }
  31. namespace test_nontype_param {
  32. template <typename T> struct Bar { T x; };
  33. typedef int Qux;
  34. template <Bar<Qux> *P>
  35. struct Foo {
  36. };
  37. Bar<int> g;
  38. template struct Foo<&g>;
  39. }
  40. // MSVC accepts this, but Clang doesn't.
  41. namespace test_template_instantiation_arg {
  42. template <typename T> struct Bar { T x; };
  43. template <typename T = Bar<Weber>> // expected-error {{use of undeclared identifier 'Weber'}}
  44. struct Foo {
  45. static_assert(sizeof(T) == 4, "Bar should have gotten int");
  46. // FIXME: These diagnostics are bad.
  47. }; // expected-error {{expected ',' or '>' in template-parameter-list}}
  48. // expected-warning@-1 {{does not declare anything}}
  49. typedef int Weber;
  50. }
  51. #ifdef __clang__
  52. // These are negative test cases that MSVC doesn't compile either. Try to use
  53. // unique undeclared identifiers so typo correction doesn't find types declared
  54. // above.
  55. namespace test_undeclared_nontype_parm_type {
  56. template <Zargon N> // expected-error {{unknown type name 'Zargon'}}
  57. struct Foo { int x[N]; };
  58. typedef int Zargon;
  59. template struct Foo<4>;
  60. }
  61. namespace test_undeclared_nontype_parm_type_no_name {
  62. template <typename T, Asdf> // expected-error {{unknown type name 'Asdf'}}
  63. struct Foo { T x; };
  64. template struct Foo<int, 0>;
  65. }
  66. namespace test_undeclared_type_arg {
  67. template <typename T>
  68. struct Foo { T x; };
  69. template struct Foo<Yodel>; // expected-error {{use of undeclared identifier 'Yodel'}}
  70. }
  71. namespace test_undeclared_nontype_parm_arg {
  72. // Bury an undeclared type as a template argument to the type of a non-type
  73. // template parameter.
  74. template <typename T> struct Bar { T x; };
  75. template <Bar<Xylophone> *P> // expected-error {{use of undeclared identifier 'Xylophone'}}
  76. // expected-note@-1 {{template parameter is declared here}}
  77. struct Foo { };
  78. typedef int Xylophone;
  79. Bar<Xylophone> g;
  80. template struct Foo<&g>; // expected-error {{cannot be converted}}
  81. }
  82. #endif