summaryrefslogtreecommitdiffstats
path: root/test/CXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/CXX')
-rw-r--r--test/CXX/basic/basic.link/p1.cpp57
-rw-r--r--test/CXX/basic/basic.link/p2.cpp16
-rw-r--r--test/CXX/basic/basic.link/p3.cpp53
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-associated-namespaces-classes.cpp344
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-inline-namespace.cpp56
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp16
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp64
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp93
-rw-r--r--test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp86
-rw-r--r--test/CXX/class.access/p4.cpp10
-rw-r--r--test/CXX/class/class.union/class.union.anon/p4.cpp2
-rw-r--r--test/CXX/cpp/cpp.module/Inputs/attrs.h1
-rw-r--r--test/CXX/cpp/cpp.module/Inputs/empty.h0
-rw-r--r--test/CXX/cpp/cpp.module/p1.cpp18
-rw-r--r--test/CXX/cpp/cpp.module/p2.cpp32
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp2
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p3.cpp18
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp4
-rw-r--r--test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp27
-rw-r--r--test/CXX/drs/dr0xx.cpp37
-rw-r--r--test/CXX/drs/dr13xx.cpp2
-rw-r--r--test/CXX/drs/dr14xx.cpp16
-rw-r--r--test/CXX/drs/dr15xx.cpp10
-rw-r--r--test/CXX/drs/dr16xx.cpp48
-rw-r--r--test/CXX/drs/dr17xx.cpp27
-rw-r--r--test/CXX/drs/dr19xx.cpp1
-rw-r--r--test/CXX/drs/dr23xx.cpp26
-rw-r--r--test/CXX/drs/dr7xx.cpp112
-rw-r--r--test/CXX/except/except.spec/p14.cpp29
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p9.cpp8
-rw-r--r--test/CXX/lex/lex.pptoken/Inputs/foo bar1
-rw-r--r--test/CXX/lex/lex.pptoken/Inputs/foo bar1
-rw-r--r--test/CXX/lex/lex.pptoken/p3-2a.cpp81
-rw-r--r--test/CXX/module/module.interface/Inputs/header.h3
-rw-r--r--test/CXX/module/module.interface/p1.cpp38
-rw-r--r--test/CXX/module/module.interface/p2.cpp94
-rw-r--r--test/CXX/module/module.interface/p3.cpp54
-rw-r--r--test/CXX/module/module.interface/p5.cpp89
-rw-r--r--test/CXX/module/module.unit/p3.cpp4
-rw-r--r--test/CXX/module/module.unit/p8.cpp40
-rw-r--r--test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp2
-rw-r--r--test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm16
-rw-r--r--test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp2
-rw-r--r--test/CXX/modules-ts/basic/basic.link/module-declaration.cpp34
-rw-r--r--test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp5
-rw-r--r--test/CXX/temp/temp.decls/temp.friend/p1.cpp6
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/p4.cpp9
47 files changed, 1597 insertions, 97 deletions
diff --git a/test/CXX/basic/basic.link/p1.cpp b/test/CXX/basic/basic.link/p1.cpp
new file mode 100644
index 0000000000..c6a119aa7f
--- /dev/null
+++ b/test/CXX/basic/basic.link/p1.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+// RUN: %clang_cc1 -std=c++2a -verify -DNO_GLOBAL_FRAG %s
+// RUN: %clang_cc1 -std=c++2a -verify -DNO_MODULE_DECL %s
+// RUN: %clang_cc1 -std=c++2a -verify -DNO_PRIVATE_FRAG %s
+// RUN: %clang_cc1 -std=c++2a -verify -DNO_MODULE_DECL -DNO_PRIVATE_FRAG %s
+// RUN: %clang_cc1 -std=c++2a -verify -DNO_GLOBAL_FRAG -DNO_PRIVATE_FRAG %s
+// RUN: %clang_cc1 -std=c++2a -verify -DNO_GLOBAL_FRAG -DNO_MODULE_DECL %s
+// RUN: %clang_cc1 -std=c++2a -verify -DNO_GLOBAL_FRAG -DNO_MODULE_DECL -DNO_PRIVATE_FRAG %s
+// RUN: %clang_cc1 -std=c++2a -verify -DEXPORT_FRAGS %s
+
+#ifndef NO_GLOBAL_FRAG
+#ifdef EXPORT_FRAGS
+export // expected-error {{global module fragment cannot be exported}}
+#endif
+module;
+#ifdef NO_MODULE_DECL
+// expected-error@-2 {{missing 'module' declaration at end of global module fragment introduced here}}
+#endif
+#endif
+
+extern int a; // #a1
+
+#ifndef NO_MODULE_DECL
+export module Foo;
+#ifdef NO_GLOBAL_FRAG
+// expected-error@-2 {{module declaration must occur at the start of the translation unit}}
+// expected-note@1 {{add 'module;' to the start of the file to introduce a global module fragment}}
+#endif
+
+// expected-error@#a2 {{declaration of 'a' in module Foo follows declaration in the global module}}
+// expected-note@#a1 {{previous decl}}
+#endif
+
+int a; // #a2
+extern int b;
+
+module; // expected-error {{'module;' introducing a global module fragment can appear only at the start of the translation unit}}
+
+#ifndef NO_PRIVATE_FRAG
+#ifdef EXPORT_FRAGS
+export // expected-error {{private module fragment cannot be exported}}
+#endif
+module :private; // #priv-frag
+#ifdef NO_MODULE_DECL
+// expected-error@-2 {{private module fragment declaration with no preceding module declaration}}
+#endif
+#endif
+
+int b; // ok
+
+
+#ifndef NO_PRIVATE_FRAG
+#ifndef NO_MODULE_DECL
+module :private; // expected-error {{private module fragment redefined}}
+// expected-note@#priv-frag {{previous definition is here}}
+#endif
+#endif
diff --git a/test/CXX/basic/basic.link/p2.cpp b/test/CXX/basic/basic.link/p2.cpp
new file mode 100644
index 0000000000..54e347c91e
--- /dev/null
+++ b/test/CXX/basic/basic.link/p2.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++2a -DEXPORT %s -verify
+// RUN: %clang_cc1 -std=c++2a -DEXPORT %s -emit-module-interface -o %t.pcm
+// RUN: %clang_cc1 -std=c++2a -UEXPORT %s -verify -fmodule-file=%t.pcm
+
+#ifdef EXPORT
+// expected-no-diagnostics
+export
+#else
+// expected-note@+2 {{add 'export' here}}
+#endif
+module M;
+
+#ifndef EXPORT
+// expected-error@+2 {{private module fragment in module implementation unit}}
+#endif
+module :private;
diff --git a/test/CXX/basic/basic.link/p3.cpp b/test/CXX/basic/basic.link/p3.cpp
new file mode 100644
index 0000000000..23f39d11b6
--- /dev/null
+++ b/test/CXX/basic/basic.link/p3.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+// RUN: %clang_cc1 -std=c++2a -verify %s -DIMPORT_ERROR=1
+// RUN: %clang_cc1 -std=c++2a -verify %s -DIMPORT_ERROR=2
+
+module;
+
+#if IMPORT_ERROR != 2
+struct import { struct inner {}; };
+#endif
+struct module { struct inner {}; };
+
+constexpr int n = 123;
+
+export module m; // #1
+
+// Import errors are fatal, so we test them in isolation.
+#if IMPORT_ERROR == 1
+import x = {}; // expected-error {{module 'x' not found}}
+
+#elif IMPORT_ERROR == 2
+struct X;
+template<int> struct import;
+template<> struct import<n> {
+ static X y;
+};
+
+// This is not valid because the 'import <n>' is a pp-import, even though it
+// grammatically can't possibly be an import declaration.
+struct X {} import<n>::y; // expected-error {{'n' file not found}}
+
+#else
+module y = {}; // expected-error {{multiple module declarations}} expected-error 2{{}}
+// expected-note@#1 {{previous module declaration}}
+
+::import x = {};
+::module y = {};
+
+import::inner xi = {};
+module::inner yi = {};
+
+namespace N {
+ module a;
+ import b;
+}
+
+extern "C++" module cxxm;
+extern "C++" import cxxi;
+
+template<typename T> module module_var_template;
+
+// This is a variable named 'import' that shadows the type 'import' above.
+struct X {} import;
+#endif
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-associated-namespaces-classes.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-associated-namespaces-classes.cpp
new file mode 100644
index 0000000000..7562e64b17
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-associated-namespaces-classes.cpp
@@ -0,0 +1,344 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+
+// Attempt to test each rule for forming associated namespaces
+// and classes as described in [basic.lookup.argdep]p2.
+
+// fundamental type: no associated namespace and no associated class
+namespace adl_fundamental_type {
+ constexpr int g(char) { return 1; } // #1
+ template <typename T> constexpr int foo(T t) { return g(t); }
+ constexpr int g(int) { return 2; } // #2 not found
+ void test() {
+ static_assert(foo(0) == 1); // ok, #1
+ }
+}
+
+// class type:
+// associated classes: itself, the class of which it is a member (if any),
+// direct and indirect base classes
+// associated namespaces: innermost enclosing namespaces of associated classes
+namespace adl_class_type {
+ // associated class: itself, simple case
+ namespace X1 {
+ namespace N {
+ struct S {};
+ void f(S); // found
+ }
+ void g(N::S); // not found
+ };
+ void test1() {
+ f(X1::N::S{}); // ok
+ g(X1::N::S{}); // expected-error {{use of undeclared identifier}}
+ }
+
+ // associated class: itself, local type
+ namespace X2 {
+ auto foo() {
+ struct S {} s;
+ return s;
+ }
+ using S = decltype(foo());
+ void f(S); // #1
+ }
+ void test2() {
+ f(X2::S{}); // This is well-formed; X2 is the innermost enclosing namespace
+ // of the local struct S. Calls #1.
+ }
+
+ // associated class: the parent class
+ namespace X3 {
+ struct S {
+ struct T {};
+ friend void f(T);
+ };
+ }
+ void test3() {
+ f(X3::S::T{}); // ok
+ }
+
+ // associated class: direct and indirect base classes
+ namespace X4 {
+ namespace IndirectBaseNamespace {
+ struct IndirectBase {};
+ void f(IndirectBase); // #1
+ }
+ namespace DirectBaseNamespace {
+ struct DirectBase : IndirectBaseNamespace::IndirectBase {};
+ void g(DirectBase); // #2
+ }
+ struct S : DirectBaseNamespace::DirectBase {};
+ }
+ void test4() {
+ f(X4::S{}); // ok, #1
+ g(X4::S{}); // ok, #2
+ }
+
+ // associated class: itself, lambda
+ namespace X5 {
+ namespace N {
+ auto get_lambda() { return [](){}; }
+ void f(decltype(get_lambda()));
+ }
+
+ void test5() {
+ auto lambda = N::get_lambda();
+ f(lambda); // ok
+ }
+ }
+
+ // The parameter types and return type of a lambda's operator() do not
+ // contribute to the associated namespaces and classes of the lambda itself.
+ namespace X6 {
+ namespace N {
+ struct A {};
+ template<class T> constexpr int f(T) { return 1; }
+ }
+
+ constexpr int f(N::A (*)()) { return 2; }
+ constexpr int f(void (*)(N::A)) { return 3; }
+
+ void test() {
+ constexpr auto lambda = []() -> N::A { return {}; };
+ static_assert(f(lambda) == 2);
+
+ constexpr auto lambda2 = [](N::A) {};
+ static_assert(f(lambda2) == 3);
+ }
+ }
+} // namespace adl_class_type
+
+// class template specialization: as for class type plus
+// for non-type template arguments:
+// - nothing
+// for type template arguments:
+// - associated namespaces and classes of the type template arguments
+// for template template arguments:
+// - namespaces of which template template arguments are member of
+// - classes of which member template used as template template arguments
+// are member of
+namespace adl_class_template_specialization_type {
+ // non-type template argument
+ namespace X1 {
+ namespace BaseNamespace { struct Base {}; }
+ namespace N { struct S : BaseNamespace::Base {}; }
+ template <N::S *> struct C {};
+ namespace N {
+ template <S *p> void X1_f(C<p>); // #1
+ }
+ namespace BaseNamespace {
+ template <N::S *p> void X1_g(C<p>); // #2
+ }
+ template <N::S *p> void X1_h(C<p>); // #3
+ }
+ void test1() {
+ constexpr X1::N::S *p = nullptr;
+ X1::C<p> c;
+ X1_f(c); // N is not added to the set of associated namespaces
+ // and #1 is not found...
+ // expected-error@-2 {{use of undeclared identifier}}
+ X1_g(c); // ... nor is #2 ...
+ // expected-error@-1 {{use of undeclared identifier}}
+ X1_h(c); // ... but the namespace X1 is added and #3 is found.
+ }
+
+ // type template argument
+ namespace X2 {
+ template <typename T> struct C {};
+ namespace BaseNamespace { struct Base {}; }
+ namespace N { struct S : BaseNamespace::Base {}; }
+ namespace N {
+ template <typename T> void X2_f(C<T>); // #1
+ }
+ namespace BaseNamespace {
+ template <typename T> void X2_g(C<T>); // #2
+ }
+ template <typename T> void X2_h(C<T>); // #2
+ }
+ void test2() {
+ X2::C<X2::N::S> c;
+ X2_f(c); // N is added to the set of associated namespaces and #1 is found.
+ X2_g(c); // Similarly BaseNamespace is added and #2 is found.
+ X2_h(c); // As before, X2 is also added and #3 is found.
+ }
+
+ // template template argument
+ namespace X3 {
+ template <template <typename> class TT> struct C {};
+ namespace N {
+ template <typename T> struct Z {};
+ void X3_f(C<Z>); // #1
+ }
+ struct M {
+ template <typename T> struct Z {};
+ friend void X3_g(C<Z>); // #2
+ };
+ }
+ void test3() {
+ X3::C<X3::N::Z> c1;
+ X3::C<X3::M::Z> c2;
+ X3_f(c1); // ok, namespace N is added, #1
+ X3_g(c2); // ok, struct M is added, #2
+ }
+}
+
+// enumeration type:
+// associated namespace: innermost enclosing namespace of its declaration.
+// associated class: if the enumeration is a class member, the member's class.
+namespace adl_enumeration_type {
+ namespace N {
+ enum E : int;
+ void f(E);
+ struct S {
+ enum F : int;
+ friend void g(F);
+ };
+ auto foo() {
+ enum G {} g;
+ return g;
+ }
+ using G = decltype(foo());
+ void h(G);
+ }
+
+ void test() {
+ N::E e;
+ f(e); // ok
+ N::S::F f;
+ g(f); // ok
+ N::G g;
+ h(g); // ok
+
+ }
+}
+
+// pointer and reference type:
+// associated namespaces and classes of the pointee type
+// array type:
+// associated namespaces and classes of the base type
+namespace adl_point_array_reference_type {
+ namespace N {
+ struct S {};
+ void f(S *);
+ void f(S &);
+ }
+
+ void test() {
+ N::S *p;
+ f(p); // ok
+ extern N::S &r;
+ f(r); // ok
+ N::S a[2];
+ f(a); // ok
+ }
+}
+
+// function type:
+// associated namespaces and classes of the function parameter types
+// and the return type.
+namespace adl_function_type {
+ namespace M { struct T; }
+ namespace N {
+ struct S {};
+ void f(S (*)(M::T));
+ };
+ namespace M {
+ struct T {};
+ void g(N::S (*)(T));
+ }
+
+ void test() {
+ extern N::S x(M::T);
+ f(x); // ok
+ g(x); // ok
+ }
+}
+
+// pointer to member function:
+// associated namespaces and classes of the class, parameter types
+// and return type.
+namespace adl_pointer_to_member_function {
+ namespace M { struct C; }
+ namespace L { struct T; }
+ namespace N {
+ struct S {};
+ void f(N::S (M::C::*)(L::T));
+ }
+ namespace L {
+ struct T {};
+ void g(N::S (M::C::*)(L::T));
+ }
+ namespace M {
+ struct C {};
+ void h(N::S (M::C::*)(L::T));
+ }
+
+ void test() {
+ N::S (M::C::*p)(L::T);
+ f(p); // ok
+ g(p); // ok
+ h(p); // ok
+ }
+}
+
+// pointer to member:
+// associated namespaces and classes of the class and of the member type.
+namespace adl_pointer_to_member {
+ namespace M { struct C; }
+ namespace N {
+ struct S {};
+ void f(N::S (M::C::*));
+ }
+ namespace M {
+ struct C {};
+ void g(N::S (M::C::*));
+ }
+
+ void test() {
+ N::S (M::C::*p);
+ f(p); // ok
+ g(p); // ok
+ }
+}
+
+// [...] if the argument is the name or address of a set of overloaded
+// functions and/or function templates, its associated classes and namespaces
+// are the union of those associated with each of the members of the set,
+// i.e., the classes and namespaces associated with its parameter types and
+// return type.
+//
+// Additionally, if the aforementioned set of overloaded functions is named
+// with a template-id, its associated classes and namespaces also include
+// those of its type template-arguments and its template template-arguments.
+//
+// CWG 33 for the union rule. CWG 997 for the template-id rule.
+namespace adl_overload_set {
+ namespace N {
+ struct S {};
+ constexpr int f(int (*g)()) { return g(); }
+ // expected-note@-1 2{{'N::f' declared here}}
+ template <typename T> struct Q;
+ }
+
+ constexpr int g1() { return 1; }
+ constexpr int g1(N::S) { return 2; }
+
+ template <typename T> constexpr int g2() { return 3; }
+
+ // Inspired from CWG 997.
+ constexpr int g3() { return 4; }
+ template <typename T> constexpr int g3(T, N::Q<T>) { return 5; }
+
+ void test() {
+ static_assert(f(g1) == 1, ""); // Well-formed from the union rule above
+ static_assert(f(g2<N::S>) == 3, ""); // FIXME: Well-formed from the template-id rule above.
+ // expected-error@-1 {{use of undeclared}}
+
+ // A objection was raised during review against implementing the
+ // template-id rule. Currently only GCC implements it. Implementing
+ // it would weaken the argument to remove it in the future since
+ // actual real code might start to depend on it.
+
+ static_assert(f(g3) == 4, ""); // FIXME: Also well-formed from the union rule.
+ // expected-error@-1 {{use of undeclared}}
+ }
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-inline-namespace.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-inline-namespace.cpp
new file mode 100644
index 0000000000..19054f6415
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-inline-namespace.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+// C++11 [basic.lookup.argdep]p2
+//
+// [...] If an associated namespace is an inline namespace (10.3.1), its
+// enclosing namespace is also included in the set. If an associated
+// namespace directly contains inline namespaces, those inline namespaces
+// are also included in the set.
+
+namespace test1 {
+ namespace L {
+ namespace M {
+ inline namespace N {
+ inline namespace O {
+ struct S {};
+ void f1(S);
+ }
+ void f2(S);
+ }
+ void f3(S);
+ }
+ void f4(M::S); // expected-note {{declared here}}
+ }
+
+ void test() {
+ L::M::S s;
+ f1(s); // ok
+ f2(s); // ok
+ f3(s); // ok
+ f4(s); // expected-error {{use of undeclared}}
+ }
+}
+
+namespace test2 {
+ namespace L {
+ struct S {};
+ inline namespace M {
+ inline namespace N {
+ inline namespace O {
+ void f1(S);
+ }
+ void f2(S);
+ }
+ void f3(S);
+ }
+ void f4(S);
+ }
+
+ void test() {
+ L::S s;
+ f1(s); // ok
+ f2(s); // ok
+ f3(s); // ok
+ f4(s); // ok
+ }
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp
index e352bbe83c..b19c81f2f3 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp
@@ -132,3 +132,19 @@ namespace test8 {
test8_function(ref);
}
}
+
+
+
+// [...] Typedef names and using-declarations used to specify the types
+// do not contribute to this set.
+namespace typedef_names_and_using_declarations {
+ namespace N { struct S {}; void f(S); }
+ namespace M { typedef N::S S; void g1(S); } // expected-note {{declared here}}
+ namespace L { using N::S; void g2(S); } // expected-note {{declared here}}
+ void test() {
+ M::S s;
+ f(s); // ok
+ g1(s); // expected-error {{use of undeclared}}
+ g2(s); // expected-error {{use of undeclared}}
+ }
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp
index c4c2c8d605..88e06fc9ae 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp
@@ -18,3 +18,67 @@ namespace test0 {
}
};
}
+
+// If X contains [...] then Y is empty.
+// - a declaration of a class member
+namespace test_adl_suppression_by_class_member {
+ namespace N {
+ struct T {};
+ void f(T); // expected-note {{declared here}}
+ }
+ struct S {
+ void f();
+ void test() {
+ N::T t;
+ f(t); // expected-error {{too many arguments}}
+ }
+ };
+}
+
+// - a block-scope function declaration that is not a using-declaration
+namespace test_adl_suppression_by_block_scope {
+ namespace N {
+ struct S {};
+ void f(S);
+ }
+ namespace M { void f(int); } // expected-note 2{{candidate}}
+ void test1() {
+ N::S s;
+ using M::f;
+ f(s); // ok
+ }
+
+ void test2() {
+ N::S s;
+ extern void f(char); // expected-note {{passing argument to parameter here}}
+ f(s); // expected-error {{no viable conversion from 'N::S' to 'char'}}
+ }
+
+ void test3() {
+ N::S s;
+ extern void f(char); // expected-note {{candidate}}
+ using M::f;
+ f(s); // expected-error {{no matching function}}
+ }
+
+ void test4() {
+ N::S s;
+ using M::f;
+ extern void f(char); // expected-note {{candidate}}
+ f(s); // expected-error {{no matching function}}
+ }
+
+}
+
+// - a declaration that is neither a function nor a function template
+namespace test_adl_suppression_by_non_function {
+ namespace N {
+ struct S {};
+ void f(S);
+ }
+ void test() {
+ extern void (*f)();
+ N::S s;
+ f(s); // expected-error {{too many arguments}}
+ }
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp
index 2292fc540c..910eb0c1a8 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp
@@ -67,3 +67,96 @@ namespace test1 {
foo(a, 10); // expected-error {{no matching function for call to 'foo'}}
}
}
+
+
+// Check the rules described in p4:
+// When considering an associated namespace, the lookup is the same as the lookup
+// performed when the associated namespace is used as a qualifier (6.4.3.2) except that:
+
+// - Any using-directives in the associated namespace are ignored.
+namespace test_using_directives {
+ namespace M { struct S; }
+ namespace N {
+ void f(M::S); // expected-note {{declared here}}
+ }
+ namespace M {
+ using namespace N;
+ struct S {};
+ }
+ void test() {
+ M::S s;
+ f(s); // expected-error {{use of undeclared}}
+ M::f(s); // ok
+ }
+}
+
+// - Any namespace-scope friend functions or friend function templates declared in
+// associated classes are visible within their respective namespaces even if
+// they are not visible during an ordinary lookup
+// (Note: For the friend declaration to be visible, the corresponding class must be
+// included in the set of associated classes. Merely including the namespace in
+// the set of associated namespaces is not enough.)
+namespace test_friend1 {
+ namespace N {
+ struct S;
+ struct T {
+ friend void f(S); // #1
+ };
+ struct S { S(); S(T); };
+ }
+
+ void test() {
+ N::S s;
+ N::T t;
+ f(s); // expected-error {{use of undeclared}}
+ f(t); // ok, #1
+ }
+}
+
+// credit: Arthur O’Dwyer
+namespace test_friend2 {
+ struct A {
+ struct B {
+ struct C {};
+ };
+ friend void foo(...); // #1
+ };
+
+ struct D {
+ friend void foo(...); // #2
+ };
+ template<class> struct E {
+ struct F {};
+ };
+
+ template<class> struct G {};
+ template<class> struct H {};
+ template<class> struct I {};
+ struct J { friend void foo(...) {} }; // #3
+
+ void test() {
+ A::B::C c;
+ foo(c); // #1 is not visible since A is not an associated class
+ // expected-error@-1 {{use of undeclared}}
+ E<D>::F f;
+ foo(f); // #2 is not visible since D is not an associated class
+ // expected-error@-1 {{use of undeclared}}
+ G<H<I<J> > > j;
+ foo(j); // ok, #3.
+ }
+}
+
+// - All names except those of (possibly overloaded) functions and
+// function templates are ignored.
+namespace test_other_names {
+ namespace N {
+ struct S {};
+ struct Callable { void operator()(S); };
+ static struct Callable Callable;
+ }
+
+ void test() {
+ N::S s;
+ Callable(s); // expected-error {{use of undeclared}}
+ }
+}
diff --git a/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp b/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp
new file mode 100644
index 0000000000..55c5ce6c4c
--- /dev/null
+++ b/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp
@@ -0,0 +1,86 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: echo '#ifndef FOO_H' > %t/foo.h
+// RUN: echo '#define FOO_H' >> %t/foo.h
+// RUN: echo 'extern int in_header;' >> %t/foo.h
+// RUN: echo '#endif' >> %t/foo.h
+// RUN: %clang_cc1 -std=c++2a -I%t -emit-module-interface -DINTERFACE %s -o %t.pcm
+// RUN: %clang_cc1 -std=c++2a -I%t -fmodule-file=%t.pcm -DIMPLEMENTATION %s -verify -fno-modules-error-recovery
+// RUN: %clang_cc1 -std=c++2a -I%t -fmodule-file=%t.pcm %s -verify -fno-modules-error-recovery
+
+#ifdef INTERFACE
+module;
+#include "foo.h"
+int global_module_fragment;
+export module A;
+export int exported;
+int not_exported;
+static int internal;
+
+module :private;
+int not_exported_private;
+static int internal_private;
+#else
+
+#ifdef IMPLEMENTATION
+module;
+#endif
+
+void test_early() {
+ in_header = 1; // expected-error {{missing '#include "foo.h"'; 'in_header' must be declared before it is used}}
+ // expected-note@*{{previous}}
+
+ global_module_fragment = 1; // expected-error {{missing '#include'; 'global_module_fragment' must be declared before it is used}}
+
+ exported = 1; // expected-error {{must be imported from module 'A'}}
+ // expected-note@p2.cpp:16 {{previous}}
+
+ not_exported = 1; // expected-error {{undeclared identifier}}
+
+ internal = 1; // expected-error {{undeclared identifier}}
+
+ not_exported_private = 1; // expected-error {{undeclared identifier}}
+
+ internal_private = 1; // expected-error {{undeclared identifier}}
+}
+
+#ifdef IMPLEMENTATION
+module A;
+#else
+import A;
+#endif
+
+void test_late() {
+ in_header = 1; // expected-error {{missing '#include "foo.h"'; 'in_header' must be declared before it is used}}
+ // expected-note@*{{previous}}
+
+ global_module_fragment = 1; // expected-error {{missing '#include'; 'global_module_fragment' must be declared before it is used}}
+
+ exported = 1;
+
+ not_exported = 1;
+#ifndef IMPLEMENTATION
+ // expected-error@-2 {{undeclared identifier 'not_exported'; did you mean 'exported'}}
+ // expected-note@p2.cpp:16 {{declared here}}
+#endif
+
+ internal = 1;
+#ifndef IMPLEMENTATION
+ // FIXME: should not be visible here
+ // expected-error@-3 {{undeclared identifier}}
+#endif
+
+ not_exported_private = 1;
+#ifndef IMPLEMENTATION
+ // FIXME: should not be visible here
+ // expected-error@-3 {{undeclared identifier}}
+#endif
+
+ internal_private = 1;
+#ifndef IMPLEMENTATION
+ // FIXME: should not be visible here
+ // expected-error@-3 {{undeclared identifier}}
+#endif
+}
+
+#endif
diff --git a/test/CXX/class.access/p4.cpp b/test/CXX/class.access/p4.cpp
index 6d452d8199..a2d0da1a83 100644
--- a/test/CXX/class.access/p4.cpp
+++ b/test/CXX/class.access/p4.cpp
@@ -514,16 +514,12 @@ namespace test17 {
}
namespace test18 {
- template <class T> class A {};
- class B : A<int> {
+ template <class T> class A {}; // expected-note {{member is declared here}}
+ class B : A<int> { // expected-note {{constrained by implicitly private inheritance here}}
A<int> member;
};
-
- // FIXME: this access to A should be forbidden (because C++ is dumb),
- // but LookupResult can't express the necessary information to do
- // the check, so we aggressively suppress access control.
class C : B {
- A<int> member;
+ A<int> member; // expected-error {{'A' is a private member of 'test18::A<int>'}}
};
}
diff --git a/test/CXX/class/class.union/class.union.anon/p4.cpp b/test/CXX/class/class.union/class.union.anon/p4.cpp
index cc54ba4066..a12ec38503 100644
--- a/test/CXX/class/class.union/class.union.anon/p4.cpp
+++ b/test/CXX/class/class.union/class.union.anon/p4.cpp
@@ -2,7 +2,7 @@
union U {
int x = 0; // expected-note {{previous initialization is here}}
- union {};
+ union {}; // expected-warning {{does not declare anything}}
union {
int z;
int y = 1; // expected-error {{initializing multiple members of union}}
diff --git a/test/CXX/cpp/cpp.module/Inputs/attrs.h b/test/CXX/cpp/cpp.module/Inputs/attrs.h
new file mode 100644
index 0000000000..bc6b78b056
--- /dev/null
+++ b/test/CXX/cpp/cpp.module/Inputs/attrs.h
@@ -0,0 +1 @@
+#define ATTRS [[ ]]
diff --git a/test/CXX/cpp/cpp.module/Inputs/empty.h b/test/CXX/cpp/cpp.module/Inputs/empty.h
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/CXX/cpp/cpp.module/Inputs/empty.h
diff --git a/test/CXX/cpp/cpp.module/p1.cpp b/test/CXX/cpp/cpp.module/p1.cpp
new file mode 100644
index 0000000000..d56375e1fc
--- /dev/null
+++ b/test/CXX/cpp/cpp.module/p1.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++2a -emit-header-module -fmodule-name=attrs -x c++-header %S/Inputs/empty.h %S/Inputs/attrs.h -o %t.pcm
+// RUN: %clang_cc1 -std=c++2a %s -fmodule-file=%t.pcm -E -verify -I%S/Inputs | FileCheck %s
+
+#define SEMI ;
+// expected-error@+1 {{semicolon terminating header import declaration cannot be produced by a macro}}
+import "empty.h" SEMI // CHECK: import attrs.{{.*}};
+
+#define IMPORT import "empty.h"
+IMPORT; // CHECK: import attrs.{{.*}};
+
+#define IMPORT_ANGLED import <empty.h>
+IMPORT_ANGLED; // CHECK: import attrs.{{.*}};
+
+// Ensure that macros only become visible at the semicolon.
+// CHECK: import attrs.{{.*}} ATTRS ;
+import "attrs.h" ATTRS ;
+// CHECK: {{\[\[}} ]] int n;
+ATTRS int n;
diff --git a/test/CXX/cpp/cpp.module/p2.cpp b/test/CXX/cpp/cpp.module/p2.cpp
new file mode 100644
index 0000000000..d5bf4fa1a6
--- /dev/null
+++ b/test/CXX/cpp/cpp.module/p2.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -std=c++2a -emit-header-module -fmodule-name=attrs -x c++-header %S/Inputs/empty.h %S/Inputs/attrs.h -o %t.pcm
+// RUN: %clang_cc1 -std=c++2a %s -fmodule-file=%t.pcm -fsyntax-only -verify -I%S/Inputs
+
+template<int> struct import; // expected-note 2{{previous}}
+constexpr struct { int h; } empty = {0};
+struct A;
+struct B;
+struct C;
+template<> struct import<0> {
+ static A a;
+ static B b;
+ static C c;
+};
+
+// OK, not an import-declaration.
+struct A {}
+::import
+<empty.h>::a;
+
+// This is invalid: the tokens after 'import' are a header-name, so cannot be
+// parsed as a template-argument-list.
+struct B {}
+import // expected-error {{redefinition of 'import'}} expected-error {{expected ';'}}
+<empty.h>::b; // (error recovery skips these tokens)
+
+// Likewise, this is ill-formed after the tokens are reconstituted into a
+// header-name token.
+struct C {}
+import // expected-error {{redefinition of 'import'}} expected-error {{expected ';'}}
+<
+empty.h // (error recovery skips these tokens)
+>::c;
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp
index 686aac2802..e435bee2c8 100644
--- a/test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -verify %s
+// RUN: %clang_cc1 -std=c++11 -verify %s -triple x86_64-linux-gnu
alignas(double) void f(); // expected-error {{'alignas' attribute only applies to variables, data members and tag types}}
alignas(double) unsigned char c[sizeof(double)]; // expected-note {{previous}}
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p3.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p3.cpp
index 551df38a81..5f715a1ec2 100644
--- a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p3.cpp
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p3.cpp
@@ -5,9 +5,17 @@ static_assert(__has_cpp_attribute(maybe_unused) == 201603, "");
struct [[maybe_unused]] S {};
+enum E1 {
+ EnumVal [[maybe_unused]],
+ UsedEnumVal,
+};
+
void f() {
int x; // expected-warning {{unused variable}}
typedef int I; // expected-warning {{unused typedef 'I'}}
+ E1 e;
+ switch (e) { // expected-warning {{enumeration value 'UsedEnumVal' not handled in switch}}
+ }
// Should not warn about these due to not being used.
[[maybe_unused]] int y;
@@ -17,10 +25,16 @@ void f() {
S s;
maybe_unused_int test;
y = 12;
+ switch (e) {
+ case UsedEnumVal:
+ break;
+ }
}
#ifdef EXT
// expected-warning@6 {{use of the 'maybe_unused' attribute is a C++17 extension}}
-// expected-warning@13 {{use of the 'maybe_unused' attribute is a C++17 extension}}
-// expected-warning@14 {{use of the 'maybe_unused' attribute is a C++17 extension}}
+// expected-warning@9 {{use of the 'maybe_unused' attribute is a C++17 extension}}
+// expected-warning@9 {{attributes on an enumerator declaration are a C++17 extension}}
+// expected-warning@21 {{use of the 'maybe_unused' attribute is a C++17 extension}}
+// expected-warning@22 {{use of the 'maybe_unused' attribute is a C++17 extension}}
#endif
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
index 54aabe6ef3..e24e63178e 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
@@ -181,8 +181,8 @@ union Empty {
} constexpr empty1;
struct EmptyVariant {
- union {};
- struct {};
+ union {}; // expected-warning {{does not declare anything}}
+ struct {}; // expected-warning {{does not declare anything}}
constexpr EmptyVariant() {} // ok
} constexpr empty2;
diff --git a/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
index c2f3b5a045..2b7886d383 100644
--- a/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
+++ b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
@@ -56,8 +56,8 @@ constexpr S5::S5() = default;
static_assert(S5().m == 4, "");
-// An explicitly-defaulted function may have an exception specification only if
-// it is compatible with the exception specification on an implicit declaration.
+// An explicitly-defaulted function may have a different exception specification
+// from the exception specification on an implicit declaration.
struct E1 {
E1() noexcept = default;
E1(const E1&) noexcept = default;
@@ -67,13 +67,24 @@ struct E1 {
~E1() noexcept = default;
};
struct E2 {
- E2() noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted default constructor does not match the calculated one}}
- E2(const E2&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted copy constructor does not match the calculated one}}
- E2(E2&&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted move constructor does not match the calculated one}}
- E2 &operator=(const E2&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted copy assignment operator does not match the calculated one}}
- E2 &operator=(E2&&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted move assignment operator does not match the calculated one}}
- ~E2() noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted destructor does not match the calculated one}}
+ E2() noexcept(false) = default;
+ E2(const E2&) noexcept(false) = default;
+ E2(E2&&) noexcept(false) = default;
+ E2 &operator=(const E2&) noexcept(false) = default;
+ E2 &operator=(E2&&) noexcept(false) = default;
+ ~E2() noexcept(false) = default;
};
+E2 e2;
+E2 make_e2() noexcept;
+void take_e2(E2&&) noexcept;
+static_assert(!noexcept(E2()), "");
+static_assert(!noexcept(E2(e2)), "");
+static_assert(!noexcept(E2(static_cast<E2&&>(e2))), "");
+static_assert(!noexcept(e2 = e2), "");
+static_assert(!noexcept(e2 = static_cast<E2&&>(e2)), "");
+// FIXME: This expression results in destruction of an E2 temporary; the
+// noexcept expression should evaluate to false.
+static_assert(noexcept(take_e2(make_e2())), "");
// If a function is explicitly defaulted on its first declaration
// -- it is implicitly considered to have the same exception-specification as
diff --git a/test/CXX/drs/dr0xx.cpp b/test/CXX/drs/dr0xx.cpp
index 048187814d..53bd6f3f05 100644
--- a/test/CXX/drs/dr0xx.cpp
+++ b/test/CXX/drs/dr0xx.cpp
@@ -413,6 +413,36 @@ namespace dr33 { // dr33: yes
void g(X::S);
template<typename Z> Z g(Y::T);
void h() { f(&g); } // expected-error {{ambiguous}}
+
+ template<typename T> void t(X::S);
+ template<typename T, typename U = void> void u(X::S); // expected-error 0-1{{default template argument}}
+ void templ() { f(t<int>); f(u<int>); }
+
+ // Even though v<int> cannot select the first overload, ADL considers it
+ // and adds namespace Z to the set of associated namespaces, and then picks
+ // Z::f even though that function has nothing to do with any associated type.
+ namespace Z { struct Q; void f(void(*)()); }
+ template<int> Z::Q v();
+ template<typename> void v();
+ void unrelated_templ() { f(v<int>); }
+
+ namespace dependent {
+ struct X {};
+ template<class T> struct Y {
+ friend int operator+(X, void(*)(Y)) {}
+ };
+
+ template<typename T> void f(Y<T>);
+ int use = X() + f<int>; // expected-error {{invalid operands}}
+ }
+
+ namespace member {
+ struct Q {};
+ struct Y { friend int operator+(Q, Y (*)()); };
+ struct X { template<typename> static Y f(); };
+ int m = Q() + X().f<int>; // ok
+ int n = Q() + (&(X().f<int>)); // ok
+ }
}
// dr34: na
@@ -839,18 +869,17 @@ namespace dr68 { // dr68: yes
}
namespace dr69 { // dr69: yes
- template<typename T> static void f() {}
+ template<typename T> static void f() {} // #dr69-f
// FIXME: Should we warn here?
inline void g() { f<int>(); }
- // FIXME: This should be rejected, per [temp.explicit]p11.
- extern template void f<char>();
+ extern template void f<char>(); // expected-error {{explicit instantiation declaration of 'f' with internal linkage}}
#if __cplusplus < 201103L
// expected-error@-2 {{C++11 extension}}
#endif
template<void(*)()> struct Q {};
Q<&f<int> > q;
#if __cplusplus < 201103L
- // expected-error@-2 {{internal linkage}} expected-note@-11 {{here}}
+ // expected-error@-2 {{internal linkage}} expected-note@#dr69-f {{here}}
#endif
}
diff --git a/test/CXX/drs/dr13xx.cpp b/test/CXX/drs/dr13xx.cpp
index 208ab8a03b..1d61e8687e 100644
--- a/test/CXX/drs/dr13xx.cpp
+++ b/test/CXX/drs/dr13xx.cpp
@@ -272,7 +272,7 @@ namespace dr1359 { // dr1359: 3.5
union A { constexpr A() = default; };
union B { constexpr B() = default; int a; }; // expected-error {{not constexpr}} expected-note 2{{candidate}}
union C { constexpr C() = default; int a, b; }; // expected-error {{not constexpr}} expected-note 2{{candidate}}
- struct X { constexpr X() = default; union {}; };
+ struct X { constexpr X() = default; union {}; }; // expected-error {{does not declare anything}}
struct Y { constexpr Y() = default; union { int a; }; }; // expected-error {{not constexpr}} expected-note 2{{candidate}}
constexpr A a = A();
diff --git a/test/CXX/drs/dr14xx.cpp b/test/CXX/drs/dr14xx.cpp
index eb5ba3db44..eb086178fc 100644
--- a/test/CXX/drs/dr14xx.cpp
+++ b/test/CXX/drs/dr14xx.cpp
@@ -13,22 +13,22 @@ namespace dr1460 { // dr1460: 3.5
#if __cplusplus >= 201103L
namespace DRExample {
union A {
- union {};
- union {};
+ union {}; // expected-error {{does not declare anything}}
+ union {}; // expected-error {{does not declare anything}}
constexpr A() {}
};
constexpr A a = A();
union B {
- union {};
- union {};
+ union {}; // expected-error {{does not declare anything}}
+ union {}; // expected-error {{does not declare anything}}
constexpr B() = default;
};
constexpr B b = B();
union C {
- union {};
- union {};
+ union {}; // expected-error {{does not declare anything}}
+ union {}; // expected-error {{does not declare anything}}
};
constexpr C c = C();
#if __cplusplus > 201103L
@@ -40,7 +40,7 @@ namespace dr1460 { // dr1460: 3.5
union A {};
union B { int n; }; // expected-note +{{here}}
union C { int n = 0; };
- struct D { union {}; };
+ struct D { union {}; }; // expected-error {{does not declare anything}}
struct E { union { int n; }; }; // expected-note +{{here}}
struct F { union { int n = 0; }; };
@@ -66,7 +66,7 @@ namespace dr1460 { // dr1460: 3.5
union A { constexpr A() = default; };
union B { int n; constexpr B() = default; }; // expected-error {{not constexpr}}
union C { int n = 0; constexpr C() = default; };
- struct D { union {}; constexpr D() = default; };
+ struct D { union {}; constexpr D() = default; }; // expected-error {{does not declare anything}}
struct E { union { int n; }; constexpr E() = default; }; // expected-error {{not constexpr}}
struct F { union { int n = 0; }; constexpr F() = default; };
diff --git a/test/CXX/drs/dr15xx.cpp b/test/CXX/drs/dr15xx.cpp
index cca4509fa0..bd714865ee 100644
--- a/test/CXX/drs/dr15xx.cpp
+++ b/test/CXX/drs/dr15xx.cpp
@@ -236,6 +236,16 @@ namespace dr1560 { // dr1560: 3.5
const X &x = true ? get() : throw 0;
}
+namespace dr1563 { // dr1563: yes
+#if __cplusplus >= 201103L
+ double bar(double) { return 0.0; }
+ float bar(float) { return 0.0f; }
+
+ using fun = double(double);
+ fun &foo{bar}; // ok
+#endif
+}
+
namespace dr1573 { // dr1573: 3.9
#if __cplusplus >= 201103L
// ellipsis is inherited (p0136r1 supersedes this part).
diff --git a/test/CXX/drs/dr16xx.cpp b/test/CXX/drs/dr16xx.cpp
index 4f2f06e0d0..b5047e8fe2 100644
--- a/test/CXX/drs/dr16xx.cpp
+++ b/test/CXX/drs/dr16xx.cpp
@@ -284,6 +284,54 @@ namespace dr1687 { // dr1687: 7
#endif
}
+namespace dr1690 { // dr1690: 9
+ // See also the various tests in "CXX/basic/basic.lookup/basic.lookup.argdep".
+#if __cplusplus >= 201103L
+ namespace N {
+ static auto lambda = []() { struct S {} s; return s; };
+ void f(decltype(lambda()));
+ }
+
+ void test() {
+ auto s = N::lambda();
+ f(s); // ok
+ }
+#endif
+}
+
+namespace dr1691 { // dr1691: 9
+#if __cplusplus >= 201103L
+ namespace N {
+ namespace M {
+ enum E : int;
+ void f(E);
+ }
+ enum M::E : int {};
+ void g(M::E); // expected-note {{declared here}}
+ }
+ void test() {
+ N::M::E e;
+ f(e); // ok
+ g(e); // expected-error {{use of undeclared}}
+ }
+#endif
+}
+
+namespace dr1692 { // dr1692: 9
+ namespace N {
+ struct A {
+ struct B {
+ struct C {};
+ };
+ };
+ void f(A::B::C);
+ }
+ void test() {
+ N::A::B::C c;
+ f(c); // ok
+ }
+}
+
namespace dr1696 { // dr1696: 7
namespace std_examples {
#if __cplusplus >= 201402L
diff --git a/test/CXX/drs/dr17xx.cpp b/test/CXX/drs/dr17xx.cpp
index a917412adc..ca55c42977 100644
--- a/test/CXX/drs/dr17xx.cpp
+++ b/test/CXX/drs/dr17xx.cpp
@@ -76,3 +76,30 @@ namespace dr1758 { // dr1758: 3.7
A a{b};
#endif
}
+
+namespace dr1722 { // dr1722: 9
+#if __cplusplus >= 201103L
+void f() {
+ const auto lambda = [](int x) { return x + 1; };
+ // Without the DR applied, this static_assert would fail.
+ static_assert(
+ noexcept((int (*)(int))(lambda)),
+ "Lambda-to-function-pointer conversion is expected to be noexcept");
+}
+#endif
+} // namespace dr1722
+
+namespace dr1778 { // dr1778: 9
+ // Superseded by P1286R2.
+#if __cplusplus >= 201103L
+ struct A { A() noexcept(true) = default; };
+ struct B { B() noexcept(false) = default; };
+ static_assert(noexcept(A()), "");
+ static_assert(!noexcept(B()), "");
+
+ struct C { A a; C() noexcept(false) = default; };
+ struct D { B b; D() noexcept(true) = default; };
+ static_assert(!noexcept(C()), "");
+ static_assert(noexcept(D()), "");
+#endif
+}
diff --git a/test/CXX/drs/dr19xx.cpp b/test/CXX/drs/dr19xx.cpp
index e6cf337da0..a1e8c76435 100644
--- a/test/CXX/drs/dr19xx.cpp
+++ b/test/CXX/drs/dr19xx.cpp
@@ -84,6 +84,7 @@ namespace dr1940 { // dr1940: yes
static union {
static_assert(true, ""); // ok
static_assert(false, ""); // expected-error {{static_assert failed}}
+ int not_empty;
};
#endif
}
diff --git a/test/CXX/drs/dr23xx.cpp b/test/CXX/drs/dr23xx.cpp
new file mode 100644
index 0000000000..87db0d4c9b
--- /dev/null
+++ b/test/CXX/drs/dr23xx.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+#if __cplusplus <= 201103L
+// expected-no-diagnostics
+#endif
+
+namespace dr2387 { // dr2387: 9
+#if __cplusplus >= 201402L
+ template<int> int a = 0;
+ extern template int a<0>; // ok
+
+ template<int> static int b = 0;
+ extern template int b<0>; // expected-error {{internal linkage}}
+
+ template<int> const int c = 0;
+ extern template const int c<0>; // ok, has external linkage despite 'const'
+
+ template<typename T> T d = 0;
+ extern template int d<int>;
+ extern template const int d<const int>;
+#endif
+}
diff --git a/test/CXX/drs/dr7xx.cpp b/test/CXX/drs/dr7xx.cpp
index d02582b5b4..2d9d396018 100644
--- a/test/CXX/drs/dr7xx.cpp
+++ b/test/CXX/drs/dr7xx.cpp
@@ -1,7 +1,21 @@
// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+namespace dr705 { // dr705: yes
+ namespace N {
+ struct S {};
+ void f(S); // expected-note {{declared here}}
+ }
+
+ void g() {
+ N::S s;
+ f(s); // ok
+ (f)(s); // expected-error {{use of undeclared}}
+ }
+}
namespace dr727 { // dr727: partial
struct A {
@@ -53,7 +67,7 @@ namespace dr727 { // dr727: partial
struct D {
template<typename T> struct C { typename T::error e; }; // expected-error {{no members}}
template<typename T> void f() { T::error; } // expected-error {{no members}}
- template<typename T> static const int N = T::error; // expected-error 2{{no members}} expected-error 0-1{{C++14}}
+ template<typename T> static const int N = T::error; // expected-error {{no members}} expected-error 0-1{{C++14}}
template<> struct C<int> {};
template<> void f<int>() {}
@@ -66,7 +80,7 @@ namespace dr727 { // dr727: partial
void d(D<int> di) {
D<int>::C<int>();
di.f<int>();
- int a = D<int>::N<int>; // FIXME: expected-note {{instantiation of}}
+ int a = D<int>::N<int>;
D<int>::C<int*>();
int b = D<int>::N<int*>;
@@ -75,6 +89,98 @@ namespace dr727 { // dr727: partial
di.f<float>(); // expected-note {{instantiation of}}
int c = D<int>::N<float>; // expected-note {{instantiation of}}
}
+
+ namespace mixed_inner_outer_specialization {
+#if __cplusplus >= 201103L
+ template<int> struct A {
+ template<int> constexpr int f() const { return 1; }
+ template<> constexpr int f<0>() const { return 2; }
+ };
+ template<> template<int> constexpr int A<0>::f() const { return 3; }
+ template<> template<> constexpr int A<0>::f<0>() const { return 4; }
+ static_assert(A<1>().f<1>() == 1, "");
+ static_assert(A<1>().f<0>() == 2, "");
+ static_assert(A<0>().f<1>() == 3, "");
+ static_assert(A<0>().f<0>() == 4, "");
+#endif
+
+#if __cplusplus >= 201402L
+ template<int> struct B {
+ template<int> static const int u = 1;
+ template<> static const int u<0> = 2; // expected-note {{here}}
+
+ // Note that in C++17 onwards, these are implicitly inline, and so the
+ // initializer of v<0> is not instantiated with the declaration. In
+ // C++14, v<0> is a non-defining declaration and its initializer is
+ // instantiated with the class.
+ template<int> static constexpr int v = 1;
+ template<> static constexpr int v<0> = 2; // #v0
+
+ template<int> static const inline int w = 1; // expected-error 0-1{{C++17 extension}}
+ template<> static const inline int w<0> = 2; // expected-error 0-1{{C++17 extension}}
+ };
+
+ template<> template<int> constexpr int B<0>::u = 3;
+ template<> template<> constexpr int B<0>::u<0> = 4; // expected-error {{already has an initializer}}
+
+ template<> template<int> constexpr int B<0>::v = 3;
+ template<> template<> constexpr int B<0>::v<0> = 4;
+#if __cplusplus < 201702L
+ // expected-error@-2 {{already has an initializer}}
+ // expected-note@#v0 {{here}}
+#endif
+
+ template<> template<int> constexpr int B<0>::w = 3;
+ template<> template<> constexpr int B<0>::w<0> = 4;
+
+ static_assert(B<1>().u<1> == 1, "");
+ static_assert(B<1>().u<0> == 2, "");
+ static_assert(B<0>().u<1> == 3, "");
+
+ static_assert(B<1>().v<1> == 1, "");
+ static_assert(B<1>().v<0> == 2, "");
+ static_assert(B<0>().v<1> == 3, "");
+ static_assert(B<0>().v<0> == 4, "");
+#if __cplusplus < 201702L
+ // expected-error@-2 {{failed}}
+#endif
+
+ static_assert(B<1>().w<1> == 1, "");
+ static_assert(B<1>().w<0> == 2, "");
+ static_assert(B<0>().w<1> == 3, "");
+ static_assert(B<0>().w<0> == 4, "");
+#endif
+ }
+
+ template<typename T, typename U> struct Collision {
+ // FIXME: Missing diagnostic for duplicate function explicit specialization declaration.
+ template<typename> int f1();
+ template<> int f1<T>();
+ template<> int f1<U>();
+
+ // FIXME: Missing diagnostic for fucntion redefinition!
+ template<typename> int f2();
+ template<> int f2<T>() {}
+ template<> int f2<U>() {}
+
+ template<typename> static int v1; // expected-error 0-1{{C++14 extension}}
+ template<> static int v1<T>; // expected-note {{previous}}
+ template<> static int v1<U>; // expected-error {{duplicate member}}
+
+ template<typename> static inline int v2; // expected-error 0-1{{C++17 extension}} expected-error 0-1{{C++14 extension}}
+ template<> static inline int v2<T>; // expected-error 0-1{{C++17 extension}} expected-note {{previous}}
+ template<> static inline int v2<U>; // expected-error 0-1{{C++17 extension}} expected-error {{duplicate member}}
+
+ // FIXME: Missing diagnostic for duplicate class explicit specialization.
+ template<typename> struct S1;
+ template<> struct S1<T>;
+ template<> struct S1<U>;
+
+ template<typename> struct S2;
+ template<> struct S2<T> {}; // expected-note {{previous}}
+ template<> struct S2<U> {}; // expected-error {{redefinition}}
+ };
+ Collision<int, int> c; // expected-note {{in instantiation of}}
}
namespace dr777 { // dr777: 3.7
diff --git a/test/CXX/except/except.spec/p14.cpp b/test/CXX/except/except.spec/p14.cpp
index c717d97797..b1c8b207b4 100644
--- a/test/CXX/except/except.spec/p14.cpp
+++ b/test/CXX/except/except.spec/p14.cpp
@@ -83,7 +83,12 @@ namespace PR14141 {
Derived &operator=(const Derived&) noexcept(false) = default;
Derived &operator=(Derived&&) noexcept(false) = default;
~Derived() noexcept(false) = default;
- };
+ } d1;
+ static_assert(!noexcept(Derived()), "");
+ static_assert(!noexcept(Derived(static_cast<Derived&&>(d1))), "");
+ static_assert(!noexcept(Derived(d1)), "");
+ static_assert(!noexcept(d1 = static_cast<Derived&&>(d1)), "");
+ static_assert(!noexcept(d1 = d1), "");
struct Derived2 : ThrowingBase {
Derived2() = default;
Derived2(const Derived2&) = default;
@@ -91,15 +96,21 @@ namespace PR14141 {
Derived2 &operator=(const Derived2&) = default;
Derived2 &operator=(Derived2&&) = default;
~Derived2() = default;
- };
+ } d2;
+ static_assert(!noexcept(Derived2()), "");
+ static_assert(!noexcept(Derived2(static_cast<Derived2&&>(d2))), "");
+ static_assert(!noexcept(Derived2(d2)), "");
+ static_assert(!noexcept(d2 = static_cast<Derived2&&>(d2)), "");
+ static_assert(!noexcept(d2 = d2), "");
struct Derived3 : ThrowingBase {
- Derived3() noexcept(true) = default; // expected-error {{does not match the calculated}}
- Derived3(const Derived3&) noexcept(true) = default; // expected-error {{does not match the calculated}}
- Derived3(Derived3&&) noexcept(true) = default; // expected-error {{does not match the calculated}}
- Derived3 &operator=(const Derived3&) noexcept(true) = default; // expected-error {{does not match the calculated}}
- Derived3 &operator=(Derived3&&) noexcept(true) = default; // expected-error {{does not match the calculated}}
- ~Derived3() noexcept(true) = default; // expected-error {{does not match the calculated}}
- };
+ Derived3() noexcept(true) = default;
+ Derived3(const Derived3&) noexcept(true) = default;
+ Derived3(Derived3&&) noexcept(true) = default;
+ Derived3 &operator=(const Derived3&) noexcept(true) = default;
+ Derived3 &operator=(Derived3&&) noexcept(true) = default;
+ ~Derived3() noexcept(true) = default;
+ } d3;
+ static_assert(noexcept(Derived3(), Derived3(Derived3()), Derived3(d3), d3 = Derived3(), d3 = d3), "");
}
namespace rdar13017229 {
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p9.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p9.cpp
new file mode 100644
index 0000000000..2d3c69fc38
--- /dev/null
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p9.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 %s -verify
+// expected-no-diagnostics
+
+void test_noexcept() {
+ const auto lambda = [](int x) { return x + 1; };
+ static_assert(noexcept((int (*)(int))(lambda)),
+ "Lambda-to-function-pointer conversion is expected to be noexcept");
+}
diff --git a/test/CXX/lex/lex.pptoken/Inputs/foo bar b/test/CXX/lex/lex.pptoken/Inputs/foo bar
new file mode 100644
index 0000000000..9fb8e2fb61
--- /dev/null
+++ b/test/CXX/lex/lex.pptoken/Inputs/foo bar
@@ -0,0 +1 @@
+#error ERROR: This file should never actually be included
diff --git a/test/CXX/lex/lex.pptoken/Inputs/foo bar b/test/CXX/lex/lex.pptoken/Inputs/foo bar
new file mode 100644
index 0000000000..9fb8e2fb61
--- /dev/null
+++ b/test/CXX/lex/lex.pptoken/Inputs/foo bar
@@ -0,0 +1 @@
+#error ERROR: This file should never actually be included
diff --git a/test/CXX/lex/lex.pptoken/p3-2a.cpp b/test/CXX/lex/lex.pptoken/p3-2a.cpp
new file mode 100644
index 0000000000..0e0e5fec6e
--- /dev/null
+++ b/test/CXX/lex/lex.pptoken/p3-2a.cpp
@@ -0,0 +1,81 @@
+// RUN: not %clang_cc1 -std=c++2a -E -I%S/Inputs %s -o - | FileCheck %s --strict-whitespace --implicit-check-not=ERROR
+
+// Check for context-sensitive header-name token formation.
+// CHECK: import <foo bar>;
+import <foo bar>;
+
+// Not at the top level: these are each 8 tokens rather than 5.
+// CHECK: { import <foo bar>; }
+{ import <foo bar>; }
+// CHECK: ( import <foo bar>; :>
+( import <foo bar>; :>
+// CHECK: [ import <foo bar>; %>
+[ import <foo bar>; %>
+
+// CHECK: import <foo bar>;
+import <foo bar>;
+
+// CHECK: foo; import <foo bar>;
+foo; import <foo bar>;
+
+// CHECK: foo import <foo bar>;
+foo import <foo bar>;
+
+// CHECK: import <foo bar> {{\[\[ ]]}};
+import <foo bar> [[ ]];
+
+// CHECK: import <foo bar> import <foo bar>;
+import <foo bar> import <foo bar>;
+
+// FIXME: We do not form header-name tokens in the pp-import-suffix of a
+// pp-import. Conforming programs can't tell the difference.
+// CHECK: import <foo bar> {} import <foo bar>;
+// FIXME: import <foo bar> {} import <foo bar>;
+import <foo bar> {} import <foo bar>;
+
+
+// CHECK: export import <foo bar>;
+export import <foo bar>;
+
+// CHECK: export export import <foo bar>;
+export export import <foo bar>;
+
+#define UNBALANCED_PAREN (
+// CHECK: import <foo bar>;
+import <foo bar>;
+
+UNBALANCED_PAREN
+// CHECK: import <foo bar>;
+import <foo bar>;
+)
+
+_Pragma("clang no_such_pragma (");
+// CHECK: import <foo bar>;
+import <foo bar>;
+
+#define HEADER <foo bar>
+// CHECK: import <foo bar>;
+import HEADER;
+
+// CHECK: import <foo bar>;
+import <
+foo
+ bar
+>;
+
+// CHECK: import{{$}}
+// CHECK: {{^}}<foo bar>;
+import
+<
+foo
+ bar
+>;
+
+// CHECK: import{{$}}
+// CHECK: {{^}}<foo bar>;
+import
+<foo bar>;
+
+#define IMPORT import <foo bar>
+// CHECK: import <foo bar>;
+IMPORT;
diff --git a/test/CXX/module/module.interface/Inputs/header.h b/test/CXX/module/module.interface/Inputs/header.h
new file mode 100644
index 0000000000..f2e2cbb53c
--- /dev/null
+++ b/test/CXX/module/module.interface/Inputs/header.h
@@ -0,0 +1,3 @@
+extern int foo;
+namespace bar { extern int baz(); }
+static int baz;
diff --git a/test/CXX/module/module.interface/p1.cpp b/test/CXX/module/module.interface/p1.cpp
new file mode 100644
index 0000000000..0947b81915
--- /dev/null
+++ b/test/CXX/module/module.interface/p1.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -std=c++2a %s -DERRORS -verify
+// RUN: %clang_cc1 -std=c++2a %s -emit-module-interface -o %t.pcm
+// RUN: %clang_cc1 -std=c++2a %s -fmodule-file=%t.pcm -DIMPLEMENTATION -verify -Db=b2 -Dc=c2
+
+module;
+
+#ifdef ERRORS
+export int a; // expected-error {{after the module declaration}}
+#endif
+
+#ifndef IMPLEMENTATION
+export
+#else
+// expected-error@#1 {{can only be used within a module interface unit}}
+// expected-error@#2 {{can only be used within a module interface unit}}
+// expected-note@+2 1+{{add 'export'}}
+#endif
+module M;
+
+export int b; // #1
+namespace N {
+ export int c; // #2
+}
+
+#ifdef ERRORS
+namespace { // expected-note 2{{anonymous namespace begins here}}
+ export int d1; // expected-error {{export declaration appears within anonymous namespace}}
+ namespace X {
+ export int d2; // expected-error {{export declaration appears within anonymous namespace}}
+ }
+}
+
+export export int e; // expected-error {{within another export declaration}}
+export { export int f; } // expected-error {{within another export declaration}} expected-note {{export block begins here}}
+
+module :private; // expected-note {{private module fragment begins here}}
+export int priv; // expected-error {{export declaration cannot be used in a private module fragment}}
+#endif
diff --git a/test/CXX/module/module.interface/p2.cpp b/test/CXX/module/module.interface/p2.cpp
new file mode 100644
index 0000000000..0a6f8c2aad
--- /dev/null
+++ b/test/CXX/module/module.interface/p2.cpp
@@ -0,0 +1,94 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: %clang_cc1 -std=c++2a -x c++-header %S/Inputs/header.h -emit-header-module -fmodule-name=FIXME -o %t/h.pcm
+// RUN: %clang_cc1 -std=c++2a %s -DX_INTERFACE -emit-module-interface -o %t/x.pcm
+// RUN: %clang_cc1 -std=c++2a %s -DY_INTERFACE -emit-module-interface -o %t/y.pcm
+// RUN: %clang_cc1 -std=c++2a %s -DINTERFACE -fmodule-file=%t/x.pcm -fmodule-file=%t/y.pcm -emit-module-interface -o %t/m.pcm
+// RUN: %clang_cc1 -std=c++2a %s -DIMPLEMENTATION -I%S/Inputs -fmodule-file=%t/h.pcm -fmodule-file=%t/m.pcm -verify
+// RUN: %clang_cc1 -std=c++2a %s -DUSER -I%S/Inputs -fmodule-file=%t/h.pcm -fmodule-file=%t/m.pcm -verify
+
+#if defined(X_INTERFACE)
+export module X;
+export int x;
+
+#elif defined(Y_INTERFACE)
+export module Y;
+export int y;
+
+#elif defined(INTERFACE)
+export module p2;
+export import X;
+import Y; // not exported
+
+namespace A {
+ int f();
+ export int g();
+ int h();
+ namespace inner {}
+}
+export namespace B {
+ namespace inner {}
+}
+namespace B {
+ int f();
+}
+namespace C {}
+namespace D { int f(); }
+export namespace D {}
+
+#elif defined(IMPLEMENTATION)
+module p2;
+import "header.h";
+
+// Per [basic.scope.namespace]/2.3, exportedness has no impact on visibility
+// within the same module.
+//
+// expected-no-diagnostics
+
+void use() {
+ A::f();
+ A::g();
+ A::h();
+ using namespace A::inner;
+
+ using namespace B;
+ using namespace B::inner;
+ B::f();
+ f();
+
+ using namespace C;
+
+ D::f();
+}
+
+int use_header() { return foo + bar::baz(); }
+
+#elif defined(USER)
+import p2;
+import "header.h";
+
+void use() {
+ // namespace A is implicitly exported by the export of A::g.
+ A::f(); // expected-error {{no member named 'f' in namespace 'A'}}
+ A::g();
+ A::h(); // expected-error {{no member named 'h' in namespace 'A'}}
+ using namespace A::inner; // expected-error {{expected namespace name}}
+
+ // namespace B and B::inner are explicitly exported
+ using namespace B;
+ using namespace B::inner;
+ B::f(); // expected-error {{no member named 'f' in namespace 'B'}}
+ f(); // expected-error {{undeclared identifier 'f'}}
+
+ // namespace C is not exported
+ using namespace C; // expected-error {{expected namespace name}}
+
+ // namespace D is exported, but D::f is not
+ D::f(); // expected-error {{no member named 'f' in namespace 'D'}}
+}
+
+int use_header() { return foo + bar::baz(); }
+
+#else
+#error unknown mode
+#endif
diff --git a/test/CXX/module/module.interface/p3.cpp b/test/CXX/module/module.interface/p3.cpp
new file mode 100644
index 0000000000..29d2cb43b4
--- /dev/null
+++ b/test/CXX/module/module.interface/p3.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -std=c++2a %s -verify -pedantic-errors
+
+export module p3;
+
+namespace A { int ns_mem; }
+
+// An exported declaration shall declare at least one name.
+export; // expected-error {{empty declaration cannot be exported}}
+export static_assert(true); // expected-error {{static_assert declaration cannot be exported}}
+export using namespace A; // expected-error {{ISO C++20 does not permit using directive to be exported}}
+
+export { // expected-note 3{{export block begins here}}
+ ; // expected-error {{ISO C++20 does not permit an empty declaration to appear in an export block}}
+ static_assert(true); // expected-error {{ISO C++20 does not permit a static_assert declaration to appear in an export block}}
+ using namespace A; // expected-error {{ISO C++20 does not permit using directive to be exported}}
+}
+
+export struct {}; // expected-error {{must be class member}} expected-error {{GNU extension}} expected-error {{does not declare anything}}
+export struct {} struct_;
+export union {}; // expected-error {{must be declared 'static'}} expected-error {{does not declare anything}}
+export union {} union_;
+export enum {}; // expected-error {{does not declare anything}}
+export enum {} enum_;
+export enum E : int;
+export typedef int; // expected-error {{typedef requires a name}}
+export static union {}; // expected-error {{does not declare anything}}
+export asm(""); // expected-error {{asm declaration cannot be exported}}
+export namespace B = A;
+export using A::ns_mem;
+namespace A {
+ export using A::ns_mem;
+}
+export using Int = int;
+export extern "C++" {} // expected-error {{ISO C++20 does not permit a declaration that does not introduce any names to be exported}}
+export extern "C++" { extern "C" {} } // expected-error {{ISO C++20 does not permit a declaration that does not introduce any names to be exported}}
+export extern "C++" { extern "C" int extern_c; }
+export { // expected-note {{export block}}
+ extern "C++" int extern_cxx;
+ extern "C++" {} // expected-error {{ISO C++20 does not permit a declaration that does not introduce any names to be exported}}
+}
+export [[]]; // FIXME (bad diagnostic text): expected-error {{empty declaration cannot be exported}}
+export [[example::attr]]; // FIXME: expected-error {{empty declaration cannot be exported}} expected-warning {{unknown attribute 'attr'}}
+
+// [...] shall not declare a name with internal linkage
+export static int a; // expected-error {{declaration of 'a' with internal linkage cannot be exported}}
+export static int b(); // expected-error {{declaration of 'b' with internal linkage cannot be exported}}
+export namespace { int c; } // expected-error {{declaration of 'c' with internal linkage cannot be exported}}
+namespace { // expected-note {{here}}
+ export int d; // expected-error {{export declaration appears within anonymous namespace}}
+}
+export template<typename> static int e; // expected-error {{declaration of 'e' with internal linkage cannot be exported}}
+export template<typename> static int f(); // expected-error {{declaration of 'f' with internal linkage cannot be exported}}
+export const int k = 5;
+export static union { int n; }; // expected-error {{declaration of 'n' with internal linkage cannot be exported}}
diff --git a/test/CXX/module/module.interface/p5.cpp b/test/CXX/module/module.interface/p5.cpp
new file mode 100644
index 0000000000..17c4105baa
--- /dev/null
+++ b/test/CXX/module/module.interface/p5.cpp
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -std=c++2a %s -verify -pedantic-errors
+
+export module p5;
+
+int a;
+static int sa; // expected-note {{target}}
+void b();
+static void sb(); // expected-note {{target}}
+struct c {};
+enum d {};
+using e = int;
+using f = c;
+static union { int sg1, sg2; }; // expected-note {{target}}
+namespace NS {}
+
+template<typename> int ta;
+template<typename> static int sta; // expected-note {{target}}
+template<typename> void tb();
+template<typename> static void stb(); // expected-note {{target}}
+template<typename> struct tc {};
+template<typename> using te = int;
+template<typename> using tf = c;
+
+namespace UnnamedNS {
+ namespace {
+ int a; // expected-note {{target}}
+ static int sa; // expected-note {{target}}
+ void b(); // expected-note {{target}}
+ static void sb(); // expected-note {{target}}
+ struct c {}; // expected-note {{target}}
+ enum d {}; // expected-note {{target}}
+ using e = int;
+ using f = c;
+ static union { int sg1, sg2; }; // expected-note {{target}}
+ namespace NS {}
+
+ template<typename> int ta; // expected-note {{target}}
+ template<typename> static int sta; // expected-note {{target}}
+ template<typename> void tb(); // expected-note {{target}}
+ template<typename> static void stb(); // expected-note {{target}}
+ template<typename> struct tc {}; // expected-note {{target}}
+ template<typename> using te = int; // expected-note {{target}}
+ template<typename> using tf = c; // expected-note {{target}}
+ }
+}
+
+export { // expected-note 19{{here}}
+ using ::a;
+ using ::sa; // expected-error {{using declaration referring to 'sa' with internal linkage}}
+ using ::b;
+ using ::sb; // expected-error {{using declaration referring to 'sb' with internal linkage}}
+ using ::c;
+ using ::d;
+ using ::e;
+ using ::f;
+ using ::sg1; // expected-error {{using declaration referring to 'sg1' with internal linkage}}
+
+ using ::ta;
+ using ::sta; // expected-error {{using declaration referring to 'sta' with internal linkage}}
+ using ::tb;
+ using ::stb; // expected-error {{using declaration referring to 'stb' with internal linkage}}
+ using ::tc;
+ using ::te;
+ using ::tf;
+ namespace NS2 = ::NS;
+
+ namespace UnnamedNS {
+ using UnnamedNS::a; // expected-error {{internal linkage}}
+ using UnnamedNS::sa; // expected-error {{internal linkage}}
+ using UnnamedNS::b; // expected-error {{internal linkage}}
+ using UnnamedNS::sb; // expected-error {{internal linkage}}
+ using UnnamedNS::c; // expected-error {{internal linkage}}
+ using UnnamedNS::d; // expected-error {{internal linkage}}
+ using UnnamedNS::e; // ok
+ using UnnamedNS::f; // ok? using-declaration refers to alias-declaration,
+ // which does not have linkage (even though that then
+ // refers to a type that has internal linkage)
+ using UnnamedNS::sg1; // expected-error {{internal linkage}}
+
+ using UnnamedNS::ta; // expected-error {{internal linkage}}
+ using UnnamedNS::sta; // expected-error {{internal linkage}}
+ using UnnamedNS::tb; // expected-error {{internal linkage}}
+ using UnnamedNS::stb; // expected-error {{internal linkage}}
+ using UnnamedNS::tc; // expected-error {{internal linkage}}
+ using UnnamedNS::te; // expected-error {{internal linkage}}
+ using UnnamedNS::tf; // expected-error {{internal linkage}}
+ namespace NS2 = UnnamedNS::NS; // ok (wording bug?)
+ }
+}
diff --git a/test/CXX/module/module.unit/p3.cpp b/test/CXX/module/module.unit/p3.cpp
new file mode 100644
index 0000000000..2e08f4a9a8
--- /dev/null
+++ b/test/CXX/module/module.unit/p3.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+
+export module foo:bar; // expected-error {{sorry, module partitions are not yet supported}}
+import :baz; // expected-error {{sorry, module partitions are not yet supported}}
diff --git a/test/CXX/module/module.unit/p8.cpp b/test/CXX/module/module.unit/p8.cpp
new file mode 100644
index 0000000000..aad65272f0
--- /dev/null
+++ b/test/CXX/module/module.unit/p8.cpp
@@ -0,0 +1,40 @@
+// RUN: echo 'export module foo; export int n;' > %t.cppm
+// RUN: %clang_cc1 -std=c++2a %t.cppm -emit-module-interface -o %t.pcm
+// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=0 %s
+// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=1 %s
+// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=2 %s
+// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=3 %s
+// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=4 %s
+// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=5 %s
+
+#if MODE == 0
+// no module declaration
+
+#elif MODE == 1
+// expected-no-diagnostics
+module foo;
+#define IMPORTED
+
+#elif MODE == 2
+export module foo; // expected-error {{redefinition of module 'foo'}}
+// expected-note-re@* {{module loaded from '{{.*}}.pcm'}}
+#define IMPORTED
+
+#elif MODE == 3
+export module bar;
+
+#elif MODE == 4
+module foo:bar; // expected-error {{not yet supported}}
+#define IMPORTED // FIXME
+
+#elif MODE == 5
+export module foo:bar; // expected-error {{not yet supported}} expected-error {{redefinition}} expected-note@* {{loaded from}}
+#define IMPORTED // FIXME
+
+#endif
+
+int k = n;
+#ifndef IMPORTED
+// expected-error@-2 {{declaration of 'n' must be imported from module 'foo' before it is required}}
+// expected-note@* {{previous}}
+#endif
diff --git a/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp b/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp
index ad03191363..6eb5639d30 100644
--- a/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp
+++ b/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp
@@ -3,7 +3,6 @@
// CHECK-DAG: @extern_var_exported = external {{(dso_local )?}}global
// CHECK-DAG: @inline_var_exported = linkonce_odr {{(dso_local )?}}global
-// CHECK-DAG: @_ZW6ModuleE19static_var_exported = available_externally {{(dso_local )?}}global i32 0,
// CHECK-DAG: @const_var_exported = available_externally {{(dso_local )?}}constant i32 3,
//
// CHECK-DAG: @_ZW6ModuleE25extern_var_module_linkage = external {{(dso_local )?}}global
@@ -21,7 +20,6 @@ void use() {
(void)&extern_var_exported;
(void)&inline_var_exported;
- (void)&static_var_exported; // FIXME: Should not be exported.
(void)&const_var_exported;
// FIXME: This symbol should not be visible here.
diff --git a/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm b/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm
index 0f2c0db66e..65861f84ba 100644
--- a/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm
+++ b/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm
@@ -11,7 +11,6 @@
// can discard this global and its initializer (if any), and other TUs are not
// permitted to run the initializer for this variable.
// CHECK-DAG: @inline_var_exported = linkonce_odr {{(dso_local )?}}global
-// CHECK-DAG: @_ZW6ModuleE19static_var_exported = {{(dso_local )?}}global
// CHECK-DAG: @const_var_exported = {{(dso_local )?}}constant
//
// CHECK-DAG: @_ZW6ModuleE25extern_var_module_linkage = external {{(dso_local )?}}global
@@ -58,32 +57,17 @@ void noninline_global_module() {
export module Module;
export {
- // FIXME: These should be ill-formed: you can't export an internal linkage
- // symbol, per [dcl.module.interface]p2.
- // CHECK: define {{(dso_local )?}}void {{.*}}@_ZW6ModuleE22unused_static_exportedv
- static void unused_static_exported() {}
- // CHECK: define {{(dso_local )?}}void {{.*}}@_ZW6ModuleE20used_static_exportedv
- static void used_static_exported() {}
-
inline void unused_inline_exported() {}
inline void used_inline_exported() {}
extern int extern_var_exported;
inline int inline_var_exported;
- // FIXME: This should be ill-formed: you can't export an internal linkage
- // symbol.
- static int static_var_exported;
const int const_var_exported = 3;
// CHECK: define {{(dso_local )?}}void {{.*}}@_Z18noninline_exportedv
void noninline_exported() {
- used_static_exported();
- // CHECK: define linkonce_odr {{.*}}@_Z20used_inline_exportedv
- used_inline_exported();
-
(void)&extern_var_exported;
(void)&inline_var_exported;
- (void)&static_var_exported;
(void)&const_var_exported;
}
}
diff --git a/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp b/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
index 97c69fa0bb..d55e063797 100644
--- a/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
+++ b/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
@@ -3,7 +3,6 @@
// CHECK-DAG: @extern_var_exported = external {{(dso_local )?}}global
// CHECK-DAG: @inline_var_exported = linkonce_odr {{(dso_local )?}}global
-// CHECK-DAG: @_ZW6ModuleE19static_var_exported = available_externally {{(dso_local )?}}global i32 0
// CHECK-DAG: @const_var_exported = available_externally {{(dso_local )?}}constant i32 3
import Module;
@@ -16,7 +15,6 @@ void use() {
(void)&extern_var_exported;
(void)&inline_var_exported;
- (void)&static_var_exported;
(void)&const_var_exported;
// Module-linkage declarations are not visible here.
diff --git a/test/CXX/modules-ts/basic/basic.link/module-declaration.cpp b/test/CXX/modules-ts/basic/basic.link/module-declaration.cpp
index feb0afdda0..7615536b81 100644
--- a/test/CXX/modules-ts/basic/basic.link/module-declaration.cpp
+++ b/test/CXX/modules-ts/basic/basic.link/module-declaration.cpp
@@ -10,47 +10,39 @@
//
// Module implementation for unknown and known module. (The former is ill-formed.)
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=1 -DEXPORT= -DPARTITION= -DMODULE_NAME=z
+// RUN: -DTEST=1 -DEXPORT= -DMODULE_NAME=z
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=2 -DEXPORT= -DPARTITION= -DMODULE_NAME=x
+// RUN: -DTEST=2 -DEXPORT= -DMODULE_NAME=x
//
// Module interface for unknown and known module. (The latter is ill-formed due to
// redefinition.)
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=3 -DEXPORT=export -DPARTITION= -DMODULE_NAME=z
+// RUN: -DTEST=3 -DEXPORT=export -DMODULE_NAME=z
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=4 -DEXPORT=export -DPARTITION= -DMODULE_NAME=x
-//
-// Defining a module partition.
-// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=5 -DEXPORT=export -DPARTITION=partition -DMODULE_NAME=z
-// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=6 -DEXPORT= -DPARTITION=partition -DMODULE_NAME=z
+// RUN: -DTEST=4 -DEXPORT=export -DMODULE_NAME=x
//
// Miscellaneous syntax.
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=7 -DEXPORT= -DPARTITION=elderberry -DMODULE_NAME=z
+// RUN: -DTEST=7 -DEXPORT=export -DMODULE_NAME='z elderberry'
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=8 -DEXPORT=export -DPARTITION= -DMODULE_NAME='z [[]]'
+// RUN: -DTEST=8 -DEXPORT=export -DMODULE_NAME='z [[]]'
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=9 -DEXPORT=export -DPARTITION= -DMODULE_NAME='z [[fancy]]'
+// RUN: -DTEST=9 -DEXPORT=export -DMODULE_NAME='z [[fancy]]'
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=10 -DEXPORT=export -DPARTITION= -DMODULE_NAME='z [[maybe_unused]]'
+// RUN: -DTEST=10 -DEXPORT=export -DMODULE_NAME='z [[maybe_unused]]'
-EXPORT module PARTITION MODULE_NAME;
+EXPORT module MODULE_NAME;
#if TEST == 4
// expected-error@-2 {{redefinition of module 'x'}}
// expected-note-re@module-declaration.cpp:* {{loaded from '{{.*[/\\]}}x.pcm'}}
-#elif TEST == 6
-// expected-error@-5 {{module partition must be declared 'export'}}
#elif TEST == 7
-// expected-error@-7 {{expected ';'}} expected-error@-7 {{requires a type specifier}} expected-error@-7 {{definition of module 'elderberry' is not available}}
+// expected-error@-5 {{expected ';'}} expected-error@-5 {{requires a type specifier}}
#elif TEST == 9
-// expected-warning@-9 {{unknown attribute 'fancy' ignored}}
+// expected-warning@-7 {{unknown attribute 'fancy' ignored}}
#elif TEST == 10
-// expected-error-re@-11 {{'maybe_unused' attribute cannot be applied to a module{{$}}}}
+// expected-error-re@-9 {{'maybe_unused' attribute cannot be applied to a module{{$}}}}
#elif TEST == 1
-// expected-error@-13 {{definition of module 'z' is not available}}
+// expected-error@-11 {{definition of module 'z' is not available}}
#else
// expected-no-diagnostics
#endif
diff --git a/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp b/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp
index 68f2570dd3..52f45f578d 100644
--- a/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp
+++ b/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp
@@ -10,7 +10,7 @@
// expected-no-diagnostics
export module A;
#elif IMPLEMENTATION
-module A;
+module A; // #module-decl
#ifdef BUILT_AS_INTERFACE
// expected-error@-2 {{missing 'export' specifier in module declaration while building module interface}}
#define INTERFACE
@@ -23,6 +23,9 @@ module A;
#ifndef INTERFACE
export int b; // expected-error {{export declaration can only be used within a module interface unit}}
+#ifdef IMPLEMENTATION
+// expected-note@#module-decl {{add 'export' here}}
+#endif
#else
export int a;
#endif
diff --git a/test/CXX/temp/temp.decls/temp.friend/p1.cpp b/test/CXX/temp/temp.decls/temp.friend/p1.cpp
index 849728a448..ab1b9f7a73 100644
--- a/test/CXX/temp/temp.decls/temp.friend/p1.cpp
+++ b/test/CXX/temp/temp.decls/temp.friend/p1.cpp
@@ -380,10 +380,10 @@ template <class T> struct A {
namespace test18 {
namespace ns1 { template <class T> struct foo {}; } // expected-note{{candidate ignored: not a function template}}
namespace ns2 { void foo() {} } // expected-note{{candidate ignored: not a function template}}
-using ns1::foo;
-using ns2::foo;
+using ns1::foo; // expected-note {{found by name lookup}}
+using ns2::foo; // expected-note {{found by name lookup}}
template <class T> class A {
- friend void foo<T>() {} // expected-error{{no candidate function template was found for dependent friend function template specialization}}
+ friend void foo<T>() {} // expected-error {{ambiguous}} expected-error{{no candidate function template was found for dependent friend function template specialization}}
};
}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/p4.cpp b/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
index 1681325f2e..da9895ca6d 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
@@ -213,8 +213,10 @@ namespace PackExpansionWithinLambda {
};
#endif
+#if __cplusplus > 201703L
// - in a template parameter pack that is a pack expansion
- // FIXME: We do not support any way to reach this case yet.
+ swallow([]<T *...v, template<T *> typename ...W>(W<v> ...wv) { });
+#endif
// - in an initializer-list
int arr[] = {T().x...};
@@ -279,11 +281,6 @@ namespace PackExpansionWithinLambda {
struct T { int x; using U = int; };
void g() { f<T>(1, 2, 3); }
- template<typename ...T, typename ...U> void pack_in_lambda(U ...u) { // expected-note {{here}}
- // FIXME: Move this test into 'f' above once we support this syntax.
- []<T *...v, template<T *> typename ...U>(U<v> ...uv) {}; // expected-error {{expected body of lambda}} expected-error {{does not refer to a value}}
- }
-
template<typename ...T> void pack_expand_attr() {
// FIXME: Move this test into 'f' above once we support this.
[[gnu::aligned(alignof(T))...]] int x; // expected-error {{cannot be used as an attribute pack}} expected-error {{unexpanded}}