aboutsummaryrefslogtreecommitdiff
path: root/test/SemaTemplate/ms-delayed-default-template-args.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaTemplate/ms-delayed-default-template-args.cpp')
-rw-r--r--test/SemaTemplate/ms-delayed-default-template-args.cpp96
1 files changed, 96 insertions, 0 deletions
diff --git a/test/SemaTemplate/ms-delayed-default-template-args.cpp b/test/SemaTemplate/ms-delayed-default-template-args.cpp
new file mode 100644
index 000000000000..ca9ddb0d9d15
--- /dev/null
+++ b/test/SemaTemplate/ms-delayed-default-template-args.cpp
@@ -0,0 +1,96 @@
+// RUN: %clang_cc1 -fms-compatibility -std=c++11 %s -verify
+
+// MSVC should compile this file without errors.
+
+namespace test_basic {
+template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}}
+struct Foo { T x; };
+typedef int Baz;
+template struct Foo<>;
+}
+
+namespace test_namespace {
+namespace nested {
+template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}}
+struct Foo {
+ static_assert(sizeof(T) == 4, "should get int, not double");
+};
+typedef int Baz;
+}
+typedef double Baz;
+template struct nested::Foo<>;
+}
+
+namespace test_inner_class_template {
+struct Outer {
+ template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}}
+ struct Foo {
+ static_assert(sizeof(T) == 4, "should get int, not double");
+ };
+ typedef int Baz;
+};
+typedef double Baz;
+template struct Outer::Foo<>;
+}
+
+namespace test_nontype_param {
+template <typename T> struct Bar { T x; };
+typedef int Qux;
+template <Bar<Qux> *P>
+struct Foo {
+};
+Bar<int> g;
+template struct Foo<&g>;
+}
+
+// MSVC accepts this, but Clang doesn't.
+namespace test_template_instantiation_arg {
+template <typename T> struct Bar { T x; };
+template <typename T = Bar<Weber>> // expected-error {{use of undeclared identifier 'Weber'}}
+struct Foo {
+ static_assert(sizeof(T) == 4, "Bar should have gotten int");
+ // FIXME: These diagnostics are bad.
+}; // expected-error {{expected ',' or '>' in template-parameter-list}}
+// expected-warning@-1 {{does not declare anything}}
+typedef int Weber;
+}
+
+#ifdef __clang__
+// These are negative test cases that MSVC doesn't compile either. Try to use
+// unique undeclared identifiers so typo correction doesn't find types declared
+// above.
+
+namespace test_undeclared_nontype_parm_type {
+template <Zargon N> // expected-error {{unknown type name 'Zargon'}}
+struct Foo { int x[N]; };
+typedef int Zargon;
+template struct Foo<4>;
+}
+
+namespace test_undeclared_nontype_parm_type_no_name {
+template <typename T, Asdf> // expected-error {{unknown type name 'Asdf'}}
+struct Foo { T x; };
+template struct Foo<int, 0>;
+}
+
+namespace test_undeclared_type_arg {
+template <typename T>
+struct Foo { T x; };
+template struct Foo<Yodel>; // expected-error {{use of undeclared identifier 'Yodel'}}
+}
+
+namespace test_undeclared_nontype_parm_arg {
+// Bury an undeclared type as a template argument to the type of a non-type
+// template parameter.
+template <typename T> struct Bar { T x; };
+
+template <Bar<Xylophone> *P> // expected-error {{use of undeclared identifier 'Xylophone'}}
+// expected-note@-1 {{template parameter is declared here}}
+struct Foo { };
+
+typedef int Xylophone;
+Bar<Xylophone> g;
+template struct Foo<&g>; // expected-error {{cannot be converted}}
+}
+
+#endif