aboutsummaryrefslogtreecommitdiff
path: root/test/SemaCXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaCXX')
-rw-r--r--test/SemaCXX/MicrosoftCompatibility.cpp27
-rw-r--r--test/SemaCXX/MicrosoftExtensions.cpp19
-rw-r--r--test/SemaCXX/PR25848.cpp16
-rw-r--r--test/SemaCXX/PR29152.cpp15
-rw-r--r--test/SemaCXX/PR8755.cpp2
-rw-r--r--test/SemaCXX/address-packed-member-memops.cpp28
-rw-r--r--test/SemaCXX/address-packed.cpp114
-rw-r--r--test/SemaCXX/aggregate-init-cxx98.cpp7
-rw-r--r--test/SemaCXX/aggregate-initialization.cpp14
-rw-r--r--test/SemaCXX/ambig-user-defined-conversions.cpp5
-rw-r--r--test/SemaCXX/attr-gnu.cpp16
-rw-r--r--test/SemaCXX/attr-no-sanitize-address.cpp3
-rw-r--r--test/SemaCXX/attr-no-sanitize.cpp2
-rw-r--r--test/SemaCXX/attr-noreturn.cpp2
-rw-r--r--test/SemaCXX/attr-require-constant-initialization.cpp282
-rw-r--r--test/SemaCXX/attr-swiftcall.cpp4
-rw-r--r--test/SemaCXX/builtin-exception-spec.cpp1
-rw-r--r--test/SemaCXX/builtins.cpp11
-rw-r--r--test/SemaCXX/compare.cpp3
-rw-r--r--test/SemaCXX/composite-pointer-type.cpp4
-rw-r--r--test/SemaCXX/compound-literal.cpp10
-rw-r--r--test/SemaCXX/conditional-expr.cpp2
-rw-r--r--test/SemaCXX/constant-expression-cxx11.cpp108
-rw-r--r--test/SemaCXX/constant-expression-cxx1y.cpp20
-rw-r--r--test/SemaCXX/constant-expression-cxx1z.cpp21
-rw-r--r--test/SemaCXX/constexpr-string.cpp201
-rw-r--r--test/SemaCXX/constexpr-strlen.cpp15
-rw-r--r--test/SemaCXX/constexpr-value-init.cpp11
-rw-r--r--test/SemaCXX/conversion-function.cpp6
-rw-r--r--test/SemaCXX/conversion.cpp2
-rw-r--r--test/SemaCXX/copy-assignment.cpp15
-rw-r--r--test/SemaCXX/copy-initialization.cpp11
-rw-r--r--test/SemaCXX/coreturn.cpp73
-rw-r--r--test/SemaCXX/coroutines.cpp155
-rw-r--r--test/SemaCXX/cxx0x-defaulted-functions.cpp53
-rw-r--r--test/SemaCXX/cxx0x-initializer-constructor.cpp5
-rw-r--r--test/SemaCXX/cxx0x-initializer-references.cpp5
-rw-r--r--test/SemaCXX/cxx0x-initializer-scalars.cpp21
-rw-r--r--test/SemaCXX/cxx11-ast-print.cpp8
-rw-r--r--test/SemaCXX/cxx11-inheriting-ctors.cpp32
-rw-r--r--test/SemaCXX/cxx1y-initializer-aggregates.cpp16
-rw-r--r--test/SemaCXX/cxx1y-variable-templates_in_class.cpp8
-rw-r--r--test/SemaCXX/cxx1y-variable-templates_top_level.cpp6
-rw-r--r--test/SemaCXX/cxx1z-constexpr-lambdas.cpp62
-rw-r--r--test/SemaCXX/cxx1z-copy-omission.cpp134
-rw-r--r--test/SemaCXX/cxx1z-decomposition.cpp68
-rw-r--r--test/SemaCXX/cxx1z-noexcept-function-type.cpp167
-rw-r--r--test/SemaCXX/cxx1z-user-defined-literals.cpp21
-rw-r--r--test/SemaCXX/cxx98-compat-flags.cpp2
-rw-r--r--test/SemaCXX/cxx98-compat-pedantic.cpp6
-rw-r--r--test/SemaCXX/cxx98-compat.cpp4
-rw-r--r--test/SemaCXX/default-arg-closures.cpp45
-rw-r--r--test/SemaCXX/deprecated.cpp16
-rw-r--r--test/SemaCXX/derived-to-base-ambig.cpp4
-rw-r--r--test/SemaCXX/designated-initializers.cpp31
-rw-r--r--test/SemaCXX/elaborated-type-specifier.cpp9
-rw-r--r--test/SemaCXX/enable_if.cpp24
-rw-r--r--test/SemaCXX/expression-traits.cpp2
-rw-r--r--test/SemaCXX/friend.cpp9
-rw-r--r--test/SemaCXX/friend2.cpp172
-rw-r--r--test/SemaCXX/function-redecl-2.cpp19
-rw-r--r--test/SemaCXX/implicit-exception-spec.cpp18
-rw-r--r--test/SemaCXX/instantiate-template-fatal-error.cpp22
-rw-r--r--test/SemaCXX/lambda-expressions.cpp48
-rw-r--r--test/SemaCXX/libstdcxx_libcxx_less_hack.cpp67
-rw-r--r--test/SemaCXX/libstdcxx_pair_swap_hack.cpp24
-rw-r--r--test/SemaCXX/member-init.cpp24
-rw-r--r--test/SemaCXX/member-pointer-ms.cpp8
-rw-r--r--test/SemaCXX/microsoft-new-delete.cpp2
-rw-r--r--test/SemaCXX/modules-ts.cppm83
-rw-r--r--test/SemaCXX/ms-uuid.cpp95
-rw-r--r--test/SemaCXX/new-delete-cxx0x.cpp48
-rw-r--r--test/SemaCXX/null_in_arithmetic_ops.cpp4
-rw-r--r--test/SemaCXX/nullability.cpp33
-rw-r--r--test/SemaCXX/nullptr.cpp46
-rw-r--r--test/SemaCXX/nullptr_in_arithmetic_ops.cpp8
-rw-r--r--test/SemaCXX/overload-call.cpp11
-rw-r--r--test/SemaCXX/pr28050.cpp11
-rw-r--r--test/SemaCXX/predefined-expr.cpp18
-rw-r--r--test/SemaCXX/reinterpret-cast.cpp2
-rw-r--r--test/SemaCXX/rval-references.cpp10
-rw-r--r--test/SemaCXX/switch.cpp30
-rw-r--r--test/SemaCXX/template-ambiguous-overload.cpp16
-rw-r--r--test/SemaCXX/type-definition-in-specifier.cpp21
-rw-r--r--test/SemaCXX/unknown-anytype.cpp12
-rw-r--r--test/SemaCXX/using-decl-templates.cpp11
-rw-r--r--test/SemaCXX/vartemplate-lambda.cpp20
-rw-r--r--test/SemaCXX/warn-c++1z-extensions.cpp8
-rw-r--r--test/SemaCXX/warn-everthing.cpp2
-rw-r--r--test/SemaCXX/warn-logical-not-compare.cpp41
-rw-r--r--test/SemaCXX/warn-max-unsigned-zero.cpp55
-rw-r--r--test/SemaCXX/warn-memset-bad-sizeof.cpp43
-rw-r--r--test/SemaCXX/warn-memsize-comparison.cpp8
-rw-r--r--test/SemaCXX/warn-missing-variable-declarations.cpp5
-rw-r--r--test/SemaCXX/warn-msvc-enum-bitfield.cpp40
-rw-r--r--test/SemaCXX/warn-range-loop-analysis.cpp2
-rw-r--r--test/SemaCXX/warn-shadow-in-lambdas.cpp139
-rw-r--r--test/SemaCXX/warn-unused-variables.cpp44
-rw-r--r--test/SemaCXX/warn-weak-vtables.cpp5
99 files changed, 3013 insertions, 245 deletions
diff --git a/test/SemaCXX/MicrosoftCompatibility.cpp b/test/SemaCXX/MicrosoftCompatibility.cpp
index fe8e8f77accb..26cd7825ee87 100644
--- a/test/SemaCXX/MicrosoftCompatibility.cpp
+++ b/test/SemaCXX/MicrosoftCompatibility.cpp
@@ -99,23 +99,39 @@ int jump_over_indirect_goto() {
namespace PR11826 {
struct pair {
pair(int v) { }
+#if _MSC_VER >= 1900
+ void operator=(pair&& rhs) { } // expected-note {{copy constructor is implicitly deleted because 'pair' has a user-declared move assignment operator}}
+#else
void operator=(pair&& rhs) { }
+#endif
};
void f() {
pair p0(3);
+#if _MSC_VER >= 1900
+ pair p = p0; // expected-error {{call to implicitly-deleted copy constructor of 'PR11826::pair'}}
+#else
pair p = p0;
+#endif
}
}
namespace PR11826_for_symmetry {
struct pair {
pair(int v) { }
+#if _MSC_VER >= 1900
+ pair(pair&& rhs) { } // expected-note {{copy assignment operator is implicitly deleted because 'pair' has a user-declared move constructor}}
+#else
pair(pair&& rhs) { }
+#endif
};
void f() {
pair p0(3);
pair p(4);
+#if _MSC_VER >= 1900
+ p = p0; // expected-error {{object of type 'PR11826_for_symmetry::pair' cannot be assigned because its copy assignment operator is implicitly deleted}}
+#else
p = p0;
+#endif
}
}
@@ -242,3 +258,14 @@ namespace IntToNullPtrConv {
template<int N> int *get_n() { return N; } // expected-warning {{expression which evaluates to zero treated as a null pointer constant}}
int *g_nullptr = get_n<0>(); // expected-note {{in instantiation of function template specialization}}
}
+
+namespace signed_hex_i64 {
+void f(long long);
+void f(int);
+void g() {
+ // This is an ambiguous call in standard C++.
+ // This calls f(long long) in Microsoft mode because LL is always signed.
+ f(0xffffffffffffffffLL);
+ f(0xffffffffffffffffi64);
+}
+}
diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp
index e10deadf7c7f..e12dea1fb620 100644
--- a/test/SemaCXX/MicrosoftExtensions.cpp
+++ b/test/SemaCXX/MicrosoftExtensions.cpp
@@ -158,19 +158,16 @@ void m1() {
}
-
-
-
-void f(long long);
-void f(int);
-
-int main()
-{
- // This is an ambiguous call in standard C++.
- // This calls f(long long) in Microsoft mode because LL is always signed.
- f(0xffffffffffffffffLL);
+namespace signed_hex_i64 {
+void f(long long); // expected-note {{candidate function}}
+void f(int); // expected-note {{candidate function}}
+void g() {
+ // This used to be controlled by -fms-extensions, but it is now under
+ // -fms-compatibility.
+ f(0xffffffffffffffffLL); // expected-error {{call to 'f' is ambiguous}}
f(0xffffffffffffffffi64);
}
+}
// Enumeration types with a fixed underlying type.
const int seventeen = 17;
diff --git a/test/SemaCXX/PR25848.cpp b/test/SemaCXX/PR25848.cpp
new file mode 100644
index 000000000000..a22ac6650a06
--- /dev/null
+++ b/test/SemaCXX/PR25848.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct A;
+
+inline int g(); // expected-warning{{inline function 'g' is not defined}}
+
+template<int M>
+struct R {
+ friend int g() {
+ return M;
+ }
+};
+
+void m() {
+ g(); // expected-note{{used here}}
+}
diff --git a/test/SemaCXX/PR29152.cpp b/test/SemaCXX/PR29152.cpp
new file mode 100644
index 000000000000..63c9c9bed545
--- /dev/null
+++ b/test/SemaCXX/PR29152.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunreachable-code -verify %s
+
+static const bool False = false;
+
+struct A {
+ ~A();
+ operator bool();
+};
+void Bar();
+
+void Foo() {
+ if (False && A()) {
+ Bar(); // expected-no-diagnostics
+ }
+}
diff --git a/test/SemaCXX/PR8755.cpp b/test/SemaCXX/PR8755.cpp
index 07778ddfc900..6818f3f0a822 100644
--- a/test/SemaCXX/PR8755.cpp
+++ b/test/SemaCXX/PR8755.cpp
@@ -7,7 +7,7 @@ struct A {
template <typename T>
void f() {
- class A <T> ::iterator foo; // expected-error{{elaborated type refers to a typedef}}
+ class A <T> ::iterator foo; // expected-error{{typedef 'iterator' cannot be referenced with a class specifier}}
}
void g() {
diff --git a/test/SemaCXX/address-packed-member-memops.cpp b/test/SemaCXX/address-packed-member-memops.cpp
new file mode 100644
index 000000000000..6614626ae65c
--- /dev/null
+++ b/test/SemaCXX/address-packed-member-memops.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+struct B {
+ int x, y, z, w;
+} b;
+
+struct __attribute__((packed)) A {
+ struct B b;
+} a;
+
+typedef __typeof__(sizeof(int)) size_t;
+
+extern "C" {
+void *memcpy(void *dest, const void *src, size_t n);
+int memcmp(const void *s1, const void *s2, size_t n);
+void *memmove(void *dest, const void *src, size_t n);
+void *memset(void *s, int c, size_t n);
+}
+
+int x;
+
+void foo() {
+ memcpy(&a.b, &b, sizeof(b));
+ memmove(&a.b, &b, sizeof(b));
+ memset(&a.b, 0, sizeof(b));
+ x = memcmp(&a.b, &b, sizeof(b));
+}
diff --git a/test/SemaCXX/address-packed.cpp b/test/SemaCXX/address-packed.cpp
new file mode 100644
index 000000000000..308c4858cd50
--- /dev/null
+++ b/test/SemaCXX/address-packed.cpp
@@ -0,0 +1,114 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+extern void f1(int *);
+extern void f2(char *);
+
+struct __attribute__((packed)) Arguable {
+ int x;
+ char c;
+ static void foo();
+};
+
+extern void f3(void());
+
+namespace Foo {
+struct __attribute__((packed)) Arguable {
+ char c;
+ int x;
+ static void foo();
+};
+}
+
+struct Arguable *get_arguable();
+
+void f4(int &);
+
+void to_void(void *);
+
+template <typename... T>
+void sink(T...);
+
+void g0() {
+ {
+ Foo::Arguable arguable;
+ f1(&arguable.x); // expected-warning {{packed member 'x' of class or structure 'Foo::Arguable'}}
+ f2(&arguable.c); // no-warning
+ f3(&arguable.foo); // no-warning
+
+ to_void(&arguable.x); // no-warning
+ void *p1 = &arguable.x; // no-warning
+ void *p2 = static_cast<void *>(&arguable.x); // no-warning
+ void *p3 = reinterpret_cast<void *>(&arguable.x); // no-warning
+ void *p4 = (void *)&arguable.x; // no-warning
+ sink(p1, p2, p3, p4);
+ }
+ {
+ Arguable arguable1;
+ Arguable &arguable(arguable1);
+ f1(&arguable.x); // expected-warning {{packed member 'x' of class or structure 'Arguable'}}
+ f2(&arguable.c); // no-warning
+ f3(&arguable.foo); // no-warning
+ }
+ {
+ Arguable *arguable1;
+ Arguable *&arguable(arguable1);
+ f1(&arguable->x); // expected-warning {{packed member 'x' of class or structure 'Arguable'}}
+ f2(&arguable->c); // no-warning
+ f3(&arguable->foo); // no-warning
+ }
+}
+
+struct __attribute__((packed)) A {
+ int x;
+ char c;
+
+ int *f0() {
+ return &this->x; // expected-warning {{packed member 'x' of class or structure 'A'}}
+ }
+
+ int *g0() {
+ return &x; // expected-warning {{packed member 'x' of class or structure 'A'}}
+ }
+
+ char *h0() {
+ return &c; // no-warning
+ }
+};
+
+struct B : A {
+ int *f1() {
+ return &this->x; // expected-warning {{packed member 'x' of class or structure 'A'}}
+ }
+
+ int *g1() {
+ return &x; // expected-warning {{packed member 'x' of class or structure 'A'}}
+ }
+
+ char *h1() {
+ return &c; // no-warning
+ }
+};
+
+template <typename Ty>
+class __attribute__((packed)) S {
+ Ty X;
+
+public:
+ const Ty *get() const {
+ return &X; // expected-warning {{packed member 'X' of class or structure 'S<int>'}}
+ // expected-warning@-1 {{packed member 'X' of class or structure 'S<float>'}}
+ }
+};
+
+template <typename Ty>
+void h(Ty *);
+
+void g1() {
+ S<int> s1;
+ s1.get(); // expected-note {{in instantiation of member function 'S<int>::get'}}
+
+ S<char> s2;
+ s2.get();
+
+ S<float> s3;
+ s3.get(); // expected-note {{in instantiation of member function 'S<float>::get'}}
+}
diff --git a/test/SemaCXX/aggregate-init-cxx98.cpp b/test/SemaCXX/aggregate-init-cxx98.cpp
new file mode 100644
index 000000000000..332801f0822c
--- /dev/null
+++ b/test/SemaCXX/aggregate-init-cxx98.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -std=c++98 -verify %s
+
+struct A {
+ A() = default; // expected-warning {{C++11}}
+ int n;
+};
+A a = {0};
diff --git a/test/SemaCXX/aggregate-initialization.cpp b/test/SemaCXX/aggregate-initialization.cpp
index ddaf33fc1bfa..7b6abd22acc7 100644
--- a/test/SemaCXX/aggregate-initialization.cpp
+++ b/test/SemaCXX/aggregate-initialization.cpp
@@ -4,8 +4,6 @@
// Verify that using an initializer list for a non-aggregate looks for
// constructors..
-// Note that due to a (likely) standard bug, this is technically an aggregate,
-// but we do not treat it as one.
struct NonAggr1 { // expected-note 2 {{candidate constructor}}
NonAggr1(int, int) { } // expected-note {{candidate constructor}}
@@ -57,7 +55,7 @@ struct A {
A(int);
~A();
- A(const A&) = delete; // expected-note 2 {{'A' has been explicitly marked deleted here}}
+ A(const A&) = delete; // expected-note 0-2{{'A' has been explicitly marked deleted here}}
};
struct B {
@@ -70,10 +68,16 @@ struct C {
void f() {
A as1[1] = { };
- A as2[1] = { 1 }; // expected-error {{copying array element of type 'A' invokes deleted constructor}}
+ A as2[1] = { 1 };
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{copying array element of type 'A' invokes deleted constructor}}
+#endif
B b1 = { };
- B b2 = { 1 }; // expected-error {{copying member subobject of type 'A' invokes deleted constructor}}
+ B b2 = { 1 };
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{copying member subobject of type 'A' invokes deleted constructor}}
+#endif
C c1 = { 1 };
}
diff --git a/test/SemaCXX/ambig-user-defined-conversions.cpp b/test/SemaCXX/ambig-user-defined-conversions.cpp
index 1a3c102f034c..276c1b07b5d9 100644
--- a/test/SemaCXX/ambig-user-defined-conversions.cpp
+++ b/test/SemaCXX/ambig-user-defined-conversions.cpp
@@ -65,3 +65,8 @@ namespace rdar8876150 {
bool f(D d) { return !d; } // expected-error{{ambiguous conversion from derived class 'rdar8876150::D' to base class 'rdar8876150::A':}}
}
+
+namespace assignment {
+ struct A { operator short(); operator bool(); }; // expected-note 2{{candidate}}
+ void f(int n, A a) { n = a; } // expected-error{{ambiguous}}
+}
diff --git a/test/SemaCXX/attr-gnu.cpp b/test/SemaCXX/attr-gnu.cpp
index b4e9f4609f67..a553f0d21000 100644
--- a/test/SemaCXX/attr-gnu.cpp
+++ b/test/SemaCXX/attr-gnu.cpp
@@ -27,3 +27,19 @@ public:
void test3() __attribute__((cf_unknown_transfer)) override {} // Ok, not known to GCC.
};
}
+
+template<typename T>
+union Tu { T b; } __attribute__((transparent_union)); // expected-warning {{'transparent_union' attribute ignored}}
+
+template<typename T>
+union Tu2 { int x; T b; } __attribute__((transparent_union)); // expected-warning {{'transparent_union' attribute ignored}}
+
+union Tu3 { int x; } __attribute((transparent_union)); // expected-warning {{'transparent_union' attribute ignored}}
+
+void tuTest1(Tu<int> u); // expected-note {{candidate function not viable: no known conversion from 'int' to 'Tu<int>' for 1st argument}}
+void tuTest2(Tu3 u); // expected-note {{candidate function not viable: no known conversion from 'int' to 'Tu3' for 1st argument}}
+void tu() {
+ int x = 2;
+ tuTest1(x); // expected-error {{no matching function for call to 'tuTest1'}}
+ tuTest2(x); // expected-error {{no matching function for call to 'tuTest2'}}
+}
diff --git a/test/SemaCXX/attr-no-sanitize-address.cpp b/test/SemaCXX/attr-no-sanitize-address.cpp
index 9499742ac570..127129c948a0 100644
--- a/test/SemaCXX/attr-no-sanitize-address.cpp
+++ b/test/SemaCXX/attr-no-sanitize-address.cpp
@@ -21,9 +21,6 @@ int noanal_testfn(int y) {
return x;
}
-int noanal_test_var NO_SANITIZE_ADDRESS; // \
- // expected-error {{'no_sanitize_address' attribute only applies to functions}}
-
class NoanalFoo {
private:
int test_field NO_SANITIZE_ADDRESS; // \
diff --git a/test/SemaCXX/attr-no-sanitize.cpp b/test/SemaCXX/attr-no-sanitize.cpp
index 741f76062821..965def6f0254 100644
--- a/test/SemaCXX/attr-no-sanitize.cpp
+++ b/test/SemaCXX/attr-no-sanitize.cpp
@@ -2,8 +2,6 @@
// RUN: not %clang_cc1 -std=c++11 -ast-dump %s | FileCheck --check-prefix=DUMP %s
// RUN: not %clang_cc1 -std=c++11 -ast-print %s | FileCheck --check-prefix=PRINT %s
-int v1 __attribute__((no_sanitize("address"))); // expected-error{{'no_sanitize' attribute only applies to functions and methods}}
-
int f1() __attribute__((no_sanitize)); // expected-error{{'no_sanitize' attribute takes at least 1 argument}}
int f2() __attribute__((no_sanitize(1))); // expected-error{{'no_sanitize' attribute requires a string}}
diff --git a/test/SemaCXX/attr-noreturn.cpp b/test/SemaCXX/attr-noreturn.cpp
index 6df008dffa81..a8e71db73702 100644
--- a/test/SemaCXX/attr-noreturn.cpp
+++ b/test/SemaCXX/attr-noreturn.cpp
@@ -167,7 +167,7 @@ namespace destructor_tests {
// PR5620
void f0() __attribute__((__noreturn__));
-void f1(void (*)());
+void f1(void (*)());
void f2() { f1(f0); }
// Taking the address of a noreturn function
diff --git a/test/SemaCXX/attr-require-constant-initialization.cpp b/test/SemaCXX/attr-require-constant-initialization.cpp
new file mode 100644
index 000000000000..73f81cb1fc1d
--- /dev/null
+++ b/test/SemaCXX/attr-require-constant-initialization.cpp
@@ -0,0 +1,282 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -DTEST_ONE -std=c++03 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DTEST_ONE -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DTEST_ONE -std=c++14 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DTEST_TWO \
+// RUN: -Wglobal-constructors -std=c++14 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DTEST_THREE -xc %s
+
+#define ATTR __attribute__((require_constant_initialization)) // expected-note 0+ {{expanded from macro}}
+
+int ReturnInt();
+
+struct PODType {
+ int value;
+ int value2;
+};
+
+#if defined(__cplusplus)
+
+#if __cplusplus >= 201103L
+struct LitType {
+ constexpr LitType() : value(0) {}
+ constexpr LitType(int x) : value(x) {}
+ LitType(void *) : value(-1) {}
+ int value;
+};
+#endif
+
+struct NonLit {
+#if __cplusplus >= 201402L
+ constexpr NonLit() : value(0) {}
+ constexpr NonLit(int x) : value(x) {}
+#else
+ NonLit() : value(0) {}
+ NonLit(int x) : value(x) {}
+#endif
+ NonLit(void *) : value(-1) {}
+ ~NonLit() {}
+ int value;
+};
+
+struct StoresNonLit {
+#if __cplusplus >= 201402L
+ constexpr StoresNonLit() : obj() {}
+ constexpr StoresNonLit(int x) : obj(x) {}
+#else
+ StoresNonLit() : obj() {}
+ StoresNonLit(int x) : obj(x) {}
+#endif
+ StoresNonLit(void *p) : obj(p) {}
+ NonLit obj;
+};
+
+#endif // __cplusplus
+
+
+#if defined(TEST_ONE) // Test semantics of attribute
+
+// Test diagnostics when attribute is applied to non-static declarations.
+void test_func_local(ATTR int param) { // expected-error {{only applies to variables with static or thread}}
+ ATTR int x = 42; // expected-error {{only applies to variables with static or thread}}
+ ATTR extern int y;
+}
+struct ATTR class_mem { // expected-error {{only applies to variables with static or thread}}
+ ATTR int x; // expected-error {{only applies to variables with static or thread}}
+};
+
+// [basic.start.static]p2.1
+// if each full-expression (including implicit conversions) that appears in
+// the initializer of a reference with static or thread storage duration is
+// a constant expression (5.20) and the reference is bound to a glvalue
+// designating an object with static storage duration, to a temporary object
+// (see 12.2) or subobject thereof, or to a function;
+
+// Test binding to a static glvalue
+const int glvalue_int = 42;
+const int glvalue_int2 = ReturnInt();
+ATTR const int &glvalue_ref ATTR = glvalue_int;
+ATTR const int &glvalue_ref2 ATTR = glvalue_int2;
+ATTR __thread const int &glvalue_ref_tl = glvalue_int;
+
+void test_basic_start_static_2_1() {
+ const int non_global = 42;
+ ATTR static const int &local_init = non_global; // expected-error {{variable does not have a constant initializer}}
+ // expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+ ATTR static const int &global_init = glvalue_int;
+ ATTR static const int &temp_init = 42;
+}
+
+ATTR const int &temp_ref = 42;
+ATTR const int &temp_ref2 = ReturnInt(); // expected-error {{variable does not have a constant initializer}}
+// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+ATTR const NonLit &nl_temp_ref = 42; // expected-error {{variable does not have a constant initializer}}
+// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+
+#if __cplusplus >= 201103L
+ATTR const LitType &lit_temp_ref = 42;
+ATTR const int &subobj_ref = LitType{}.value;
+#endif
+
+ATTR const int &nl_subobj_ref = NonLit().value; // expected-error {{variable does not have a constant initializer}}
+// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+
+struct TT1 {
+ ATTR static const int &no_init;
+ ATTR static const int &glvalue_init;
+ ATTR static const int &temp_init;
+ ATTR static const int &subobj_init;
+#if __cplusplus >= 201103L
+ ATTR static thread_local const int &tl_glvalue_init;
+ ATTR static thread_local const int &tl_temp_init; // expected-note {{required by 'require_constant_initializer' attribute here}}
+#endif
+};
+const int &TT1::glvalue_init = glvalue_int;
+const int &TT1::temp_init = 42;
+const int &TT1::subobj_init = PODType().value;
+#if __cplusplus >= 201103L
+thread_local const int &TT1::tl_glvalue_init = glvalue_int;
+thread_local const int &TT1::tl_temp_init = 42; // expected-error {{variable does not have a constant initializer}}
+#endif
+
+// [basic.start.static]p2.2
+// if an object with static or thread storage duration is initialized by a
+// constructor call, and if the initialization full-expression is a constant
+// initializer for the object;
+
+void test_basic_start_static_2_2() {
+#if __cplusplus < 201103L
+ ATTR static PODType pod;
+#else
+ ATTR static PODType pod; // expected-error {{variable does not have a constant initializer}}
+// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+#endif
+ ATTR static PODType pot2 = {ReturnInt()}; // expected-error {{variable does not have a constant initializer}}
+ // expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+
+#if __cplusplus >= 201103L
+ constexpr LitType l;
+ ATTR static LitType static_lit = l;
+ ATTR static LitType static_lit2 = (void *)0; // expected-error {{variable does not have a constant initializer}}
+ // expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+ ATTR static LitType static_lit3 = ReturnInt(); // expected-error {{variable does not have a constant initializer}}
+ // expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+ ATTR thread_local LitType tls = 42;
+#endif
+}
+
+struct TT2 {
+ ATTR static PODType pod_noinit;
+#if __cplusplus >= 201103L
+// expected-note@-2 {{required by 'require_constant_initializer' attribute here}}
+#endif
+ ATTR static PODType pod_copy_init; // expected-note {{required by 'require_constant_initializer' attribute here}}
+#if __cplusplus >= 201402L
+ ATTR static constexpr LitType lit = {};
+ ATTR static const NonLit non_lit;
+ ATTR static const NonLit non_lit_list_init;
+ ATTR static const NonLit non_lit_copy_init; // expected-note {{required by 'require_constant_initializer' attribute here}}
+#endif
+};
+PODType TT2::pod_noinit;
+#if __cplusplus >= 201103L
+// expected-error@-2 {{variable does not have a constant initializer}}
+#endif
+PODType TT2::pod_copy_init(TT2::pod_noinit); // expected-error {{variable does not have a constant initializer}}
+#if __cplusplus >= 201402L
+const NonLit TT2::non_lit(42);
+const NonLit TT2::non_lit_list_init = {42};
+const NonLit TT2::non_lit_copy_init = 42; // expected-error {{variable does not have a constant initializer}}
+#endif
+
+#if __cplusplus >= 201103L
+ATTR LitType lit_ctor;
+ATTR LitType lit_ctor2{};
+ATTR LitType lit_ctor3 = {};
+ATTR __thread LitType lit_ctor_tl = {};
+
+#if __cplusplus >= 201402L
+ATTR NonLit nl_ctor;
+ATTR NonLit nl_ctor2{};
+ATTR NonLit nl_ctor3 = {};
+ATTR thread_local NonLit nl_ctor_tl = {};
+ATTR StoresNonLit snl;
+#else
+ATTR NonLit nl_ctor; // expected-error {{variable does not have a constant initializer}}
+// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+ATTR NonLit nl_ctor2{}; // expected-error {{variable does not have a constant initializer}}
+// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+ATTR NonLit nl_ctor3 = {}; // expected-error {{variable does not have a constant initializer}}
+// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+ATTR thread_local NonLit nl_ctor_tl = {}; // expected-error {{variable does not have a constant initializer}}
+// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+ATTR StoresNonLit snl; // expected-error {{variable does not have a constant initializer}}
+// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+#endif
+
+// Non-literal types cannot appear in the initializer of a non-literal type.
+ATTR int nl_in_init = NonLit{42}.value; // expected-error {{variable does not have a constant initializer}}
+// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+ATTR int lit_in_init = LitType{42}.value;
+#endif
+
+// [basic.start.static]p2.3
+// if an object with static or thread storage duration is not initialized by a
+// constructor call and if either the object is value-initialized or every
+// full-expression that appears in its initializer is a constant expression.
+void test_basic_start_static_2_3() {
+ ATTR static int static_local = 42;
+ ATTR static int static_local2; // zero-initialization takes place
+#if __cplusplus >= 201103L
+ ATTR thread_local int tl_local = 42;
+#endif
+}
+
+ATTR int no_init; // zero initialization takes place
+ATTR int arg_init = 42;
+ATTR PODType pod_init = {};
+ATTR PODType pod_missing_init = {42 /* should have second arg */};
+ATTR PODType pod_full_init = {1, 2};
+ATTR PODType pod_non_constexpr_init = {1, ReturnInt()}; // expected-error {{variable does not have a constant initializer}}
+// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+
+#if __cplusplus >= 201103L
+ATTR int val_init{};
+ATTR int brace_init = {};
+#endif
+
+ATTR __thread int tl_init = 0;
+typedef const char *StrType;
+
+#if __cplusplus >= 201103L
+
+// Test that the validity of the selected constructor is checked, not just the
+// initializer
+struct NotC {
+ constexpr NotC(void *) {}
+ NotC(int) {}
+};
+template <class T>
+struct TestCtor {
+ constexpr TestCtor(int x) : value(x) {}
+ T value;
+};
+ATTR TestCtor<NotC> t(42); // expected-error {{variable does not have a constant initializer}}
+// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+#endif
+
+// Test various array types
+ATTR const char *foo[] = {"abc", "def"};
+ATTR PODType bar[] = {{}, {123, 456}};
+
+#elif defined(TEST_TWO) // Test for duplicate warnings
+struct NotC {
+ constexpr NotC(void *) {}
+ NotC(int) {} // expected-note 2 {{declared here}}
+};
+template <class T>
+struct TestCtor {
+ constexpr TestCtor(int x) : value(x) {} // expected-note 2 {{non-constexpr constructor}}
+ T value;
+};
+
+ATTR LitType non_const_lit(nullptr); // expected-error {{variable does not have a constant initializer}}
+// expected-note@-1 {{required by 'require_constant_initializer' attribute here}}
+ATTR NonLit non_const(nullptr); // expected-error {{variable does not have a constant initializer}}
+// expected-warning@-1 {{declaration requires a global destructor}}
+// expected-note@-2 {{required by 'require_constant_initializer' attribute here}}
+LitType const_init_lit(nullptr); // expected-warning {{declaration requires a global constructor}}
+NonLit const_init{42}; // expected-warning {{declaration requires a global destructor}}
+constexpr TestCtor<NotC> inval_constexpr(42); // expected-error {{must be initialized by a constant expression}}
+// expected-note@-1 {{in call to 'TestCtor(42)'}}
+ATTR constexpr TestCtor<NotC> inval_constexpr2(42); // expected-error {{must be initialized by a constant expression}}
+// expected-note@-1 {{in call to 'TestCtor(42)'}}
+
+#elif defined(TEST_THREE)
+#if defined(__cplusplus)
+#error This test requires C
+#endif
+// Test that using the attribute in C results in a diagnostic
+ATTR int x = 0; // expected-warning {{attribute ignored}}
+#else
+#error No test case specified
+#endif // defined(TEST_N)
diff --git a/test/SemaCXX/attr-swiftcall.cpp b/test/SemaCXX/attr-swiftcall.cpp
index fd17aae18523..eb9538e31044 100644
--- a/test/SemaCXX/attr-swiftcall.cpp
+++ b/test/SemaCXX/attr-swiftcall.cpp
@@ -17,16 +17,16 @@ void indirect_result_single(INDIRECT_RESULT void *out) SWIFTCALL;
void indirect_result_multiple(INDIRECT_RESULT void *out1, INDIRECT_RESULT void *out2) SWIFTCALL;
void error_result_nonswift(ERROR_RESULT void **error); // expected-error {{'swift_error_result' parameter can only be used with swiftcall calling convention}} expected-error{{'swift_error_result' parameter must follow 'swift_context' parameter}}
-void error_result_bad_position(ERROR_RESULT void **error, int last) SWIFTCALL; // expected-error {{'swift_error_result' parameter must be last parameter of function}}
void error_result_bad_position2(int first, ERROR_RESULT void **error) SWIFTCALL; // expected-error {{'swift_error_result' parameter must follow 'swift_context' parameter}}
void error_result_bad_type(CONTEXT void *context, ERROR_RESULT int error) SWIFTCALL; // expected-error {{'swift_error_result' parameter must have pointer to unqualified pointer type; type here is 'int'}}
void error_result_bad_type2(CONTEXT void *context, ERROR_RESULT int *error) SWIFTCALL; // expected-error {{'swift_error_result' parameter must have pointer to unqualified pointer type; type here is 'int *'}}
void error_result_okay(int a, int b, CONTEXT void *context, ERROR_RESULT void **error) SWIFTCALL;
+void error_result_okay(CONTEXT void *context, ERROR_RESULT void **error, void *selfType, char **selfWitnessTable) SWIFTCALL;
void context_nonswift(CONTEXT void *context); // expected-error {{'swift_context' parameter can only be used with swiftcall calling convention}}
-void context_bad_position(CONTEXT void *context, int x) SWIFTCALL; // expected-error {{'swift_context' parameter can only be followed by 'swift_error_result' parameter}}
void context_bad_type(CONTEXT int context) SWIFTCALL; // expected-error {{'swift_context' parameter must have pointer type; type here is 'int'}}
void context_okay(CONTEXT void *context) SWIFTCALL;
+void context_okay(CONTEXT void *context, void *selfType, char **selfWitnessTable) SWIFTCALL;
template <class T> void indirect_result_temp_okay1(INDIRECT_RESULT T *out) SWIFTCALL;
template <class T> void indirect_result_temp_okay2(INDIRECT_RESULT T out) SWIFTCALL; // expected-note {{candidate template ignored: substitution failure [with T = int]: 'swift_indirect_result' parameter must have pointer type; type here is 'int'}}
diff --git a/test/SemaCXX/builtin-exception-spec.cpp b/test/SemaCXX/builtin-exception-spec.cpp
index 590cd3c35d4e..9845172bcd72 100644
--- a/test/SemaCXX/builtin-exception-spec.cpp
+++ b/test/SemaCXX/builtin-exception-spec.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -isystem %S/Inputs -fsyntax-only -verify %s
+// RUN: %clang_cc1 -isystem %S/Inputs -fsyntax-only -verify -std=c++1z %s
// expected-no-diagnostics
#include <malloc.h>
diff --git a/test/SemaCXX/builtins.cpp b/test/SemaCXX/builtins.cpp
index 69bdfa614517..f26931b55bdb 100644
--- a/test/SemaCXX/builtins.cpp
+++ b/test/SemaCXX/builtins.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++11
+// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++11 -fcxx-exceptions
+// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++1z -fcxx-exceptions
typedef const struct __CFString * CFStringRef;
#define CFSTR __builtin___CFStringMakeConstantString
@@ -44,3 +45,11 @@ void no_ms_builtins() {
__noop(1); // expected-error {{use of undeclared}}
__debugbreak(); // expected-error {{use of undeclared}}
}
+
+struct FILE;
+extern "C" int vfprintf(FILE *__restrict, const char *__restrict,
+ __builtin_va_list va);
+
+void synchronize_args() {
+ __sync_synchronize(0); // expected-error {{too many arguments}}
+}
diff --git a/test/SemaCXX/compare.cpp b/test/SemaCXX/compare.cpp
index ef0a524f92f1..0528b044fb1f 100644
--- a/test/SemaCXX/compare.cpp
+++ b/test/SemaCXX/compare.cpp
@@ -201,9 +201,10 @@ int test1(int i) {
enum E { e };
void test2(int i, void *vp) {
+ if (&i == vp) { } // ok
if (test1 == vp) { } // expected-warning{{equality comparison between function pointer and void pointer}}
if (test1 == e) { } // expected-error{{comparison between pointer and integer}}
- if (vp < 0) { }
+ if (vp < 0) { } // expected-error {{comparison between pointer and zero}}
if (test1 < e) { } // expected-error{{comparison between pointer and integer}}
}
diff --git a/test/SemaCXX/composite-pointer-type.cpp b/test/SemaCXX/composite-pointer-type.cpp
index 06fc8f43855d..dddf424caa2e 100644
--- a/test/SemaCXX/composite-pointer-type.cpp
+++ b/test/SemaCXX/composite-pointer-type.cpp
@@ -53,8 +53,8 @@ bool f(Matrix4 m1, const Matrix4 m2) {
// PR6346
bool f1(bool b, void **p, const void **q) {
- if (p == q) // expected-warning{{comparison of distinct pointer types ('void **' and 'const void **') uses non-standard composite pointer type 'const void *const *'}}
+ if (p == q)
return false;
- return b? p : q; // expected-warning{{incompatible operand types ('void **' and 'const void **') use non-standard composite pointer type 'const void *const *'}}
+ return b? p : q;
}
diff --git a/test/SemaCXX/compound-literal.cpp b/test/SemaCXX/compound-literal.cpp
index 3fc61505dfee..5480b1fef44d 100644
--- a/test/SemaCXX/compound-literal.cpp
+++ b/test/SemaCXX/compound-literal.cpp
@@ -86,3 +86,13 @@ int PR17415 = (int){PR17415}; // expected-error {{initializer element is not a c
template<unsigned> struct Value { };
template<typename T>
int &check_narrowed(Value<sizeof((T){1.1})>);
+
+#if __cplusplus >= 201103L
+// Compound literals in global lambdas have automatic storage duration
+// and are not subject to the constant-initialization rules.
+int computed_with_lambda = [] {
+ int x = 5;
+ int result = ((int[]) { x, x + 2, x + 4, x + 6 })[0];
+ return result;
+}();
+#endif
diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp
index c12efc0be7ef..5025990cfd36 100644
--- a/test/SemaCXX/conditional-expr.cpp
+++ b/test/SemaCXX/conditional-expr.cpp
@@ -262,7 +262,7 @@ namespace PR6757 {
struct Foo2 { };
struct Foo3 {
- Foo3();
+ Foo3(); // expected-note{{requires 0 arguments}}
Foo3(Foo3&); // expected-note{{would lose const qualifier}}
};
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp
index e2b3f091f70f..581a524339e7 100644
--- a/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/test/SemaCXX/constant-expression-cxx11.cpp
@@ -279,17 +279,17 @@ static_assert(&s.x > &s.y, "false"); // expected-error {{false}}
static_assert(0 == &y, "false"); // expected-error {{false}}
static_assert(0 != &y, "");
-constexpr bool n3 = 0 <= &y; // expected-error {{must be initialized by a constant expression}}
-constexpr bool n4 = 0 >= &y; // expected-error {{must be initialized by a constant expression}}
-constexpr bool n5 = 0 < &y; // expected-error {{must be initialized by a constant expression}}
-constexpr bool n6 = 0 > &y; // expected-error {{must be initialized by a constant expression}}
+constexpr bool n3 = (int*)0 <= &y; // expected-error {{must be initialized by a constant expression}}
+constexpr bool n4 = (int*)0 >= &y; // expected-error {{must be initialized by a constant expression}}
+constexpr bool n5 = (int*)0 < &y; // expected-error {{must be initialized by a constant expression}}
+constexpr bool n6 = (int*)0 > &y; // expected-error {{must be initialized by a constant expression}}
static_assert(&x == 0, "false"); // expected-error {{false}}
static_assert(&x != 0, "");
-constexpr bool n9 = &x <= 0; // expected-error {{must be initialized by a constant expression}}
-constexpr bool n10 = &x >= 0; // expected-error {{must be initialized by a constant expression}}
-constexpr bool n11 = &x < 0; // expected-error {{must be initialized by a constant expression}}
-constexpr bool n12 = &x > 0; // expected-error {{must be initialized by a constant expression}}
+constexpr bool n9 = &x <= (int*)0; // expected-error {{must be initialized by a constant expression}}
+constexpr bool n10 = &x >= (int*)0; // expected-error {{must be initialized by a constant expression}}
+constexpr bool n11 = &x < (int*)0; // expected-error {{must be initialized by a constant expression}}
+constexpr bool n12 = &x > (int*)0; // expected-error {{must be initialized by a constant expression}}
static_assert(&x == &x, "");
static_assert(&x != &x, "false"); // expected-error {{false}}
@@ -386,6 +386,18 @@ namespace FakeInitList {
constexpr init_list_2_init_list_3_ints ils = { { { { 1, 2, 3 } }, { { 4, 5, 6 } } } };
}
+namespace ConstAddedByReference {
+ const int &r = (0);
+ constexpr int n = r;
+
+ struct A { constexpr operator int() const { return 0; }};
+ struct B { constexpr operator const int() const { return 0; }};
+ const int &ra = A();
+ const int &rb = B();
+ constexpr int na = ra;
+ constexpr int nb = rb;
+}
+
}
constexpr int strcmp_ce(const char *p, const char *q) {
@@ -554,6 +566,21 @@ struct ArrayRVal {
};
static_assert(ArrayRVal().elems[3].f() == 0, "");
+namespace CopyCtor {
+ struct A {
+ constexpr A() {}
+ constexpr A(const A &) {}
+ };
+ struct B {
+ A a;
+ int arr[10];
+ };
+ constexpr B b{{}, {1, 2, 3, 4, 5}};
+ constexpr B c = b;
+ static_assert(c.arr[2] == 3, "");
+ static_assert(c.arr[7] == 0, "");
+}
+
constexpr int selfref[2][2][2] = {
selfref[1][1][1] + 1, selfref[0][0][0] + 1,
selfref[1][0][1] + 1, selfref[0][1][0] + 1,
@@ -1156,7 +1183,7 @@ constexpr int m1b = const_cast<const int&>(n1); // expected-error {{constant exp
constexpr int m2b = const_cast<const int&>(n2); // expected-error {{constant expression}} expected-note {{read of volatile object 'n2'}}
struct T { int n; };
-const T t = { 42 }; // expected-note {{declared here}}
+const T t = { 42 };
constexpr int f(volatile int &&r) {
return r; // expected-note {{read of volatile-qualified type 'volatile int'}}
@@ -1168,7 +1195,7 @@ struct S {
int j : f(0); // expected-error {{constant expression}} expected-note {{in call to 'f(0)'}}
int k : g(0); // expected-error {{constant expression}} expected-note {{temporary created here}} expected-note {{in call to 'g(0)'}}
int l : n3; // expected-error {{constant expression}} expected-note {{read of non-const variable}}
- int m : t.n; // expected-error {{constant expression}} expected-note {{read of non-constexpr variable}}
+ int m : t.n; // expected-warning{{width of bit-field 'm' (42 bits)}} expected-warning{{expression is not an integral constant expression}} expected-note{{read of non-constexpr variable 't' is not allowed}}
};
}
@@ -1467,13 +1494,26 @@ namespace VLASizeof {
}
namespace CompoundLiteral {
- // FIXME:
- // We don't model the semantics of this correctly: the compound literal is
- // represented as a prvalue in the AST, but actually behaves like an lvalue.
- // We treat the compound literal as a temporary and refuse to produce a
- // pointer to it. This is OK: we're not required to treat this as a constant
- // in C++, and in C we model compound literals as lvalues.
- constexpr int *p = (int*)(int[1]){0}; // expected-warning {{C99}} expected-error {{constant expression}} expected-note 2{{temporary}}
+ // Matching GCC, file-scope array compound literals initialized by constants
+ // are lifetime-extended.
+ constexpr int *p = (int*)(int[1]){3}; // expected-warning {{C99}}
+ static_assert(*p == 3, "");
+ static_assert((int[2]){1, 2}[1] == 2, ""); // expected-warning {{C99}}
+
+ // Other kinds are not.
+ struct X { int a[2]; };
+ constexpr int *n = (X){1, 2}.a; // expected-warning {{C99}} expected-warning {{temporary array}}
+ // expected-error@-1 {{constant expression}}
+ // expected-note@-2 {{pointer to subobject of temporary}}
+ // expected-note@-3 {{temporary created here}}
+
+ void f() {
+ static constexpr int *p = (int*)(int[1]){3}; // expected-warning {{C99}}
+ // expected-error@-1 {{constant expression}}
+ // expected-note@-2 {{pointer to subobject of temporary}}
+ // expected-note@-3 {{temporary created here}}
+ static_assert((int[2]){1, 2}[1] == 2, ""); // expected-warning {{C99}}
+ }
}
namespace Vector {
@@ -1862,8 +1902,8 @@ namespace ZeroSizeTypes {
namespace BadDefaultInit {
template<int N> struct X { static const int n = N; };
- struct A {
- int k = // expected-error {{cannot use defaulted default constructor of 'A' within the class outside of member functions because 'k' has an initializer}}
+ struct A { // expected-error {{default member initializer for 'k' needed within definition of enclosing class}}
+ int k = // expected-note {{default member initializer declared here}}
X<A().k>::n; // expected-error {{not a constant expression}} expected-note {{implicit default constructor for 'BadDefaultInit::A' first required here}}
};
@@ -2066,3 +2106,33 @@ namespace InheritedCtor {
constexpr Z z(1);
static_assert(z.w == 1 && z.x == 2 && z.y == 3 && z.z == 4, "");
}
+
+
+namespace PR28366 {
+namespace ns1 {
+
+void f(char c) { //expected-note2{{declared here}}
+ struct X {
+ static constexpr char f() { //expected-error{{never produces a constant expression}}
+ return c; //expected-error{{reference to local}} expected-note{{non-const variable}}
+ }
+ };
+ int I = X::f();
+}
+
+void g() {
+ const int c = 'c';
+ static const int d = 'd';
+ struct X {
+ static constexpr int f() {
+ return c + d;
+ }
+ };
+ static_assert(X::f() == 'c' + 'd',"");
+}
+
+
+} // end ns1
+
+} //end ns PR28366
+
diff --git a/test/SemaCXX/constant-expression-cxx1y.cpp b/test/SemaCXX/constant-expression-cxx1y.cpp
index f8103224af89..dfdf50ad5484 100644
--- a/test/SemaCXX/constant-expression-cxx1y.cpp
+++ b/test/SemaCXX/constant-expression-cxx1y.cpp
@@ -957,3 +957,23 @@ namespace PR27989 {
}
static_assert(f(0) == 1, "");
}
+
+namespace const_char {
+template <int N>
+constexpr int sum(const char (&Arr)[N]) {
+ int S = 0;
+ for (unsigned I = 0; I != N; ++I)
+ S += Arr[I]; // expected-note 2{{read of non-constexpr variable 'Cs' is not allowed}}
+ return S;
+}
+
+// As an extension, we support evaluating some things that are `const` as though
+// they were `constexpr` when folding, but it should not be allowed in normal
+// constexpr evaluation.
+const char Cs[] = {'a', 'b'};
+void foo() __attribute__((enable_if(sum(Cs) == 'a' + 'b', "")));
+void run() { foo(); }
+
+static_assert(sum(Cs) == 'a' + 'b', ""); // expected-error{{not an integral constant expression}} expected-note{{in call to 'sum(Cs)'}}
+constexpr int S = sum(Cs); // expected-error{{must be initialized by a constant expression}} expected-note{{in call}}
+}
diff --git a/test/SemaCXX/constant-expression-cxx1z.cpp b/test/SemaCXX/constant-expression-cxx1z.cpp
index e84de44d374a..a48c9b11b886 100644
--- a/test/SemaCXX/constant-expression-cxx1z.cpp
+++ b/test/SemaCXX/constant-expression-cxx1z.cpp
@@ -25,3 +25,24 @@ namespace BaseClassAggregateInit {
constexpr D d5 = { __INT_MAX__ }; // expected-error {{must be initialized by a constant expression}}
// expected-note-re@-1 {{in call to 'A({{.*}})'}}
}
+
+namespace NoexceptFunctionTypes {
+ template<typename T> constexpr bool f() noexcept(true) { return true; }
+ constexpr bool (*fp)() = f<int>;
+ static_assert(f<int>());
+ static_assert(fp());
+
+ template<typename T> struct A {
+ constexpr bool f() noexcept(true) { return true; }
+ constexpr bool g() { return f(); }
+ constexpr bool operator()() const noexcept(true) { return true; }
+ };
+ static_assert(A<int>().f());
+ static_assert(A<int>().g());
+ static_assert(A<int>()());
+}
+
+namespace Cxx17CD_NB_GB19 {
+ const int &r = 0;
+ constexpr int n = r;
+}
diff --git a/test/SemaCXX/constexpr-string.cpp b/test/SemaCXX/constexpr-string.cpp
new file mode 100644
index 000000000000..944038bc163a
--- /dev/null
+++ b/test/SemaCXX/constexpr-string.cpp
@@ -0,0 +1,201 @@
+// RUN: %clang_cc1 %s -std=c++1z -fsyntax-only -verify -pedantic
+// RUN: %clang_cc1 %s -std=c++1z -fsyntax-only -verify -pedantic -fno-signed-char
+// RUN: %clang_cc1 %s -std=c++1z -fsyntax-only -verify -pedantic -fno-wchar -Dwchar_t=__WCHAR_TYPE__
+
+# 6 "/usr/include/string.h" 1 3 4
+extern "C" {
+ typedef decltype(sizeof(int)) size_t;
+
+ extern size_t strlen(const char *p);
+
+ extern int strcmp(const char *s1, const char *s2);
+ extern int strncmp(const char *s1, const char *s2, size_t n);
+ extern int memcmp(const void *s1, const void *s2, size_t n);
+
+ extern char *strchr(const char *s, int c);
+ extern void *memchr(const void *s, int c, size_t n);
+}
+# 19 "SemaCXX/constexpr-string.cpp" 2
+
+# 21 "/usr/include/wchar.h" 1 3 4
+extern "C" {
+ extern size_t wcslen(const wchar_t *p);
+
+ extern int wcscmp(const wchar_t *s1, const wchar_t *s2);
+ extern int wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t n);
+ extern int wmemcmp(const wchar_t *s1, const wchar_t *s2, size_t n);
+
+ extern wchar_t *wcschr(const wchar_t *s, wchar_t c);
+ extern wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n);
+}
+
+# 33 "SemaCXX/constexpr-string.cpp" 2
+namespace Strlen {
+ constexpr int n = __builtin_strlen("hello"); // ok
+ static_assert(n == 5);
+ constexpr int wn = __builtin_wcslen(L"hello"); // ok
+ static_assert(wn == 5);
+ constexpr int m = strlen("hello"); // expected-error {{constant expression}} expected-note {{non-constexpr function 'strlen' cannot be used in a constant expression}}
+ constexpr int wm = wcslen(L"hello"); // expected-error {{constant expression}} expected-note {{non-constexpr function 'wcslen' cannot be used in a constant expression}}
+
+ // Make sure we can evaluate a call to strlen.
+ int arr[3]; // expected-note 2{{here}}
+ int k = arr[strlen("hello")]; // expected-warning {{array index 5}}
+ int wk = arr[wcslen(L"hello")]; // expected-warning {{array index 5}}
+}
+
+namespace StrcmpEtc {
+ constexpr char kFoobar[6] = {'f','o','o','b','a','r'};
+ constexpr char kFoobazfoobar[12] = {'f','o','o','b','a','z','f','o','o','b','a','r'};
+
+ static_assert(__builtin_strcmp("abab", "abab") == 0);
+ static_assert(__builtin_strcmp("abab", "abba") == -1);
+ static_assert(__builtin_strcmp("abab", "abaa") == 1);
+ static_assert(__builtin_strcmp("ababa", "abab") == 1);
+ static_assert(__builtin_strcmp("abab", "ababa") == -1);
+ static_assert(__builtin_strcmp("abab\0banana", "abab") == 0);
+ static_assert(__builtin_strcmp("abab", "abab\0banana") == 0);
+ static_assert(__builtin_strcmp("abab\0banana", "abab\0canada") == 0);
+ static_assert(__builtin_strcmp(0, "abab") == 0); // expected-error {{not an integral constant}} expected-note {{dereferenced null}}
+ static_assert(__builtin_strcmp("abab", 0) == 0); // expected-error {{not an integral constant}} expected-note {{dereferenced null}}
+
+ static_assert(__builtin_strcmp(kFoobar, kFoobazfoobar) == -1); // FIXME: Should we reject this?
+ static_assert(__builtin_strcmp(kFoobar, kFoobazfoobar + 6) == 0); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}}
+
+ static_assert(__builtin_strncmp("abaa", "abba", 5) == -1);
+ static_assert(__builtin_strncmp("abaa", "abba", 4) == -1);
+ static_assert(__builtin_strncmp("abaa", "abba", 3) == -1);
+ static_assert(__builtin_strncmp("abaa", "abba", 2) == 0);
+ static_assert(__builtin_strncmp("abaa", "abba", 1) == 0);
+ static_assert(__builtin_strncmp("abaa", "abba", 0) == 0);
+ static_assert(__builtin_strncmp(0, 0, 0) == 0);
+ static_assert(__builtin_strncmp("abab\0banana", "abab\0canada", 100) == 0);
+
+ static_assert(__builtin_strncmp(kFoobar, kFoobazfoobar, 6) == -1);
+ static_assert(__builtin_strncmp(kFoobar, kFoobazfoobar, 7) == -1); // FIXME: Should we reject this?
+ static_assert(__builtin_strncmp(kFoobar, kFoobazfoobar + 6, 6) == 0);
+ static_assert(__builtin_strncmp(kFoobar, kFoobazfoobar + 6, 7) == 0); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}}
+
+ static_assert(__builtin_memcmp("abaa", "abba", 3) == -1);
+ static_assert(__builtin_memcmp("abaa", "abba", 2) == 0);
+ static_assert(__builtin_memcmp(0, 0, 0) == 0);
+ static_assert(__builtin_memcmp("abab\0banana", "abab\0banana", 100) == 0); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}}
+ static_assert(__builtin_memcmp("abab\0banana", "abab\0canada", 100) == -1); // FIXME: Should we reject this?
+ static_assert(__builtin_memcmp("abab\0banana", "abab\0canada", 7) == -1);
+ static_assert(__builtin_memcmp("abab\0banana", "abab\0canada", 6) == -1);
+ static_assert(__builtin_memcmp("abab\0banana", "abab\0canada", 5) == 0);
+
+ constexpr int a = strcmp("hello", "world"); // expected-error {{constant expression}} expected-note {{non-constexpr function 'strcmp' cannot be used in a constant expression}}
+ constexpr int b = strncmp("hello", "world", 3); // expected-error {{constant expression}} expected-note {{non-constexpr function 'strncmp' cannot be used in a constant expression}}
+ constexpr int c = memcmp("hello", "world", 3); // expected-error {{constant expression}} expected-note {{non-constexpr function 'memcmp' cannot be used in a constant expression}}
+}
+
+namespace WcscmpEtc {
+ constexpr wchar_t kFoobar[6] = {L'f',L'o',L'o',L'b',L'a',L'r'};
+ constexpr wchar_t kFoobazfoobar[12] = {L'f',L'o',L'o',L'b',L'a',L'z',L'f',L'o',L'o',L'b',L'a',L'r'};
+
+ static_assert(__builtin_wcscmp(L"abab", L"abab") == 0);
+ static_assert(__builtin_wcscmp(L"abab", L"abba") == -1);
+ static_assert(__builtin_wcscmp(L"abab", L"abaa") == 1);
+ static_assert(__builtin_wcscmp(L"ababa", L"abab") == 1);
+ static_assert(__builtin_wcscmp(L"abab", L"ababa") == -1);
+ static_assert(__builtin_wcscmp(L"abab\0banana", L"abab") == 0);
+ static_assert(__builtin_wcscmp(L"abab", L"abab\0banana") == 0);
+ static_assert(__builtin_wcscmp(L"abab\0banana", L"abab\0canada") == 0);
+ static_assert(__builtin_wcscmp(0, L"abab") == 0); // expected-error {{not an integral constant}} expected-note {{dereferenced null}}
+ static_assert(__builtin_wcscmp(L"abab", 0) == 0); // expected-error {{not an integral constant}} expected-note {{dereferenced null}}
+
+ static_assert(__builtin_wcscmp(kFoobar, kFoobazfoobar) == -1); // FIXME: Should we reject this?
+ static_assert(__builtin_wcscmp(kFoobar, kFoobazfoobar + 6) == 0); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}}
+
+ static_assert(__builtin_wcsncmp(L"abaa", L"abba", 5) == -1);
+ static_assert(__builtin_wcsncmp(L"abaa", L"abba", 4) == -1);
+ static_assert(__builtin_wcsncmp(L"abaa", L"abba", 3) == -1);
+ static_assert(__builtin_wcsncmp(L"abaa", L"abba", 2) == 0);
+ static_assert(__builtin_wcsncmp(L"abaa", L"abba", 1) == 0);
+ static_assert(__builtin_wcsncmp(L"abaa", L"abba", 0) == 0);
+ static_assert(__builtin_wcsncmp(0, 0, 0) == 0);
+ static_assert(__builtin_wcsncmp(L"abab\0banana", L"abab\0canada", 100) == 0);
+
+ static_assert(__builtin_wcsncmp(kFoobar, kFoobazfoobar, 6) == -1);
+ static_assert(__builtin_wcsncmp(kFoobar, kFoobazfoobar, 7) == -1); // FIXME: Should we reject this?
+ static_assert(__builtin_wcsncmp(kFoobar, kFoobazfoobar + 6, 6) == 0);
+ static_assert(__builtin_wcsncmp(kFoobar, kFoobazfoobar + 6, 7) == 0); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}}
+
+ static_assert(__builtin_wmemcmp(L"abaa", L"abba", 3) == -1);
+ static_assert(__builtin_wmemcmp(L"abaa", L"abba", 2) == 0);
+ static_assert(__builtin_wmemcmp(0, 0, 0) == 0);
+ static_assert(__builtin_wmemcmp(L"abab\0banana", L"abab\0banana", 100) == 0); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}}
+ static_assert(__builtin_wmemcmp(L"abab\0banana", L"abab\0canada", 100) == -1); // FIXME: Should we reject this?
+ static_assert(__builtin_wmemcmp(L"abab\0banana", L"abab\0canada", 7) == -1);
+ static_assert(__builtin_wmemcmp(L"abab\0banana", L"abab\0canada", 6) == -1);
+ static_assert(__builtin_wmemcmp(L"abab\0banana", L"abab\0canada", 5) == 0);
+
+ constexpr int a = wcscmp(L"hello", L"world"); // expected-error {{constant expression}} expected-note {{non-constexpr function 'wcscmp' cannot be used in a constant expression}}
+ constexpr int b = wcsncmp(L"hello", L"world", 3); // expected-error {{constant expression}} expected-note {{non-constexpr function 'wcsncmp' cannot be used in a constant expression}}
+ constexpr int c = wmemcmp(L"hello", L"world", 3); // expected-error {{constant expression}} expected-note {{non-constexpr function 'wmemcmp' cannot be used in a constant expression}}
+}
+
+namespace StrchrEtc {
+ constexpr const char *kStr = "abca\xff\0d";
+ constexpr char kFoo[] = {'f', 'o', 'o'};
+ static_assert(__builtin_strchr(kStr, 'a') == kStr);
+ static_assert(__builtin_strchr(kStr, 'b') == kStr + 1);
+ static_assert(__builtin_strchr(kStr, 'c') == kStr + 2);
+ static_assert(__builtin_strchr(kStr, 'd') == nullptr);
+ static_assert(__builtin_strchr(kStr, 'e') == nullptr);
+ static_assert(__builtin_strchr(kStr, '\0') == kStr + 5);
+ static_assert(__builtin_strchr(kStr, 'a' + 256) == nullptr);
+ static_assert(__builtin_strchr(kStr, 'a' - 256) == nullptr);
+ static_assert(__builtin_strchr(kStr, '\xff') == kStr + 4);
+ static_assert(__builtin_strchr(kStr, '\xff' + 256) == nullptr);
+ static_assert(__builtin_strchr(kStr, '\xff' - 256) == nullptr);
+ static_assert(__builtin_strchr(kFoo, 'o') == kFoo + 1);
+ static_assert(__builtin_strchr(kFoo, 'x') == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}}
+ static_assert(__builtin_strchr(nullptr, 'x') == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced null}}
+
+ static_assert(__builtin_memchr(kStr, 'a', 0) == nullptr);
+ static_assert(__builtin_memchr(kStr, 'a', 1) == kStr);
+ static_assert(__builtin_memchr(kStr, '\0', 5) == nullptr);
+ static_assert(__builtin_memchr(kStr, '\0', 6) == kStr + 5);
+ static_assert(__builtin_memchr(kStr, '\xff', 8) == kStr + 4);
+ static_assert(__builtin_memchr(kStr, '\xff' + 256, 8) == kStr + 4);
+ static_assert(__builtin_memchr(kStr, '\xff' - 256, 8) == kStr + 4);
+ static_assert(__builtin_memchr(kFoo, 'x', 3) == nullptr);
+ static_assert(__builtin_memchr(kFoo, 'x', 4) == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}}
+ static_assert(__builtin_memchr(nullptr, 'x', 3) == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced null}}
+ static_assert(__builtin_memchr(nullptr, 'x', 0) == nullptr); // FIXME: Should we reject this?
+
+ constexpr bool a = !strchr("hello", 'h'); // expected-error {{constant expression}} expected-note {{non-constexpr function 'strchr' cannot be used in a constant expression}}
+ constexpr bool b = !memchr("hello", 'h', 3); // expected-error {{constant expression}} expected-note {{non-constexpr function 'memchr' cannot be used in a constant expression}}
+}
+
+namespace WcschrEtc {
+ constexpr const wchar_t *kStr = L"abca\xffff\0dL";
+ constexpr wchar_t kFoo[] = {L'f', L'o', L'o'};
+ static_assert(__builtin_wcschr(kStr, L'a') == kStr);
+ static_assert(__builtin_wcschr(kStr, L'b') == kStr + 1);
+ static_assert(__builtin_wcschr(kStr, L'c') == kStr + 2);
+ static_assert(__builtin_wcschr(kStr, L'd') == nullptr);
+ static_assert(__builtin_wcschr(kStr, L'e') == nullptr);
+ static_assert(__builtin_wcschr(kStr, L'\0') == kStr + 5);
+ static_assert(__builtin_wcschr(kStr, L'a' + 256) == nullptr);
+ static_assert(__builtin_wcschr(kStr, L'a' - 256) == nullptr);
+ static_assert(__builtin_wcschr(kStr, L'\xffff') == kStr + 4);
+ static_assert(__builtin_wcschr(kFoo, L'o') == kFoo + 1);
+ static_assert(__builtin_wcschr(kFoo, L'x') == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}}
+ static_assert(__builtin_wcschr(nullptr, L'x') == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced null}}
+
+ static_assert(__builtin_wmemchr(kStr, L'a', 0) == nullptr);
+ static_assert(__builtin_wmemchr(kStr, L'a', 1) == kStr);
+ static_assert(__builtin_wmemchr(kStr, L'\0', 5) == nullptr);
+ static_assert(__builtin_wmemchr(kStr, L'\0', 6) == kStr + 5);
+ static_assert(__builtin_wmemchr(kStr, L'\xffff', 8) == kStr + 4);
+ static_assert(__builtin_wmemchr(kFoo, L'x', 3) == nullptr);
+ static_assert(__builtin_wmemchr(kFoo, L'x', 4) == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}}
+ static_assert(__builtin_wmemchr(nullptr, L'x', 3) == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced null}}
+ static_assert(__builtin_wmemchr(nullptr, L'x', 0) == nullptr); // FIXME: Should we reject this?
+
+ constexpr bool a = !wcschr(L"hello", L'h'); // expected-error {{constant expression}} expected-note {{non-constexpr function 'wcschr' cannot be used in a constant expression}}
+ constexpr bool b = !wmemchr(L"hello", L'h', 3); // expected-error {{constant expression}} expected-note {{non-constexpr function 'wmemchr' cannot be used in a constant expression}}
+}
diff --git a/test/SemaCXX/constexpr-strlen.cpp b/test/SemaCXX/constexpr-strlen.cpp
deleted file mode 100644
index 5e28e7f0ce5f..000000000000
--- a/test/SemaCXX/constexpr-strlen.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: %clang_cc1 %s -std=c++11 -fsyntax-only -verify -pedantic
-
-# 1 "/usr/include/string.h" 1 3 4
-extern "C" {
- typedef decltype(sizeof(int)) size_t;
- extern size_t strlen(const char *p);
-}
-
-# 10 "SemaCXX/constexpr-strlen.cpp" 2
-constexpr int n = __builtin_strlen("hello"); // ok
-constexpr int m = strlen("hello"); // expected-error {{constant expression}} expected-note {{non-constexpr function 'strlen' cannot be used in a constant expression}}
-
-// Make sure we can evaluate a call to strlen.
-int arr[3]; // expected-note {{here}}
-int k = arr[strlen("hello")]; // expected-warning {{array index 5}}
diff --git a/test/SemaCXX/constexpr-value-init.cpp b/test/SemaCXX/constexpr-value-init.cpp
index 3528fdcd8816..53271e0da3fa 100644
--- a/test/SemaCXX/constexpr-value-init.cpp
+++ b/test/SemaCXX/constexpr-value-init.cpp
@@ -34,4 +34,13 @@ struct V : virtual C {};
template<typename T> struct Z : T {
constexpr Z() : V() {}
};
-constexpr int n = Z<V>().c; // expected-error {{constant expression}} expected-note {{virtual base class}}
+constexpr int n = Z<V>().c; // expected-error {{constant expression}} expected-note {{non-literal type 'Z<V>'}}
+
+struct E {
+ A a[2];
+};
+constexpr E e; // ok
+static_assert(e.a[0].a == 1, "");
+static_assert(e.a[0].b == 2, "");
+static_assert(e.a[1].a == 1, "");
+static_assert(e.a[1].b == 2, "");
diff --git a/test/SemaCXX/conversion-function.cpp b/test/SemaCXX/conversion-function.cpp
index 3f494cce8ce3..c725a0d5b7c1 100644
--- a/test/SemaCXX/conversion-function.cpp
+++ b/test/SemaCXX/conversion-function.cpp
@@ -434,8 +434,12 @@ namespace PR18234 {
struct A {
operator enum E { e } (); // expected-error {{'PR18234::A::E' cannot be defined in a type specifier}}
operator struct S { int n; } (); // expected-error {{'PR18234::A::S' cannot be defined in a type specifier}}
+ // expected-note@-1 {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'struct A' to 'const PR18234::A::S &' for 1st argument}}
+#if __cplusplus >= 201103L
+ // expected-note@-3 {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'struct A' to 'PR18234::A::S &&' for 1st argument}}
+#endif
} a;
- A::S s = a;
+ A::S s = a; // expected-error {{no viable conversion from 'struct A' to 'A::S'}}
A::E e = a; // expected-note {{here}}
bool k1 = e == A::e; // expected-error {{no member named 'e'}}
bool k2 = e.n == 0;
diff --git a/test/SemaCXX/conversion.cpp b/test/SemaCXX/conversion.cpp
index 7b86cecdbcef..dcd64fa2ec8a 100644
--- a/test/SemaCXX/conversion.cpp
+++ b/test/SemaCXX/conversion.cpp
@@ -50,7 +50,7 @@ namespace test1 {
namespace test2 {
struct A {
unsigned int x : 2;
- A() : x(10) {} // expected-warning {{implicit truncation from 'int' to bitfield changes value from 10 to 2}}
+ A() : x(10) {} // expected-warning {{implicit truncation from 'int' to bit-field changes value from 10 to 2}}
};
}
diff --git a/test/SemaCXX/copy-assignment.cpp b/test/SemaCXX/copy-assignment.cpp
index 798582c149cf..d6ad6577895f 100644
--- a/test/SemaCXX/copy-assignment.cpp
+++ b/test/SemaCXX/copy-assignment.cpp
@@ -1,4 +1,11 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+
+#if __cplusplus >= 201103L
+// expected-note@+3 2 {{candidate constructor}}
+// expected-note@+2 {{passing argument to parameter here}}
+#endif
struct A {
};
@@ -7,6 +14,9 @@ struct ConvertibleToA {
};
struct ConvertibleToConstA {
+#if __cplusplus >= 201103L
+// expected-note@+2 {{candidate function}}
+#endif
operator const A();
};
@@ -69,6 +79,9 @@ void test() {
na = a;
na = constA;
na = convertibleToA;
+#if __cplusplus >= 201103L
+// expected-error@+2 {{no viable conversion}}
+#endif
na = convertibleToConstA;
na += a; // expected-error{{no viable overloaded '+='}}
diff --git a/test/SemaCXX/copy-initialization.cpp b/test/SemaCXX/copy-initialization.cpp
index d219ee508f03..4f6c65cf550c 100644
--- a/test/SemaCXX/copy-initialization.cpp
+++ b/test/SemaCXX/copy-initialization.cpp
@@ -30,7 +30,7 @@ void test(const foo *P) { P->bar(); } // expected-error{{'bar' not viable: 'this
namespace PR6757 {
struct Foo {
- Foo();
+ Foo(); // expected-note{{not viable}}
Foo(Foo&); // expected-note{{candidate constructor not viable}}
};
@@ -71,3 +71,12 @@ namespace DR5 {
const S b = 0;
}
}
+
+struct A {};
+struct B : A {
+ B();
+ B(B&);
+ B(A);
+ B(int);
+};
+B b = 0; // ok, calls B(int) then A(const A&) then B(A).
diff --git a/test/SemaCXX/coreturn.cpp b/test/SemaCXX/coreturn.cpp
new file mode 100644
index 000000000000..4c41ae95c513
--- /dev/null
+++ b/test/SemaCXX/coreturn.cpp
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++14 -fcoroutines-ts -fsyntax-only -Wignored-qualifiers -Wno-error=return-type -verify -fblocks -Wno-unreachable-code -Wno-unused-value
+
+struct awaitable {
+ bool await_ready();
+ void await_suspend(); // FIXME: coroutine_handle
+ void await_resume();
+} a;
+
+struct suspend_always {
+ bool await_ready() { return false; }
+ void await_suspend() {}
+ void await_resume() {}
+};
+
+struct suspend_never {
+ bool await_ready() { return true; }
+ void await_suspend() {}
+ void await_resume() {}
+};
+
+namespace std {
+namespace experimental {
+
+template <class Ret, typename... T>
+struct coroutine_traits { using promise_type = typename Ret::promise_type; };
+
+template <class Promise = void>
+struct coroutine_handle {};
+}
+}
+
+struct promise_void {
+ void get_return_object();
+ suspend_always initial_suspend();
+ suspend_always final_suspend();
+ void return_void();
+};
+
+struct promise_float {
+ float get_return_object();
+ suspend_always initial_suspend();
+ suspend_always final_suspend();
+ void return_void();
+};
+
+struct promise_int {
+ int get_return_object();
+ suspend_always initial_suspend();
+ suspend_always final_suspend();
+ void return_value(int);
+};
+
+template <typename... T>
+struct std::experimental::coroutine_traits<void, T...> { using promise_type = promise_void; };
+
+template <typename... T>
+struct std::experimental::coroutine_traits<float, T...> { using promise_type = promise_float; };
+
+template <typename... T>
+struct std::experimental::coroutine_traits<int, T...> { using promise_type = promise_int; };
+
+void test0() { co_await a; }
+float test1() { co_await a; }
+
+int test2() {
+ co_await a;
+} // expected-warning {{control reaches end of non-void coroutine}}
+
+int test3() {
+ co_await a;
+b:
+ goto b;
+}
diff --git a/test/SemaCXX/coroutines.cpp b/test/SemaCXX/coroutines.cpp
index e82cb62f12d4..a22383cd566b 100644
--- a/test/SemaCXX/coroutines.cpp
+++ b/test/SemaCXX/coroutines.cpp
@@ -1,4 +1,21 @@
-// RUN: %clang_cc1 -std=c++14 -fcoroutines -verify %s
+// RUN: %clang_cc1 -std=c++14 -fcoroutines-ts -verify %s
+
+void no_coroutine_traits_bad_arg_await() {
+ co_await a; // expected-error {{include <experimental/coroutine>}}
+ // expected-error@-1 {{use of undeclared identifier 'a'}}
+}
+
+void no_coroutine_traits_bad_arg_yield() {
+ co_yield a; // expected-error {{include <experimental/coroutine>}}
+ // expected-error@-1 {{use of undeclared identifier 'a'}}
+}
+
+
+void no_coroutine_traits_bad_arg_return() {
+ co_return a; // expected-error {{include <experimental/coroutine>}}
+ // expected-error@-1 {{use of undeclared identifier 'a'}}
+}
+
struct awaitable {
bool await_ready();
@@ -19,45 +36,64 @@ struct suspend_never {
};
void no_coroutine_traits() {
- co_await a; // expected-error {{need to include <coroutine>}}
+ co_await a; // expected-error {{need to include <experimental/coroutine>}}
}
namespace std {
- template<typename ...T> struct coroutine_traits; // expected-note {{declared here}}
-};
+namespace experimental {
+template <typename... T>
+struct coroutine_traits; // expected-note {{declared here}}
+}
+}
template<typename Promise> struct coro {};
-template<typename Promise, typename... Ps>
-struct std::coroutine_traits<coro<Promise>, Ps...> {
+template <typename Promise, typename... Ps>
+struct std::experimental::coroutine_traits<coro<Promise>, Ps...> {
using promise_type = Promise;
};
void no_specialization() {
- co_await a; // expected-error {{implicit instantiation of undefined template 'std::coroutine_traits<void>'}}
+ co_await a; // expected-error {{implicit instantiation of undefined template 'std::experimental::coroutine_traits<void>'}}
}
-template<typename ...T> struct std::coroutine_traits<int, T...> {};
+template <typename... T>
+struct std::experimental::coroutine_traits<int, T...> {};
int no_promise_type() {
- co_await a; // expected-error {{this function cannot be a coroutine: 'std::coroutine_traits<int>' has no member named 'promise_type'}}
+ co_await a; // expected-error {{this function cannot be a coroutine: 'std::experimental::coroutine_traits<int>' has no member named 'promise_type'}}
}
-template<> struct std::coroutine_traits<double, double> { typedef int promise_type; };
+template <>
+struct std::experimental::coroutine_traits<double, double> { typedef int promise_type; };
double bad_promise_type(double) {
- co_await a; // expected-error {{this function cannot be a coroutine: 'std::coroutine_traits<double, double>::promise_type' (aka 'int') is not a class}}
+ co_await a; // expected-error {{this function cannot be a coroutine: 'experimental::coroutine_traits<double, double>::promise_type' (aka 'int') is not a class}}
}
-template<> struct std::coroutine_traits<double, int> {
+template <>
+struct std::experimental::coroutine_traits<double, int> {
struct promise_type {};
};
double bad_promise_type_2(int) {
- co_yield 0; // expected-error {{no member named 'yield_value' in 'std::coroutine_traits<double, int>::promise_type'}}
+ co_yield 0; // expected-error {{no member named 'yield_value' in 'std::experimental::coroutine_traits<double, int>::promise_type'}}
}
struct promise; // expected-note 2{{forward declaration}}
-template<typename ...T> struct std::coroutine_traits<void, T...> { using promise_type = promise; };
+struct promise_void;
+struct void_tag {};
+template <typename... T>
+struct std::experimental::coroutine_traits<void, T...> { using promise_type = promise; };
+template <typename... T>
+struct std::experimental::coroutine_traits<void, void_tag, T...>
+{ using promise_type = promise_void; };
+
+namespace std {
+namespace experimental {
+template <typename Promise = void>
+struct coroutine_handle;
+}
+}
- // FIXME: This diagnostic is terrible.
+// FIXME: This diagnostic is terrible.
void undefined_promise() { // expected-error {{variable has incomplete type 'promise_type'}}
// FIXME: This diagnostic doesn't make any sense.
// expected-error@-2 {{incomplete definition of type 'promise'}}
@@ -75,10 +111,16 @@ struct promise {
awaitable yield_value(int); // expected-note 2{{candidate}}
awaitable yield_value(yielded_thing); // expected-note 2{{candidate}}
not_awaitable yield_value(void()); // expected-note 2{{candidate}}
- void return_void();
void return_value(int); // expected-note 2{{here}}
};
+struct promise_void {
+ void get_return_object();
+ suspend_always initial_suspend();
+ suspend_always final_suspend();
+ void return_void();
+};
+
void yield() {
co_yield 0;
co_yield {"foo", 1, 2};
@@ -95,10 +137,10 @@ void coreturn(int n) {
if (n == 0)
co_return 3;
if (n == 1)
- co_return {4};
+ co_return {4}; // expected-warning {{braces around scalar initializer}}
if (n == 2)
co_return "foo"; // expected-error {{cannot initialize a parameter of type 'int' with an lvalue of type 'const char [4]'}}
- co_return;
+ co_return 42;
}
void mixed_yield() {
@@ -111,11 +153,11 @@ void mixed_await() {
return; // expected-error {{not allowed in coroutine}}
}
-void only_coreturn() {
+void only_coreturn(void_tag) {
co_return; // expected-warning {{'co_return' used in a function that uses neither 'co_await' nor 'co_yield'}}
}
-void mixed_coreturn(bool b) {
+void mixed_coreturn(void_tag, bool b) {
if (b)
// expected-warning@+1 {{'co_return' used in a function that uses neither}}
co_return; // expected-note {{use of 'co_return'}}
@@ -136,7 +178,19 @@ struct CtorDtor {
}
// FIXME: The spec says this is ill-formed.
void operator=(CtorDtor&) {
- co_yield 0;
+ co_yield 0; // expected-error {{'co_yield' cannot be used in a copy assignment operator}}
+ }
+ void operator=(CtorDtor const &) {
+ co_yield 0; // expected-error {{'co_yield' cannot be used in a copy assignment operator}}
+ }
+ void operator=(CtorDtor &&) {
+ co_await a; // expected-error {{'co_await' cannot be used in a move assignment operator}}
+ }
+ void operator=(CtorDtor const &&) {
+ co_await a; // expected-error {{'co_await' cannot be used in a move assignment operator}}
+ }
+ void operator=(int) {
+ co_await a; // OK. Not a special member
}
};
@@ -149,14 +203,19 @@ void unevaluated() {
typeid(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
}
-constexpr void constexpr_coroutine() {
+constexpr auto constexpr_deduced_return_coroutine() {
co_yield 0; // expected-error {{'co_yield' cannot be used in a constexpr function}}
+ // expected-error@-1 {{'co_yield' cannot be used in a function with a deduced return type}}
}
void varargs_coroutine(const char *, ...) {
co_await a; // expected-error {{'co_await' cannot be used in a varargs function}}
}
+auto deduced_return_coroutine() {
+ co_await a; // expected-error {{'co_await' cannot be used in a function with a deduced return type}}
+}
+
struct outer {};
namespace dependent_operator_co_await_lookup {
@@ -183,7 +242,8 @@ namespace dependent_operator_co_await_lookup {
}
struct yield_fn_tag {};
-template<> struct std::coroutine_traits<void, yield_fn_tag> {
+template <>
+struct std::experimental::coroutine_traits<void, yield_fn_tag> {
struct promise_type {
// FIXME: add an await_transform overload for functions
awaitable yield_value(int());
@@ -266,3 +326,52 @@ struct bad_promise_5 {
coro<bad_promise_5> bad_final_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
co_await a;
}
+
+struct bad_promise_6 {
+ coro<bad_promise_6> get_return_object();
+ suspend_always initial_suspend();
+ suspend_always final_suspend();
+ void return_void();
+ void return_value(int) const;
+ void return_value(int);
+};
+coro<bad_promise_6> bad_implicit_return() { // expected-error {{'bad_promise_6' declares both 'return_value' and 'return_void'}}
+ co_await a;
+}
+
+struct bad_promise_7 {
+ coro<bad_promise_7> get_return_object();
+ suspend_always initial_suspend();
+ suspend_always final_suspend();
+ void return_void();
+ void set_exception(int *);
+};
+coro<bad_promise_7> no_std_current_exc() {
+ // expected-error@-1 {{you need to include <exception> before defining a coroutine that implicitly uses 'set_exception'}}
+ co_await a;
+}
+
+namespace std {
+int *current_exception();
+}
+
+struct bad_promise_8 {
+ coro<bad_promise_8> get_return_object();
+ suspend_always initial_suspend();
+ suspend_always final_suspend();
+ void return_void();
+ void set_exception(); // expected-note {{function not viable}}
+ void set_exception(int *) __attribute__((unavailable)); // expected-note {{explicitly made unavailable}}
+ void set_exception(void *); // expected-note {{candidate function}}
+};
+coro<bad_promise_8> calls_set_exception() {
+ // expected-error@-1 {{call to unavailable member function 'set_exception'}}
+ co_await a;
+}
+
+template<> struct std::experimental::coroutine_traits<int, int, const char**>
+{ using promise_type = promise; };
+
+int main(int, const char**) {
+ co_await a; // expected-error {{'co_await' cannot be used in the 'main' function}}
+}
diff --git a/test/SemaCXX/cxx0x-defaulted-functions.cpp b/test/SemaCXX/cxx0x-defaulted-functions.cpp
index 7ec9726095cb..f623dc765f88 100644
--- a/test/SemaCXX/cxx0x-defaulted-functions.cpp
+++ b/test/SemaCXX/cxx0x-defaulted-functions.cpp
@@ -87,35 +87,36 @@ namespace DefaultedFnExceptionSpec {
template<typename T>
struct Error {
- // FIXME: Type canonicalization causes all the errors to point at the first
- // declaration which has the type 'void () noexcept (T::error)'. We should
- // get one error for 'Error<int>::Error()' and one for 'Error<int>::~Error()'.
- void f() noexcept(T::error); // expected-error 2{{has no members}}
-
- Error() noexcept(T::error);
- Error(const Error&) noexcept(T::error);
- Error(Error&&) noexcept(T::error);
- Error &operator=(const Error&) noexcept(T::error);
- Error &operator=(Error&&) noexcept(T::error);
- ~Error() noexcept(T::error);
+ void f() noexcept(T::error);
+
+ Error() noexcept(T::error); // expected-error {{type 'int' cannot be used prior to '::' because it has no members}} expected-error {{type 'char'}}
+ Error(const Error&) noexcept(T::error); // expected-error {{type 'int' cannot be used prior to '::' because it has no members}}
+ Error(Error&&) noexcept(T::error); // expected-error {{type 'int' cannot be used prior to '::' because it has no members}}
+ Error &operator=(const Error&) noexcept(T::error); // expected-error {{type 'int' cannot be used prior to '::' because it has no members}} expected-error {{type 'double'}}
+ Error &operator=(Error&&) noexcept(T::error); // expected-error {{type 'int' cannot be used prior to '::' because it has no members}}
+ ~Error() noexcept(T::error); // expected-error {{type 'int' cannot be used prior to '::' because it has no members}} expected-error {{type 'char'}}
};
+ Error<char> c; // expected-note 2{{instantiation of}}
struct DelayImplicit {
- Error<int> e;
+ // FIXME: The location of this note is terrible. The instantiation was
+ // triggered by the uses of the functions in the decltype expressions below.
+ Error<int> e; // expected-note 6{{instantiation of}}
};
+ Error<float> *e;
- // Don't instantiate the exception specification here.
+ // An exception specification is needed if the exception specification for a
+ // a defaulted special member function that calls the function is needed.
+ // Use in an unevaluated operand still results in the exception spec being
+ // needed.
void test1(decltype(declval<DelayImplicit>() = DelayImplicit(DelayImplicit())));
void test2(decltype(declval<DelayImplicit>() = declval<const DelayImplicit>()));
void test3(decltype(DelayImplicit(declval<const DelayImplicit>())));
- // Any odr-use causes the exception specification to be evaluated.
- struct OdrUse { // \
- expected-note {{instantiation of exception specification for 'Error'}} \
- expected-note {{instantiation of exception specification for '~Error'}}
- Error<int> e;
- };
- OdrUse use; // expected-note {{implicit default constructor for 'DefaultedFnExceptionSpec::OdrUse' first required here}}
+ // Any odr-use needs the exception specification.
+ void f(Error<double> *p) {
+ *p = *p; // expected-note {{instantiation of}}
+ }
}
namespace PR13527 {
@@ -142,11 +143,11 @@ namespace PR13527 {
Y &operator=(Y&&) = default;
~Y() = default;
};
- Y::Y() = default; // expected-error {{definition of explicitly defaulted}}
- Y::Y(const Y&) = default; // expected-error {{definition of explicitly defaulted}}
- Y::Y(Y&&) = default; // expected-error {{definition of explicitly defaulted}}
- Y &Y::operator=(const Y&) = default; // expected-error {{definition of explicitly defaulted}}
- Y &Y::operator=(Y&&) = default; // expected-error {{definition of explicitly defaulted}}
+ Y::Y() noexcept = default; // expected-error {{definition of explicitly defaulted}}
+ Y::Y(const Y&) noexcept = default; // expected-error {{definition of explicitly defaulted}}
+ Y::Y(Y&&) noexcept = default; // expected-error {{definition of explicitly defaulted}}
+ Y &Y::operator=(const Y&) noexcept = default; // expected-error {{definition of explicitly defaulted}}
+ Y &Y::operator=(Y&&) noexcept = default; // expected-error {{definition of explicitly defaulted}}
Y::~Y() = default; // expected-error {{definition of explicitly defaulted}}
}
@@ -179,7 +180,7 @@ namespace PR14577 {
Outer<T>::Inner2<T>::~Inner2() = default; // expected-error {{nested name specifier 'Outer<T>::Inner2<T>::' for declaration does not refer into a class, class template or class template partial specialization}} expected-error {{only special member functions may be defaulted}}
}
-extern "C" {
+extern "C" { // expected-note {{extern "C" language linkage specification begins here}}
template<typename _Tp> // expected-error {{templates must have C++ linkage}}
void PR13573(const _Tp&) = delete;
}
diff --git a/test/SemaCXX/cxx0x-initializer-constructor.cpp b/test/SemaCXX/cxx0x-initializer-constructor.cpp
index 6202bf620fe3..c10bee917ac0 100644
--- a/test/SemaCXX/cxx0x-initializer-constructor.cpp
+++ b/test/SemaCXX/cxx0x-initializer-constructor.cpp
@@ -267,8 +267,11 @@ namespace PR12120 {
struct A { explicit A(int); A(float); }; // expected-note {{declared here}}
A a = { 0 }; // expected-error {{constructor is explicit}}
- struct B { explicit B(short); B(long); }; // expected-note 2 {{candidate}}
+ struct B { explicit B(short); B(long); }; // expected-note 4{{candidate}}
B b = { 0 }; // expected-error {{ambiguous}}
+
+ struct C { explicit C(short); C(long); }; // expected-note 2{{candidate}}
+ C c = {{ 0 }}; // expected-error {{ambiguous}}
}
namespace PR12498 {
diff --git a/test/SemaCXX/cxx0x-initializer-references.cpp b/test/SemaCXX/cxx0x-initializer-references.cpp
index 390047ea0752..c64511193b6e 100644
--- a/test/SemaCXX/cxx0x-initializer-references.cpp
+++ b/test/SemaCXX/cxx0x-initializer-references.cpp
@@ -72,10 +72,9 @@ namespace reference {
}
void edge_cases() {
- // FIXME: very poor error message
- int const &b({0}); // expected-error {{could not bind}}
+ int const &b({0}); // expected-error {{list-initializer for non-class type 'const int &' must not be parenthesized}}
+ const int (&arr)[3] ({1, 2, 3}); // expected-error {{list-initializer for non-class type 'const int (&)[3]' must not be parenthesized}}
}
-
}
namespace PR12182 {
diff --git a/test/SemaCXX/cxx0x-initializer-scalars.cpp b/test/SemaCXX/cxx0x-initializer-scalars.cpp
index c9d5ffd19429..65b57a5584ab 100644
--- a/test/SemaCXX/cxx0x-initializer-scalars.cpp
+++ b/test/SemaCXX/cxx0x-initializer-scalars.cpp
@@ -91,10 +91,23 @@ namespace integral {
}
void edge_cases() {
- // FIXME: very poor error message
- int a({0}); // expected-error {{cannot initialize}}
- (void) int({0}); // expected-error {{functional-style cast}}
- new int({0}); // expected-error {{cannot initialize}}
+ int a({0}); // expected-error {{list-initializer for non-class type 'int' must not be parenthesized}}
+ (void) int({0}); // expected-error {{list-initializer for non-class type 'int' must not be parenthesized}}
+ new int({0}); // expected-error {{list-initializer for non-class type 'int' must not be parenthesized}}
+
+ int *b({0}); // expected-error {{list-initializer for non-class type 'int *' must not be parenthesized}}
+ typedef int *intptr;
+ int *c = intptr({0}); // expected-error {{list-initializer for non-class type 'intptr' (aka 'int *') must not be parenthesized}}
+ }
+
+ template<typename T> void dependent_edge_cases() {
+ T a({0});
+ (void) T({0});
+ new T({0});
+
+ T *b({0});
+ typedef T *tptr;
+ T *c = tptr({0});
}
void default_argument(int i = {}) {
diff --git a/test/SemaCXX/cxx11-ast-print.cpp b/test/SemaCXX/cxx11-ast-print.cpp
index 1eeb67a3d9b3..9c617af4e95f 100644
--- a/test/SemaCXX/cxx11-ast-print.cpp
+++ b/test/SemaCXX/cxx11-ast-print.cpp
@@ -43,6 +43,14 @@ template <class C, C...> const char *operator"" _suffix();
// CHECK: const char *PR23120 = operator""_suffix<char32_t, 66615>();
const char *PR23120 = U"𐐷"_suffix;
+// PR28885
+struct A {
+ A();
+};
+struct B : A {
+ using A::A; // CHECK: using A::A;
+}; // CHECK-NEXT: };
+
// CHECK: ;
;
// CHECK-NOT: ;
diff --git a/test/SemaCXX/cxx11-inheriting-ctors.cpp b/test/SemaCXX/cxx11-inheriting-ctors.cpp
index 9c33ac05cc5f..5ce8d1aa3e0b 100644
--- a/test/SemaCXX/cxx11-inheriting-ctors.cpp
+++ b/test/SemaCXX/cxx11-inheriting-ctors.cpp
@@ -1,7 +1,5 @@
// RUN: %clang_cc1 -std=c++11 %s -verify
-// expected-no-diagnostics
-
namespace PR15757 {
struct S {
};
@@ -56,3 +54,33 @@ namespace InvalidConstruction {
template<typename T> int &f(...);
int &r = f<C>(0);
}
+
+namespace ExplicitConv {
+ struct B {}; // expected-note 2{{candidate}}
+ struct D : B { // expected-note 3{{candidate}}
+ using B::B; // expected-note 2{{inherited}}
+ };
+ struct X { explicit operator B(); } x;
+ struct Y { explicit operator D(); } y;
+
+ D dx(x); // expected-error {{no matching constructor}}
+ D dy(y);
+}
+
+namespace NestedListInit {
+ struct B { B(); } b; // expected-note 5{{candidate}}
+ struct D : B { // expected-note 3{{candidate}}
+ using B::B; // expected-note 2{{inherited}}
+ };
+ // This is a bit weird. We're allowed one pair of braces for overload
+ // resolution, and one more pair of braces due to [over.ics.list]/2.
+ B b1 = {b};
+ B b2 = {{b}};
+ B b3 = {{{b}}}; // expected-error {{no match}}
+ // This is the same, but we get one call to D's version of B::B(const B&)
+ // before the two permitted calls to D::D(D&&).
+ D d1 = {b};
+ D d2 = {{b}};
+ D d3 = {{{b}}};
+ D d4 = {{{{b}}}}; // expected-error {{no match}}
+}
diff --git a/test/SemaCXX/cxx1y-initializer-aggregates.cpp b/test/SemaCXX/cxx1y-initializer-aggregates.cpp
index 9b542403def3..3d5e7726a17e 100644
--- a/test/SemaCXX/cxx1y-initializer-aggregates.cpp
+++ b/test/SemaCXX/cxx1y-initializer-aggregates.cpp
@@ -61,3 +61,19 @@ namespace nested_aggregate_init {
};
static_assert(B(6).f() == 18, "");
}
+
+namespace use_self {
+ struct FibTree {
+ int n;
+ FibTree *l = // expected-note {{declared here}}
+ n > 1 ? new FibTree{n-1} : &fib0; // expected-error {{default member initializer for 'l' needed}}
+ FibTree *r = // expected-note {{declared here}}
+ n > 2 ? new FibTree{n-2} : &fib0; // expected-error {{default member initializer for 'r' needed}}
+ int v = l->v + r->v;
+
+ static FibTree fib0;
+ };
+ FibTree FibTree::fib0{0, nullptr, nullptr, 1};
+
+ int fib(int n) { return FibTree{n}.v; }
+}
diff --git a/test/SemaCXX/cxx1y-variable-templates_in_class.cpp b/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
index e2fbdfd69954..76f1bb9905b9 100644
--- a/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
+++ b/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -26,10 +26,10 @@ namespace out_of_line {
template<typename T, typename T0> static CONST T right = T(100);
template<typename T> static CONST T right<T,int> = T(5);
};
- template<> CONST int B0::right<int,int> = 7;
- template CONST int B0::right<int,int>;
- template<> CONST int B0::right<int,float>;
- template CONST int B0::right<int,float>;
+ template<> CONST int B0::right<int,int> = 7; // expected-note {{previous}}
+ template CONST int B0::right<int,int>; // expected-warning {{has no effect}}
+ template<> CONST int B0::right<int,float>; // expected-note {{previous}}
+ template CONST int B0::right<int,float>; // expected-warning {{has no effect}}
class B1 {
template<typename T, typename T0> static CONST T right;
diff --git a/test/SemaCXX/cxx1y-variable-templates_top_level.cpp b/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
index 496ae888732f..ec3e2b6f63d1 100644
--- a/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
+++ b/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
@@ -264,9 +264,9 @@ namespace explicit_specialization {
template<typename T>
T pi0 = T(3.1415926535897932385); // expected-note {{variable template 'pi0' declared here}}
- template<> int pi0<int> = 10;
- template int pi0<int>;
- template float pi0<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0' does not match expected type}}
+ template<> int pi0<int> = 10; // expected-note 2{{previous template specialization is here}}
+ template int pi0<int>; // expected-warning {{has no effect}}
+ template float pi0<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0' does not match expected type}} expected-warning {{has no effect}}
template<typename T1, typename T2>
CONST int pi2 = 1;
diff --git a/test/SemaCXX/cxx1z-constexpr-lambdas.cpp b/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
new file mode 100644
index 000000000000..90a07665cbf7
--- /dev/null
+++ b/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks %s
+// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s
+// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s -DCPP14_AND_EARLIER
+
+
+namespace test_lambda_is_literal {
+#ifdef CPP14_AND_EARLIER
+//expected-error@+4{{not a literal type}}
+//expected-note@+2{{not an aggregate and has no constexpr constructors}}
+#endif
+auto L = [] { };
+constexpr int foo(decltype(L) l) { return 0; }
+
+}
+
+#ifndef CPP14_AND_EARLIER
+namespace test_constexpr_checking {
+
+namespace ns1 {
+ struct NonLit { ~NonLit(); }; //expected-note{{not literal}}
+ auto L = [](NonLit NL) constexpr { }; //expected-error{{not a literal type}}
+} // end ns1
+
+namespace ns2 {
+ auto L = [](int I) constexpr { asm("non-constexpr"); }; //expected-error{{not allowed in constexpr function}}
+} // end ns1
+
+} // end ns test_constexpr_checking
+
+namespace test_constexpr_call {
+
+namespace ns1 {
+ auto L = [](int I) { return I; };
+ static_assert(L(3) == 3);
+} // end ns1
+namespace ns2 {
+ auto L = [](auto a) { return a; };
+ static_assert(L(3) == 3);
+ static_assert(L(3.14) == 3.14);
+}
+namespace ns3 {
+ auto L = [](auto a) { asm("non-constexpr"); return a; }; //expected-note{{declared here}}
+ constexpr int I = //expected-error{{must be initialized by a constant expression}}
+ L(3); //expected-note{{non-constexpr function}}
+}
+
+} // end ns test_constexpr_call
+
+namespace test_captureless_lambda {
+void f() {
+ const char c = 'c';
+ auto L = [] { return c; };
+ constexpr char C = L();
+}
+
+void f(char c) { //expected-note{{declared here}}
+ auto L = [] { return c; }; //expected-error{{cannot be implicitly captured}} expected-note{{lambda expression begins here}}
+ int I = L();
+}
+
+}
+#endif // ndef CPP14_AND_EARLIER
diff --git a/test/SemaCXX/cxx1z-copy-omission.cpp b/test/SemaCXX/cxx1z-copy-omission.cpp
new file mode 100644
index 000000000000..e2b8fd796174
--- /dev/null
+++ b/test/SemaCXX/cxx1z-copy-omission.cpp
@@ -0,0 +1,134 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+struct Noncopyable {
+ Noncopyable();
+ Noncopyable(const Noncopyable &) = delete; // expected-note 1+{{deleted}}
+ virtual ~Noncopyable();
+};
+struct Derived : Noncopyable {};
+struct NoncopyableAggr {
+ Noncopyable nc;
+};
+struct Indestructible {
+ Indestructible();
+ ~Indestructible() = delete; // expected-note 1+{{deleted}}
+};
+struct Incomplete; // expected-note 1+{{declar}}
+
+Noncopyable make(int kind = 0) {
+ switch (kind) {
+ case 0: return {};
+ case 1: return Noncopyable();
+ case 2: return Noncopyable{};
+ case 3: return make();
+ }
+ __builtin_unreachable();
+}
+
+Indestructible make_indestructible();
+Incomplete make_incomplete(); // expected-note 1+{{here}}
+
+void take(Noncopyable nc) {}
+
+Noncopyable nrvo() {
+ Noncopyable nrvo;
+ return nrvo; // expected-error {{deleted constructor}}
+}
+
+Noncopyable nc1 = make();
+Noncopyable nc2 = Noncopyable();
+Noncopyable nc3 = Derived(); // expected-error {{deleted constructor}}
+
+NoncopyableAggr nca1 = NoncopyableAggr{};
+NoncopyableAggr nca2 = NoncopyableAggr{{}};
+NoncopyableAggr nca3 = NoncopyableAggr{NoncopyableAggr{Noncopyable()}};
+
+void test_expressions(bool b) {
+ auto lambda = [a = make()] {};
+
+ take({});
+ take(Noncopyable());
+ take(Noncopyable{});
+ take(make());
+
+ Noncopyable &&dc1 = dynamic_cast<Noncopyable&&>(Noncopyable());
+ Noncopyable &&dc2 = dynamic_cast<Noncopyable&&>(nc1);
+ Noncopyable &&dc3 = dynamic_cast<Noncopyable&&>(Derived());
+
+ Noncopyable sc1 = static_cast<Noncopyable>(Noncopyable());
+ Noncopyable sc2 = static_cast<Noncopyable>(nc1); // expected-error {{deleted}}
+ Noncopyable sc3 = static_cast<Noncopyable&&>(Noncopyable()); // expected-error {{deleted}}
+ Noncopyable sc4 = static_cast<Noncopyable>(static_cast<Noncopyable&&>(Noncopyable())); // expected-error {{deleted}}
+
+ Noncopyable cc1 = (Noncopyable)Noncopyable();
+ Noncopyable cc2 = (Noncopyable)Derived(); // expected-error {{deleted}}
+
+ Noncopyable fc1 = Noncopyable(Noncopyable());
+ Noncopyable fc2 = Noncopyable(Derived()); // expected-error {{deleted}}
+
+ // We must check for a complete type for every materialized temporary. (Note
+ // that in the special case of the top level of a decltype, no temporary is
+ // materialized.)
+ make_incomplete(); // expected-error {{incomplete}}
+ make_incomplete().a; // expected-error {{incomplete}}
+ make_incomplete().*(int Incomplete::*)nullptr; // expected-error {{incomplete}}
+ dynamic_cast<Incomplete&&>(make_incomplete()); // expected-error {{incomplete}}
+ const_cast<Incomplete&&>(make_incomplete()); // expected-error {{incomplete}}
+
+ sizeof(Indestructible{}); // expected-error {{deleted}}
+ sizeof(make_indestructible()); // expected-error {{deleted}}
+ sizeof(make_incomplete()); // expected-error {{incomplete}}
+ typeid(Indestructible{}); // expected-error {{deleted}}
+ typeid(make_indestructible()); // expected-error {{deleted}}
+ typeid(make_incomplete()); // expected-error {{incomplete}}
+
+ // FIXME: The first two cases here are now also valid in C++17 onwards.
+ using I = decltype(Indestructible()); // expected-error {{deleted}}
+ using I = decltype(Indestructible{}); // expected-error {{deleted}}
+ using I = decltype(make_indestructible());
+ using J = decltype(make_incomplete());
+
+ Noncopyable cond1 = b ? Noncopyable() : make();
+ Noncopyable cond2 = b ? Noncopyable() : Derived(); // expected-error {{incompatible}}
+ Noncopyable cond3 = b ? Derived() : Noncopyable(); // expected-error {{incompatible}}
+ Noncopyable cond4 = b ? Noncopyable() : nc1; // expected-error {{deleted}}
+ Noncopyable cond5 = b ? nc1 : Noncopyable(); // expected-error {{deleted}}
+ // Could convert both to an xvalue of type Noncopyable here, but we're not
+ // permitted to consider that.
+ Noncopyable &&cond6 = b ? Noncopyable() : Derived(); // expected-error {{incompatible}}
+ Noncopyable &&cond7 = b ? Derived() : Noncopyable(); // expected-error {{incompatible}}
+ // Could convert both to a const lvalue of type Noncopyable here, but we're
+ // not permitted to consider that, either.
+ const Noncopyable cnc;
+ const Noncopyable &cond8 = b ? cnc : Derived(); // expected-error {{incompatible}}
+ const Noncopyable &cond9 = b ? Derived() : cnc; // expected-error {{incompatible}}
+
+ extern const volatile Noncopyable make_cv();
+ Noncopyable cv_difference1 = make_cv();
+ const volatile Noncopyable cv_difference2 = make();
+}
+
+template<typename T> struct ConversionFunction { operator T(); };
+Noncopyable cf1 = ConversionFunction<Noncopyable>();
+Noncopyable cf2 = ConversionFunction<Noncopyable&&>(); // expected-error {{deleted}}
+Noncopyable cf3 = ConversionFunction<const volatile Noncopyable>();
+const volatile Noncopyable cf4 = ConversionFunction<Noncopyable>();
+Noncopyable cf5 = ConversionFunction<Derived>(); // expected-error {{deleted}}
+
+struct AsMember {
+ Noncopyable member;
+ AsMember() : member(make()) {}
+};
+// FIXME: DR (no number yet): we still get a copy for base or delegating construction.
+struct AsBase : Noncopyable {
+ AsBase() : Noncopyable(make()) {} // expected-error {{deleted}}
+};
+struct AsDelegating final {
+ AsDelegating(const AsDelegating &) = delete; // expected-note {{deleted}}
+ static AsDelegating make(int);
+
+ // The base constructor version of this is problematic; the complete object
+ // version would be OK. Perhaps we could allow copy omission here for final
+ // classes?
+ AsDelegating(int n) : AsDelegating(make(n)) {} // expected-error {{deleted}}
+};
diff --git a/test/SemaCXX/cxx1z-decomposition.cpp b/test/SemaCXX/cxx1z-decomposition.cpp
new file mode 100644
index 000000000000..735a9e1dfee0
--- /dev/null
+++ b/test/SemaCXX/cxx1z-decomposition.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+void use_from_own_init() {
+ auto [a] = a; // expected-error {{binding 'a' cannot appear in the initializer of its own decomposition declaration}}
+}
+
+// As a Clang extension, _Complex can be decomposed.
+float decompose_complex(_Complex float cf) {
+ static _Complex float scf;
+ auto &[sre, sim] = scf;
+ // ok, this is references initialized by constant expressions all the way down
+ static_assert(&sre == &__real scf);
+ static_assert(&sim == &__imag scf);
+
+ auto [re, im] = cf;
+ return re*re + im*im;
+}
+
+// As a Clang extension, vector types can be decomposed.
+typedef float vf3 __attribute__((ext_vector_type(3)));
+float decompose_vector(vf3 v) {
+ auto [x, y, z] = v;
+ auto *p = &x; // expected-error {{address of vector element requested}}
+ return x + y + z;
+}
+
+struct S { int a, b; };
+constexpr int f(S s) {
+ auto &[a, b] = s;
+ return a * 10 + b;
+}
+static_assert(f({1, 2}) == 12);
+
+constexpr bool g(S &&s) {
+ auto &[a, b] = s;
+ return &a == &s.a && &b == &s.b && &a != &b;
+}
+static_assert(g({1, 2}));
+
+void enclosing() {
+ struct S { int a; };
+ auto [n] = S(); // expected-note 2{{'n' declared here}}
+
+ struct Q { int f() { return n; } }; // expected-error {{reference to local binding 'n' declared in enclosing function}}
+ // FIXME: This is probably supposed to be valid, but we do not have clear rules on how it's supposed to work.
+ (void) [&] { return n; }; // expected-error {{reference to local binding 'n' declared in enclosing function}}
+ (void) [n] {}; // expected-error {{'n' in capture list does not name a variable}}
+}
+
+void bitfield() {
+ struct { int a : 3, : 4, b : 5; } a;
+ auto &[x, y] = a;
+ auto &[p, q, r] = a; // expected-error {{decomposes into 2 elements, but 3 names were provided}}
+}
+
+void for_range() {
+ int x = 1;
+ for (auto[a, b] : x) { // expected-error {{invalid range expression of type 'int'; no viable 'begin' function available}}
+ a++;
+ }
+
+ int y[5];
+ for (auto[c] : y) { // expected-error {{cannot decompose non-class, non-array type 'int'}}
+ c++;
+ }
+}
+
+// FIXME: by-value array copies
diff --git a/test/SemaCXX/cxx1z-noexcept-function-type.cpp b/test/SemaCXX/cxx1z-noexcept-function-type.cpp
new file mode 100644
index 000000000000..a3f710970456
--- /dev/null
+++ b/test/SemaCXX/cxx1z-noexcept-function-type.cpp
@@ -0,0 +1,167 @@
+// RUN: %clang_cc1 -std=c++14 -verify -fexceptions -fcxx-exceptions %s
+// RUN: %clang_cc1 -std=c++1z -verify -fexceptions -fcxx-exceptions %s -Wno-dynamic-exception-spec
+
+#if __cplusplus > 201402L
+
+template<typename T> void redecl1() noexcept(noexcept(T())) {} // expected-note {{previous}}
+template<typename T> void redecl1() noexcept(noexcept(T())); // ok, same type
+template<typename T> void redecl1() noexcept(noexcept(T())) {} // expected-error {{redefinition}}
+
+template<bool A, bool B> void redecl2() noexcept(A); // expected-note {{previous}}
+template<bool A, bool B> void redecl2() noexcept(B); // expected-error {{conflicting types}}
+
+// These have the same canonical type, but are still different.
+template<typename A, typename B> void redecl3() throw(A); // expected-note {{previous}}
+template<typename A, typename B> void redecl3() throw(B); // expected-error {{does not match previous}}
+
+typedef int I;
+template<bool B> void redecl4(I) noexcept(B);
+template<bool B> void redecl4(I) noexcept(B); // expected-note {{failed template argument deduction}}
+
+void (*init_with_exact_type_a)(int) noexcept = redecl4<true>;
+void (*init_with_mismatched_type_a)(int) = redecl4<true>;
+auto deduce_auto_from_noexcept_function_ptr_a = redecl4<true>;
+using DeducedType_a = decltype(deduce_auto_from_noexcept_function_ptr_a);
+using DeducedType_a = void (*)(int) noexcept;
+
+void (*init_with_exact_type_b)(int) = redecl4<false>;
+void (*init_with_mismatched_type_b)(int) noexcept = redecl4<false>; // expected-error {{does not match required type}}
+auto deduce_auto_from_noexcept_function_ptr_b = redecl4<false>;
+using DeducedType_b = decltype(deduce_auto_from_noexcept_function_ptr_b);
+using DeducedType_b = void (*)(int);
+
+static_assert(noexcept(init_with_exact_type_a(0)));
+static_assert(noexcept((+init_with_exact_type_a)(0)));
+static_assert(!noexcept(init_with_exact_type_b(0)));
+static_assert(!noexcept((+init_with_exact_type_b)(0)));
+
+// Don't look through casts, use the direct type of the expression.
+// FIXME: static_cast here would be reasonable, but is not currently permitted.
+static_assert(noexcept(static_cast<decltype(init_with_exact_type_a)>(init_with_exact_type_b)(0))); // expected-error {{is not allowed}}
+static_assert(noexcept(reinterpret_cast<decltype(init_with_exact_type_a)>(init_with_exact_type_b)(0)));
+static_assert(!noexcept(static_cast<decltype(init_with_exact_type_b)>(init_with_exact_type_a)(0)));
+
+template<bool B> auto get_fn() noexcept -> void (*)() noexcept(B) {}
+static_assert(noexcept(get_fn<true>()()));
+static_assert(!noexcept(get_fn<false>()()));
+
+namespace DependentDefaultCtorExceptionSpec {
+ template<typename> struct T { static const bool value = true; };
+
+ template<class A> struct map {
+ typedef A a;
+ map() noexcept(T<a>::value) {}
+ };
+
+ template<class B> struct multimap {
+ typedef B b;
+ multimap() noexcept(T<b>::value) {}
+ };
+
+ // Don't crash here.
+ struct A { multimap<int> Map; } a;
+
+ static_assert(noexcept(A()));
+}
+
+#endif
+
+namespace CompatWarning {
+ struct X;
+
+ // These cases don't change.
+ void f0(void p() throw(int));
+ auto f0() -> void (*)() noexcept(false);
+
+ // These cases take an ABI break in C++17 because their parameter / return types change.
+ void f1(void p() noexcept);
+ void f2(void (*p)() noexcept(true));
+ void f3(void (&p)() throw());
+ void f4(void (X::*p)() throw());
+ auto f5() -> void (*)() throw();
+ auto f6() -> void (&)() throw();
+ auto f7() -> void (X::*)() throw();
+#if __cplusplus <= 201402L
+ // expected-warning@-8 {{mangled name of 'f1' will change in C++17 due to non-throwing exception specification in function signature}}
+ // expected-warning@-8 {{mangled name of 'f2' will change in C++17 due to non-throwing exception specification in function signature}}
+ // expected-warning@-8 {{mangled name of 'f3' will change in C++17 due to non-throwing exception specification in function signature}}
+ // expected-warning@-8 {{mangled name of 'f4' will change in C++17 due to non-throwing exception specification in function signature}}
+ // expected-warning@-8 {{mangled name of 'f5' will change in C++17 due to non-throwing exception specification in function signature}}
+ // expected-warning@-8 {{mangled name of 'f6' will change in C++17 due to non-throwing exception specification in function signature}}
+ // expected-warning@-8 {{mangled name of 'f7' will change in C++17 due to non-throwing exception specification in function signature}}
+#endif
+
+ // An instantiation-dependent exception specification needs to be mangled in
+ // all language modes, since it participates in SFINAE.
+ template<typename T> void g(void() throw(T)); // expected-note {{substitution failure}}
+ template<typename T> void g(...) = delete; // expected-note {{deleted}}
+ void test_g() { g<void>(nullptr); } // expected-error {{deleted}}
+
+ // An instantiation-dependent exception specification needs to be mangled in
+ // all language modes, since it participates in SFINAE.
+ template<typename T> void h(void() noexcept(T())); // expected-note {{substitution failure}}
+ template<typename T> void h(...) = delete; // expected-note {{deleted}}
+ void test_h() { h<void>(nullptr); } // expected-error {{deleted}}
+}
+
+namespace ImplicitExceptionSpec {
+ struct S {
+ ~S();
+ void f(const S &s = S());
+ };
+ S::~S() {}
+}
+
+namespace Builtins {
+ // Pick two functions that ought to have the same noexceptness.
+ extern "C" int strcmp(const char *, const char *);
+ extern "C" int strncmp(const char *, const char *, decltype(sizeof(0))) noexcept;
+
+ // Check we recognized both as builtins.
+ typedef int arr[strcmp("bar", "foo") + 4 * strncmp("foo", "bar", 4)];
+ typedef int arr[3];
+}
+
+namespace ExplicitInstantiation {
+ template<typename T> void f() noexcept {}
+ template<typename T> struct X { void f() noexcept {} };
+ template void f<int>();
+ template void X<int>::f();
+}
+
+namespace ConversionFunction {
+ struct A { template<typename T> operator T() noexcept; };
+ int a = A().operator int();
+}
+
+using size_t = decltype(sizeof(0));
+
+namespace OperatorDelete {
+ struct W {};
+ struct X {};
+ struct Y {};
+ struct Z {};
+ template<bool N, bool D> struct T {};
+}
+void *operator new(size_t, OperatorDelete::W) noexcept(false);
+void operator delete(void*, OperatorDelete::W) noexcept(false) = delete; // expected-note {{here}}
+void *operator new(size_t, OperatorDelete::X) noexcept(false);
+void operator delete(void*, OperatorDelete::X) noexcept(true) = delete; // expected-note {{here}}
+void *operator new(size_t, OperatorDelete::Y) noexcept(true);
+void operator delete(void*, OperatorDelete::Y) noexcept(false) = delete; // expected-note {{here}}
+void *operator new(size_t, OperatorDelete::Z) noexcept(true);
+void operator delete(void*, OperatorDelete::Z) noexcept(true) = delete; // expected-note {{here}}
+template<bool N, bool D> void *operator new(size_t, OperatorDelete::T<N, D>) noexcept(N);
+template<bool N, bool D> void operator delete(void*, OperatorDelete::T<N, D>) noexcept(D) = delete; // expected-note 4{{here}}
+namespace OperatorDelete {
+ struct A { A(); };
+ A *w = new (W{}) A; // expected-error {{deleted function}}
+ A *x = new (X{}) A; // expected-error {{deleted function}}
+ A *y = new (Y{}) A; // expected-error {{deleted function}}
+ A *z = new (Z{}) A; // expected-error {{deleted function}}
+
+ A *t00 = new (T<false, false>{}) A; // expected-error {{deleted function}}
+ A *t01 = new (T<false, true>{}) A; // expected-error {{deleted function}}
+ A *t10 = new (T<true, false>{}) A; // expected-error {{deleted function}}
+ A *t11 = new (T<true, true>{}) A; // expected-error {{deleted function}}
+}
diff --git a/test/SemaCXX/cxx1z-user-defined-literals.cpp b/test/SemaCXX/cxx1z-user-defined-literals.cpp
new file mode 100644
index 000000000000..978fd2fbc4b2
--- /dev/null
+++ b/test/SemaCXX/cxx1z-user-defined-literals.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=c++1z %s -include %s -verify
+
+#ifndef INCLUDED
+#define INCLUDED
+
+#pragma clang system_header
+namespace std {
+ using size_t = decltype(sizeof(0));
+
+ struct string_view {};
+ string_view operator""sv(const char*, size_t);
+}
+
+#else
+
+using namespace std;
+string_view s = "foo"sv;
+const char* p = "bar"sv; // expected-error {{no viable conversion}}
+char error = 'x'sv; // expected-error {{invalid suffix}} expected-error {{expected ';'}}
+
+#endif
diff --git a/test/SemaCXX/cxx98-compat-flags.cpp b/test/SemaCXX/cxx98-compat-flags.cpp
index f90ad345e975..62d687c49cf7 100644
--- a/test/SemaCXX/cxx98-compat-flags.cpp
+++ b/test/SemaCXX/cxx98-compat-flags.cpp
@@ -16,7 +16,7 @@ namespace CopyCtorIssues {
Private(const Private&); // expected-note {{declared private here}}
};
struct NoViable {
- NoViable();
+ NoViable(); // expected-note {{not viable}}
NoViable(NoViable&); // expected-note {{not viable}}
};
struct Ambiguous {
diff --git a/test/SemaCXX/cxx98-compat-pedantic.cpp b/test/SemaCXX/cxx98-compat-pedantic.cpp
index 38bc341e83ce..c72c44ad5feb 100644
--- a/test/SemaCXX/cxx98-compat-pedantic.cpp
+++ b/test/SemaCXX/cxx98-compat-pedantic.cpp
@@ -21,10 +21,6 @@ enum Enum {
Enum_value, // expected-warning {{commas at the end of enumerator lists are incompatible with C++98}}
};
-template<typename T> struct InstantiationAfterSpecialization {};
-template<> struct InstantiationAfterSpecialization<int> {}; // expected-note {{here}}
-template struct InstantiationAfterSpecialization<int>; // expected-warning {{explicit instantiation of 'InstantiationAfterSpecialization<int>' that occurs after an explicit specialization is incompatible with C++98}}
-
void *dlsym();
void (*FnPtr)() = (void(*)())dlsym(); // expected-warning {{cast between pointer-to-function and pointer-to-object is incompatible with C++98}}
void *FnVoidPtr = (void*)&dlsym; // expected-warning {{cast between pointer-to-function and pointer-to-object is incompatible with C++98}}
@@ -59,7 +55,7 @@ namespace CopyCtorIssues {
Private(const Private&); // expected-note {{declared private here}}
};
struct NoViable {
- NoViable();
+ NoViable(); // expected-note {{not viable}}
NoViable(NoViable&); // expected-note {{not viable}}
};
struct Ambiguous {
diff --git a/test/SemaCXX/cxx98-compat.cpp b/test/SemaCXX/cxx98-compat.cpp
index 25a086d9bcd3..4a9baf5100d6 100644
--- a/test/SemaCXX/cxx98-compat.cpp
+++ b/test/SemaCXX/cxx98-compat.cpp
@@ -361,7 +361,7 @@ template<typename T> T var = T(10);
// diagnosed the primary template.
template<typename T> T* var<T*> = new T();
template<> int var<int> = 10;
-template int var<int>;
+template char var<char>;
float fvar = var<float>;
class A {
@@ -391,7 +391,7 @@ template<typename T> T B::v = T();
template<typename T> T* B::v<T*> = new T();
template<> int B::v<int> = 10;
-template int B::v<int>;
+template char B::v<char>;
float fsvar = B::v<float>;
#ifdef CXX14COMPAT
diff --git a/test/SemaCXX/default-arg-closures.cpp b/test/SemaCXX/default-arg-closures.cpp
new file mode 100644
index 000000000000..e076cc05cd20
--- /dev/null
+++ b/test/SemaCXX/default-arg-closures.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fexceptions -fcxx-exceptions -fms-extensions -verify %s -std=c++11
+
+// The MS ABI has a few ways to generate constructor closures, which require
+// instantiating and checking the semantics of default arguments. Make sure we
+// do that right.
+
+// FIXME: Don't diagnose this issue twice.
+template <typename T>
+struct DependentDefaultCtorArg { // expected-note {{in instantiation of default function argument}}
+ // expected-error@+1 2 {{type 'int' cannot be used prior to '::' because it has no members}}
+ DependentDefaultCtorArg(int n = T::error);
+};
+struct
+__declspec(dllexport) // expected-note {{due to 'ExportDefaultCtorClosure' being dllexported}}
+ExportDefaultCtorClosure // expected-note {{implicit default constructor for 'ExportDefaultCtorClosure' first required here}}
+: DependentDefaultCtorArg<int> // expected-note {{in instantiation of template class}}
+{};
+
+template <typename T>
+struct DependentDefaultCopyArg {
+ DependentDefaultCopyArg() {}
+ // expected-error@+1 {{type 'int' cannot be used prior to '::' because it has no members}}
+ DependentDefaultCopyArg(const DependentDefaultCopyArg &o, int n = T::member) {}
+};
+
+struct HasMember {
+ enum { member = 0 };
+};
+void UseDependentArg() { throw DependentDefaultCopyArg<HasMember>(); }
+
+void ErrorInDependentArg() {
+ throw DependentDefaultCopyArg<int>(); // expected-note {{required here}}
+}
+
+struct HasCleanup {
+ ~HasCleanup();
+};
+
+struct Default {
+ Default(const Default &o, int d = (HasCleanup(), 42));
+};
+
+void f(const Default &d) {
+ throw d;
+}
diff --git a/test/SemaCXX/deprecated.cpp b/test/SemaCXX/deprecated.cpp
index 4ce058968742..0fd275e2cec6 100644
--- a/test/SemaCXX/deprecated.cpp
+++ b/test/SemaCXX/deprecated.cpp
@@ -7,13 +7,17 @@
#include "Inputs/register.h"
-void f() throw();
-void g() throw(int);
-void h() throw(...);
-#if __cplusplus >= 201103L
+void g() throw();
+void h() throw(int);
+void i() throw(...);
+#if __cplusplus > 201402L
// expected-warning@-4 {{dynamic exception specifications are deprecated}} expected-note@-4 {{use 'noexcept' instead}}
-// expected-warning@-4 {{dynamic exception specifications are deprecated}} expected-note@-4 {{use 'noexcept(false)' instead}}
-// expected-warning@-4 {{dynamic exception specifications are deprecated}} expected-note@-4 {{use 'noexcept(false)' instead}}
+// expected-error@-4 {{ISO C++1z does not allow dynamic exception specifications}} expected-note@-4 {{use 'noexcept(false)' instead}}
+// expected-error@-4 {{ISO C++1z does not allow dynamic exception specifications}} expected-note@-4 {{use 'noexcept(false)' instead}}
+#elif __cplusplus >= 201103L
+// expected-warning@-8 {{dynamic exception specifications are deprecated}} expected-note@-8 {{use 'noexcept' instead}}
+// expected-warning@-8 {{dynamic exception specifications are deprecated}} expected-note@-8 {{use 'noexcept(false)' instead}}
+// expected-warning@-8 {{dynamic exception specifications are deprecated}} expected-note@-8 {{use 'noexcept(false)' instead}}
#endif
void stuff() {
diff --git a/test/SemaCXX/derived-to-base-ambig.cpp b/test/SemaCXX/derived-to-base-ambig.cpp
index 93bd3619ccdf..5d1d56b76614 100644
--- a/test/SemaCXX/derived-to-base-ambig.cpp
+++ b/test/SemaCXX/derived-to-base-ambig.cpp
@@ -6,7 +6,7 @@ class D : public B, public C { };
void f(D* d) {
A* a;
- a = d; // expected-error{{ambiguous conversion from derived class 'D' to base class 'A':}} expected-error{{assigning to 'A *' from incompatible type 'D *'}}
+ a = d; // expected-error{{ambiguous conversion from derived class 'D' to base class 'A':}}
}
class Object2 { };
@@ -20,7 +20,7 @@ class F2 : public E2, public A2 { }; // expected-warning{{direct base 'A2' is in
void g(E2* e2, F2* f2) {
Object2* o2;
o2 = e2;
- o2 = f2; // expected-error{{ambiguous conversion from derived class 'F2' to base class 'Object2':}} expected-error{{assigning to 'Object2 *' from incompatible type 'F2 *'}}
+ o2 = f2; // expected-error{{ambiguous conversion from derived class 'F2' to base class 'Object2':}}
}
// Test that ambiguous/inaccessibility checking does not trigger too
diff --git a/test/SemaCXX/designated-initializers.cpp b/test/SemaCXX/designated-initializers.cpp
new file mode 100644
index 000000000000..e5b5f3c9cce2
--- /dev/null
+++ b/test/SemaCXX/designated-initializers.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Winitializer-overrides %s
+
+template <typename T> struct Foo {
+ struct SubFoo {
+ int bar1;
+ int bar2;
+ };
+
+ static void Test() { SubFoo sf = {.bar1 = 10, .bar2 = 20}; } // Expected no warning
+};
+
+void foo() {
+ Foo<int>::Test();
+ Foo<bool>::Test();
+ Foo<float>::Test();
+}
+
+template <typename T> struct Bar {
+ struct SubFoo {
+ int bar1;
+ int bar2;
+ };
+
+ static void Test() { SubFoo sf = {.bar1 = 10, // expected-note 2 {{previous initialization is here}}
+ .bar1 = 20}; } // expected-warning 2 {{initializer overrides prior initialization of this subobject}}
+};
+
+void bar() {
+ Bar<int>::Test(); // expected-note {{in instantiation of member function 'Bar<int>::Test' requested here}}
+ Bar<bool>::Test(); // expected-note {{in instantiation of member function 'Bar<bool>::Test' requested here}}
+}
diff --git a/test/SemaCXX/elaborated-type-specifier.cpp b/test/SemaCXX/elaborated-type-specifier.cpp
index 81c5cb4eac59..3701dd7ba630 100644
--- a/test/SemaCXX/elaborated-type-specifier.cpp
+++ b/test/SemaCXX/elaborated-type-specifier.cpp
@@ -52,3 +52,12 @@ namespace test5 {
}
};
}
+
+namespace test6 {
+struct C {
+ template <typename> friend struct A; // expected-note {{'A' declared here}}
+};
+struct B {
+ struct A *p; // expected-error {{implicit declaration introduced by elaborated type conflicts with a template of the same name}}
+};
+}
diff --git a/test/SemaCXX/enable_if.cpp b/test/SemaCXX/enable_if.cpp
index 81308136c480..0f8fc9b2652a 100644
--- a/test/SemaCXX/enable_if.cpp
+++ b/test/SemaCXX/enable_if.cpp
@@ -440,3 +440,27 @@ void testFoo() {
foo(1, 0, m, 3); // expected-error{{no matching}}
}
}
+
+// Tests that we emit errors at the point of the method call, rather than the
+// beginning of the expression that happens to be a member call.
+namespace member_loc {
+ struct Foo { void bar() __attribute__((enable_if(0, ""))); }; // expected-note{{disabled}}
+ void testFoo() {
+ Foo()
+ .bar(); // expected-error{{no matching member function}}
+ }
+}
+
+// Prior bug: we wouldn't properly convert conditions to bools when
+// instantiating templates in some cases.
+namespace template_instantiation {
+template <typename T>
+struct Foo {
+ void bar(int a) __attribute__((enable_if(a, ""))); // expected-note{{disabled}}
+};
+
+void runFoo() {
+ Foo<double>().bar(0); // expected-error{{no matching}}
+ Foo<double>().bar(1);
+}
+}
diff --git a/test/SemaCXX/expression-traits.cpp b/test/SemaCXX/expression-traits.cpp
index 51bb90e8bbf9..d965d14747ae 100644
--- a/test/SemaCXX/expression-traits.cpp
+++ b/test/SemaCXX/expression-traits.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -fcxx-exceptions %s
+// RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify -fcxx-exceptions %s
//
// Tests for "expression traits" intrinsics such as __is_lvalue_expr.
diff --git a/test/SemaCXX/friend.cpp b/test/SemaCXX/friend.cpp
index 4f27f4df6c90..1f64ba609b16 100644
--- a/test/SemaCXX/friend.cpp
+++ b/test/SemaCXX/friend.cpp
@@ -379,3 +379,12 @@ namespace tag_redecl {
X *q = p;
}
}
+
+namespace default_arg {
+ void f();
+ void f(void*); // expected-note {{previous}}
+ struct X {
+ friend void f(int a, int b = 0) {}
+ friend void f(void *p = 0) {} // expected-error {{must be the only}}
+ };
+}
diff --git a/test/SemaCXX/friend2.cpp b/test/SemaCXX/friend2.cpp
new file mode 100644
index 000000000000..347af0d61b1b
--- /dev/null
+++ b/test/SemaCXX/friend2.cpp
@@ -0,0 +1,172 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+
+// If a friend function is defined in several non-template classes,
+// it is an error.
+
+void func1(int);
+struct C1a {
+ friend void func1(int) {} // expected-note{{previous definition is here}}
+};
+struct C1b {
+ friend void func1(int) {} // expected-error{{redefinition of 'func1'}}
+};
+
+
+// If a friend function is defined in both non-template and template
+// classes it is an error only if the template is instantiated.
+
+void func2(int);
+struct C2a {
+ friend void func2(int) {}
+};
+template<typename T> struct C2b {
+ friend void func2(int) {}
+};
+
+void func3(int);
+struct C3a {
+ friend void func3(int) {} // expected-note{{previous definition is here}}
+};
+template<typename T> struct C3b {
+ friend void func3(int) {} // expected-error{{redefinition of 'func3'}}
+};
+C3b<long> c3; // expected-note{{in instantiation of template class 'C3b<long>' requested here}}
+
+
+// If a friend function is defined in several template classes it is an error
+// only if several templates are instantiated.
+
+void func4(int);
+template<typename T> struct C4a {
+ friend void func4(int) {}
+};
+template<typename T> struct C4b {
+ friend void func4(int) {}
+};
+
+
+void func5(int);
+template<typename T> struct C5a {
+ friend void func5(int) {}
+};
+template<typename T> struct C5b {
+ friend void func5(int) {}
+};
+C5a<long> c5a;
+
+void func6(int);
+template<typename T> struct C6a {
+ friend void func6(int) {} // expected-note{{previous definition is here}}
+};
+template<typename T> struct C6b {
+ friend void func6(int) {} // expected-error{{redefinition of 'func6'}}
+};
+C6a<long> c6a;
+C6b<int*> c6b; // expected-note{{in instantiation of template class 'C6b<int *>' requested here}}
+
+void func7(int);
+template<typename T> struct C7 {
+ friend void func7(int) {} // expected-error{{redefinition of 'func7'}}
+ // expected-note@-1{{previous definition is here}}
+};
+C7<long> c7a;
+C7<int*> c7b; // expected-note{{in instantiation of template class 'C7<int *>' requested here}}
+
+
+// Even if clases are not instantiated and hence friend functions defined in them are not
+// available, their declarations can be checked.
+
+void func8(int); // expected-note{{previous declaration is here}}
+template<typename T> struct C8a {
+ friend long func8(int); // expected-error{{functions that differ only in their return type cannot be overloaded}}
+};
+
+void func9(int); // expected-note{{previous declaration is here}}
+template<typename T> struct C9a {
+ friend int func9(int); // expected-error{{functions that differ only in their return type cannot be overloaded}}
+};
+
+void func10(int); // expected-note{{previous declaration is here}}
+template<typename T> struct C10a {
+ friend int func10(int); // expected-error{{functions that differ only in their return type cannot be overloaded}}
+};
+
+void func_11(); // expected-note{{previous declaration is here}}
+template<typename T> class C11 {
+ friend int func_11(); // expected-error{{functions that differ only in their return type cannot be overloaded}}
+};
+
+void func_12(int x); // expected-note{{previous declaration is here}}
+template<typename T> class C12 {
+ friend void func_12(int x = 0); // expected-error{{friend declaration specifying a default argument must be the only declaration}}
+};
+
+
+namespace pr22307 {
+
+struct t {
+ friend int leak(t);
+};
+
+template<typename v>
+struct m {
+ friend int leak(t) { return sizeof(v); } // expected-error{{redefinition of 'leak'}} expected-note{{previous definition is here}}
+};
+
+template struct m<char>;
+template struct m<short>; // expected-note{{in instantiation of template class 'pr22307::m<short>' requested here}}
+
+int main() {
+ leak(t());
+}
+
+}
+
+namespace pr17923 {
+
+void f(unsigned long long);
+
+template<typename T> struct X {
+ friend void f(unsigned long long) {
+ T t;
+ }
+};
+
+int main() { f(1234); }
+
+}
+
+namespace pr17923a {
+
+int get();
+
+template< int value >
+class set {
+ friend int get()
+ { return value; } // return 0; is OK
+};
+
+template class set< 5 >;
+
+int main() {
+ get();
+}
+
+}
+
+namespace pr8035 {
+
+void Function();
+
+int main(int argc, char* argv[]) {
+ Function();
+}
+
+template <typename T>
+struct Test {
+ friend void Function() { }
+};
+
+template class Test<int>;
+
+}
diff --git a/test/SemaCXX/function-redecl-2.cpp b/test/SemaCXX/function-redecl-2.cpp
new file mode 100644
index 000000000000..9ceeb205be88
--- /dev/null
+++ b/test/SemaCXX/function-redecl-2.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+namespace redecl_in_templ {
+template<typename T> void redecl_in_templ() {
+ extern void func_1(); // expected-note {{previous declaration is here}}
+ extern int func_1(); // expected-error {{functions that differ only in their return type cannot be overloaded}}
+}
+
+void g();
+constexpr void (*p)() = g;
+
+template<bool> struct X {};
+template<> struct X<true> { typedef int type; };
+
+template<typename T> void f() {
+ extern void g();
+ X<&g == p>::type n;
+}
+}
diff --git a/test/SemaCXX/implicit-exception-spec.cpp b/test/SemaCXX/implicit-exception-spec.cpp
index ff3d685d912e..12871b8ce707 100644
--- a/test/SemaCXX/implicit-exception-spec.cpp
+++ b/test/SemaCXX/implicit-exception-spec.cpp
@@ -16,31 +16,31 @@ namespace InClassInitializers {
// Noexcept::Noexcept is not declared constexpr, therefore noexcept(Noexcept())
// is false.
bool ThrowSomething() noexcept(false);
- struct ConstExpr {
- bool b = noexcept(ConstExpr()) && ThrowSomething(); // expected-error {{cannot use defaulted default constructor of 'ConstExpr' within the class outside of member functions}}
+ struct ConstExpr { // expected-error {{default member initializer for 'b' needed}}
+ bool b = noexcept(ConstExpr()) && ThrowSomething(); // expected-note {{declared here}}
// expected-note@-1 {{implicit default constructor for 'InClassInitializers::ConstExpr' first required here}}
};
// Much more obviously broken: we can't parse the initializer without already
// knowing whether it produces a noexcept expression.
- struct TemplateArg {
- int n = ExceptionIf<noexcept(TemplateArg())>::f(); // expected-error {{cannot use defaulted default constructor of 'TemplateArg' within the class outside of member functions}}
+ struct TemplateArg { // expected-error {{default member initializer for 'n' needed}}
+ int n = ExceptionIf<noexcept(TemplateArg())>::f(); // expected-note {{declared here}}
// expected-note@-1 {{implicit default constructor for 'InClassInitializers::TemplateArg' first required here}}
};
// And within a nested class.
struct Nested { // expected-note {{implicit default constructor for 'InClassInitializers::Nested::Inner' first required here}}
- struct Inner {
- // expected-error@+1 {{cannot use defaulted default constructor of 'Inner' within 'Nested' outside of member functions}}
- int n = ExceptionIf<noexcept(Nested())>::f(); // expected-note {{implicit default constructor for 'InClassInitializers::Nested' first required here}}
+ struct Inner { // expected-error {{default member initializer for 'n' needed}}
+ int n = // expected-note {{declared here}}
+ ExceptionIf<noexcept(Nested())>::f(); // expected-note {{implicit default constructor for 'InClassInitializers::Nested' first required here}}
} inner;
};
struct Nested2 { // expected-error {{implicit default constructor for 'InClassInitializers::Nested2' must explicitly initialize the member 'inner' which does not have a default constructor}}
struct Inner;
int n = Inner().n; // expected-note {{implicit default constructor for 'InClassInitializers::Nested2::Inner' first required here}}
- struct Inner { // expected-note {{declared here}}
- // expected-error@+1 {{cannot use defaulted default constructor of 'Inner' within 'Nested2' outside of member functions}}
+ struct Inner { // expected-error {{initializer for 'n' needed}} expected-note {{declared here}}
+ // expected-note@+1 {{declared here}}
int n = ExceptionIf<noexcept(Nested2())>::f();
// expected-note@-1 {{implicit default constructor for 'InClassInitializers::Nested2' first required here}}
} inner; // expected-note {{member is declared here}}
diff --git a/test/SemaCXX/instantiate-template-fatal-error.cpp b/test/SemaCXX/instantiate-template-fatal-error.cpp
new file mode 100644
index 000000000000..9c8916e77bb0
--- /dev/null
+++ b/test/SemaCXX/instantiate-template-fatal-error.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s
+
+#pragma clang diagnostic fatal "-Wall"
+#pragma clang diagnostic fatal "-Wold-style-cast"
+
+template <class T> bool foo0(const long long *a, T* b) {
+ return a == (const long long*)b; // expected-error {{use of old-style cast}}
+}
+
+template<class T>
+struct S1 {
+};
+
+template<class T>
+struct S2 : S1<T> {
+ bool m1(const long long *a, T *b) const { return foo0(a, b); }
+};
+
+bool foo1(const long long *a, int *b) {
+ S2<int> s2;
+ return s2.m1(a, b);
+}
diff --git a/test/SemaCXX/lambda-expressions.cpp b/test/SemaCXX/lambda-expressions.cpp
index 5fffe4111783..e0ab15dc6327 100644
--- a/test/SemaCXX/lambda-expressions.cpp
+++ b/test/SemaCXX/lambda-expressions.cpp
@@ -95,6 +95,39 @@ namespace ImplicitCapture {
}
}
+namespace SpecialMembers {
+ void f() {
+ auto a = []{}; // expected-note 2{{here}} expected-note 2{{candidate}}
+ decltype(a) b; // expected-error {{no matching constructor}}
+ decltype(a) c = a;
+ decltype(a) d = static_cast<decltype(a)&&>(a);
+ a = a; // expected-error {{copy assignment operator is implicitly deleted}}
+ a = static_cast<decltype(a)&&>(a); // expected-error {{copy assignment operator is implicitly deleted}}
+ }
+ struct P {
+ P(const P&) = delete; // expected-note {{deleted here}}
+ };
+ struct Q {
+ ~Q() = delete; // expected-note {{deleted here}}
+ };
+ struct R {
+ R(const R&) = default;
+ R(R&&) = delete;
+ R &operator=(const R&) = delete;
+ R &operator=(R&&) = delete;
+ };
+ void g(P &p, Q &q, R &r) {
+ auto pp = [p]{}; // expected-error {{deleted constructor}}
+ auto qq = [q]{}; // expected-error {{deleted function}} expected-note {{because}}
+
+ auto a = [r]{}; // expected-note 2{{here}}
+ decltype(a) b = a;
+ decltype(a) c = static_cast<decltype(a)&&>(a); // ok, copies R
+ a = a; // expected-error {{copy assignment operator is implicitly deleted}}
+ a = static_cast<decltype(a)&&>(a); // expected-error {{copy assignment operator is implicitly deleted}}
+ }
+}
+
namespace PR12031 {
struct X {
template<typename T>
@@ -525,3 +558,18 @@ int func() {
decltype(a)::D b;
}
}
+
+namespace PR30566 {
+int name1; // expected-note {{'name1' declared here}}
+
+struct S1 {
+ template<class T>
+ S1(T t) { s = sizeof(t); }
+ int s;
+};
+
+void foo1() {
+ auto s0 = S1{[name=]() {}}; // expected-error 2 {{expected expression}}
+ auto s1 = S1{[name=name]() {}}; // expected-error {{use of undeclared identifier 'name'; did you mean 'name1'?}}
+}
+}
diff --git a/test/SemaCXX/libstdcxx_libcxx_less_hack.cpp b/test/SemaCXX/libstdcxx_libcxx_less_hack.cpp
new file mode 100644
index 000000000000..53b6a3b2c42d
--- /dev/null
+++ b/test/SemaCXX/libstdcxx_libcxx_less_hack.cpp
@@ -0,0 +1,67 @@
+// This is a test for a hack in Clang that works around a problem introduced by
+// DR583: it's no longer possible to compare a pointer against nullptr_t, but
+// we still want to permit those comparisons within less<> and friends.
+
+// RUN: %clang_cc1 -verify %s -std=c++14
+
+namespace std {
+ template<typename T = void> struct less {};
+ template<typename T = void> struct less_equal {};
+ template<typename T = void> struct greater {};
+ template<typename T = void> struct greater_equal {};
+
+ template<> struct less<> {
+ template <class T1, class T2>
+ auto operator()(T1 &&t, T2 &&u) const noexcept(noexcept(t < u))
+ -> decltype(t < u) {
+ return t < u;
+ }
+ };
+
+ template<> struct less_equal<> {
+ template <class T1, class T2>
+ auto operator()(T1 &&t, T2 &&u) const noexcept(noexcept(t <= u))
+ -> decltype(t <= u) {
+ return t <= u;
+ }
+ };
+
+ template<> struct greater<> {
+ template <class T1, class T2>
+ auto operator()(T1 &&t, T2 &&u) const noexcept(noexcept(t > u))
+ -> decltype(t > u) {
+ return t > u;
+ }
+ };
+
+ template<> struct greater_equal<> {
+ template <class T1, class T2>
+ auto operator()(T1 &&t, T2 &&u) const noexcept(noexcept(t >= u))
+ -> decltype(t >= u) {
+ return t >= u;
+ }
+ };
+
+ template<typename = void> struct unrelated;
+ template<> struct unrelated<> {
+ template <class T1, class T2>
+ auto operator()(T1 &&t, T2 &&u) const noexcept(noexcept(t < u)) // expected-note {{substitution failure}}
+ -> decltype(t < u) {
+ return t < u;
+ }
+ };
+};
+
+void test(int *p) {
+ using namespace std;
+ less<>()(p, nullptr);
+ less<>()(nullptr, p);
+ less_equal<>()(p, nullptr);
+ less_equal<>()(nullptr, p);
+ greater<>()(p, nullptr);
+ greater<>()(nullptr, p);
+ greater_equal<>()(p, nullptr);
+ greater_equal<>()(nullptr, p);
+
+ unrelated<>()(p, nullptr); // expected-error {{no matching function}}
+}
diff --git a/test/SemaCXX/libstdcxx_pair_swap_hack.cpp b/test/SemaCXX/libstdcxx_pair_swap_hack.cpp
index 02431e02e48d..9f9c71a50ce1 100644
--- a/test/SemaCXX/libstdcxx_pair_swap_hack.cpp
+++ b/test/SemaCXX/libstdcxx_pair_swap_hack.cpp
@@ -8,10 +8,14 @@
// affected are array, pair, priority_queue, stack, and queue.
// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array
+// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array -DPR28423
// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=pair
// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=priority_queue
// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=stack
// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=queue
+//
+// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array -DNAMESPACE=__debug
+// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array -DNAMESPACE=__profile
// MSVC's standard library uses a very similar pattern that relies on delayed
// parsing of exception specifications.
@@ -21,12 +25,23 @@
#ifdef BE_THE_HEADER
#pragma GCC system_header
+#ifdef PR28423
+using namespace std;
+#endif
+
namespace std {
template<typename T> void swap(T &, T &);
template<typename T> void do_swap(T &a, T &b) noexcept(noexcept(swap(a, b))) {
swap(a, b);
}
+#ifdef NAMESPACE
+ namespace NAMESPACE {
+#define STD_CLASS std::NAMESPACE::CLASS
+#else
+#define STD_CLASS std::CLASS
+#endif
+
template<typename A, typename B> struct CLASS {
#ifdef MSVC
void swap(CLASS &other) noexcept(noexcept(do_swap(member, other.member)));
@@ -42,6 +57,10 @@ namespace std {
// void swap(vector &other) noexcept(noexcept(do_swap(member, other.member)));
// A member;
// };
+
+#ifdef NAMESPACE
+ }
+#endif
}
#else
@@ -50,8 +69,8 @@ namespace std {
#include __FILE__
struct X {};
-using PX = std::CLASS<X, X>;
-using PI = std::CLASS<int, int>;
+using PX = STD_CLASS<X, X>;
+using PI = STD_CLASS<int, int>;
void swap(X &, X &) noexcept;
PX px;
PI pi;
@@ -64,6 +83,7 @@ namespace sad {
template<typename A, typename B> struct CLASS {
void swap(CLASS &other) noexcept(noexcept(swap(*this, other))); // expected-error {{too many arguments}} expected-note {{declared here}}
+ // expected-error@-1{{uses itself}} expected-note@-1{{in instantiation of}}
};
CLASS<int, int> pi;
diff --git a/test/SemaCXX/member-init.cpp b/test/SemaCXX/member-init.cpp
index 65c8873117ab..105c2e49822f 100644
--- a/test/SemaCXX/member-init.cpp
+++ b/test/SemaCXX/member-init.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -std=c++11 -Wall %s
struct Bitfield {
- int n : 3 = 7; // expected-error {{bitfield member cannot have an in-class initializer}}
+ int n : 3 = 7; // expected-error {{bit-field member cannot have an in-class initializer}}
};
int a;
@@ -13,8 +13,8 @@ public:
bool b();
int k;
-struct Recurse {
- int &n = // expected-error {{cannot use defaulted default constructor of 'Recurse' within the class outside of member functions because 'n' has an initializer}}
+struct Recurse { // expected-error {{initializer for 'n' needed}}
+ int &n = // expected-note {{declared here}}
b() ?
Recurse().n : // expected-note {{implicit default constructor for 'Recurse' first required here}}
k;
@@ -87,7 +87,7 @@ namespace PR14838 {
struct thing {};
struct another {
another() : r(thing()) {}
- // expected-error@-1 {{temporary of type 'const PR14838::function' has private destructor}}
+ // expected-error@-1 {{temporary of type 'PR14838::function' has private destructor}}
// expected-warning@-2 {{binding reference member 'r' to a temporary value}}
const function &r; // expected-note {{reference member declared here}}
} af;
@@ -128,8 +128,8 @@ A::A() {}
namespace template_default_ctor {
struct A {
template <typename T>
- struct B {
- int m1 = 0; // expected-error {{cannot use defaulted default constructor of 'B' within 'A' outside of member functions because 'm1' has an initializer}}
+ struct B { // expected-error {{initializer for 'm1' needed}}
+ int m1 = 0; // expected-note {{declared here}}
};
// expected-note@+1 {{implicit default constructor for 'template_default_ctor::A::B<int>' first required here}}
enum { NOE = noexcept(B<int>()) };
@@ -138,8 +138,8 @@ struct A {
namespace default_ctor {
struct A {
- struct B {
- int m1 = 0; // expected-error {{cannot use defaulted default constructor of 'B' within 'A' outside of member functions because 'm1' has an initializer}}
+ struct B { // expected-error {{initializer for 'm1' needed}}
+ int m1 = 0; // expected-note {{declared here}}
};
// expected-note@+1 {{implicit default constructor for 'default_ctor::A::B' first required here}}
enum { NOE = noexcept(B()) };
@@ -150,12 +150,12 @@ namespace member_template {
struct A {
template <typename T>
struct B {
- struct C {
- int m1 = 0; // expected-error {{cannot use defaulted default constructor of 'C' within 'A' outside of member functions because 'm1' has an initializer}}
+ struct C { // expected-error {{initializer for 'm1' needed}}
+ int m1 = 0; // expected-note {{declared here}}
};
template <typename U>
- struct D {
- int m1 = 0; // expected-error {{cannot use defaulted default constructor of 'D' within 'A' outside of member functions because 'm1' has an initializer}}
+ struct D { // expected-error {{initializer for 'm1' needed}}
+ int m1 = 0; // expected-note {{declared here}}
};
};
enum {
diff --git a/test/SemaCXX/member-pointer-ms.cpp b/test/SemaCXX/member-pointer-ms.cpp
index 83aeb019ca81..c8059acd6737 100644
--- a/test/SemaCXX/member-pointer-ms.cpp
+++ b/test/SemaCXX/member-pointer-ms.cpp
@@ -291,3 +291,11 @@ static_assert(sizeof(int SingleInheritanceAsVirtualBeforePragma::*) == 12, "");
#pragma pointers_to_members(single) // expected-error{{unexpected 'single'}}
#endif
+
+namespace merging {
+struct __single_inheritance S;
+struct __single_inheritance S;
+
+struct __single_inheritance M; // expected-note{{previous inheritance model specified here}}
+struct __multiple_inheritance M; // expected-error{{inheritance model does not match previous declaration}}
+}
diff --git a/test/SemaCXX/microsoft-new-delete.cpp b/test/SemaCXX/microsoft-new-delete.cpp
index b929e618a036..beba4d9dd8a4 100644
--- a/test/SemaCXX/microsoft-new-delete.cpp
+++ b/test/SemaCXX/microsoft-new-delete.cpp
@@ -16,7 +16,7 @@ void *operator new(size_t, const noncopyable&);
void *q = new (nc) int[4]; // expected-error {{calling a private constructor}}
struct bitfield { int n : 3; } bf; // expected-note {{here}}
-void *operator new[](size_t, int &);
+void *operator new[](size_t, int &); // expected-note {{passing argument to parameter here}}
void *operator new(size_t, const int &);
void *r = new (bf.n) int[4]; // expected-error {{non-const reference cannot bind to bit-field}}
diff --git a/test/SemaCXX/modules-ts.cppm b/test/SemaCXX/modules-ts.cppm
new file mode 100644
index 000000000000..71c09d3bfe6c
--- /dev/null
+++ b/test/SemaCXX/modules-ts.cppm
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.pcm -verify -DTEST=0
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.pcm -verify -Dmodule=int -DTEST=1
+// RUN: not %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -fmodule-file=%t.pcm -o %t.pcm -DTEST=2 2>&1 | FileCheck %s --check-prefix=CHECK-2
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -fmodule-file=%t.pcm -o %t.pcm -verify -Dfoo=bar -DTEST=3
+
+#if TEST == 0
+// expected-no-diagnostics
+#endif
+
+module foo;
+#if TEST == 1
+// expected-error@-2 {{expected module declaration at start of module interface}}
+#elif TEST == 2
+// CHECK-2: error: redefinition of module 'foo'
+#endif
+
+static int m; // ok, internal linkage, so no redefinition error
+int n;
+#if TEST == 3
+// expected-error@-2 {{redefinition of '}}
+// expected-note@-3 {{previous}}
+#endif
+
+#if TEST == 0
+export {
+ int a;
+ int b;
+ constexpr int *p = &n;
+}
+export int c;
+
+namespace N {
+ export void f() {}
+}
+
+export struct T {} t;
+#elif TEST == 3
+int use_a = a; // expected-error {{declaration of 'a' must be imported from module 'foo' before it is required}}
+// expected-note@-13 {{previous}}
+
+#undef foo
+import foo;
+
+export {} // expected-error {{export declaration cannot be empty}}
+export { ; }
+export { static_assert(true); }
+
+// FIXME: These diagnostics are not very good.
+export import foo; // expected-error {{expected unqualified-id}}
+export { import foo; } // expected-error {{expected unqualified-id}}
+
+int use_b = b;
+int use_n = n; // FIXME: this should not be visible, because it is not exported
+
+extern int n;
+static_assert(&n == p); // FIXME: these are not the same entity
+#endif
+
+
+#if TEST == 1
+struct S {
+ export int n; // expected-error {{expected member name or ';'}}
+ export static int n; // expected-error {{expected member name or ';'}}
+};
+#endif
+
+// FIXME: Exports of declarations without external linkage are disallowed.
+// Exports of declarations with non-external-linkage types are disallowed.
+
+// Cannot export within another export. This isn't precisely covered by the
+// language rules right now, but (per personal correspondence between zygoloid
+// and gdr) is the intent.
+#if TEST == 1
+export {
+ extern "C++" {
+ namespace NestedExport {
+ export { // expected-error {{appears within another export}}
+ int q;
+ }
+ }
+ }
+}
+#endif
diff --git a/test/SemaCXX/ms-uuid.cpp b/test/SemaCXX/ms-uuid.cpp
new file mode 100644
index 000000000000..461e3c12ff8a
--- /dev/null
+++ b/test/SemaCXX/ms-uuid.cpp
@@ -0,0 +1,95 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s
+
+typedef struct _GUID {
+ unsigned long Data1;
+ unsigned short Data2;
+ unsigned short Data3;
+ unsigned char Data4[8];
+} GUID;
+
+namespace {
+// cl.exe's behavior with merging uuid attributes is a bit erratic:
+// * In []-style attributes, a single [] list must not list a duplicate uuid
+// (even if it's the same uuid), and only a single declaration of a class
+// must have a uuid else the compiler errors out (even if two declarations of
+// a class have the same uuid).
+// * For __declspec(uuid(...)), it's ok if several declarations of a class have
+// an uuid, as long as it's the same uuid each time. If uuids on declarations
+// don't match, the compiler errors out.
+// * If there are several __declspec(uuid(...))s on one declaration, the
+// compiler only warns about this and uses the last uuid. It even warns if
+// the uuids are the same.
+
+// clang-cl implements the following simpler (but largely compatible) behavior
+// instead:
+// * [] and __declspec uuids have the same behavior.
+// * If there are several uuids on a a class (no matter if on the same decl or
+// on several decls), it is an error if they don't match.
+// * Having several uuids that match is ok.
+
+// Both cl and clang-cl accept this:
+class __declspec(uuid("000000A0-0000-0000-C000-000000000049")) C1;
+class __declspec(uuid("000000a0-0000-0000-c000-000000000049")) C1;
+class __declspec(uuid("{000000a0-0000-0000-C000-000000000049}")) C1;
+class __declspec(uuid("000000A0-0000-0000-C000-000000000049")) C1 {};
+
+// Both cl and clang-cl error out on this:
+// expected-note@+1 2{{previous uuid specified here}}
+class __declspec(uuid("000000A0-0000-0000-C000-000000000049")) C2;
+// expected-error@+1 {{uuid does not match previous declaration}}
+class __declspec(uuid("110000A0-0000-0000-C000-000000000049")) C2;
+// expected-error@+1 {{uuid does not match previous declaration}}
+class __declspec(uuid("220000A0-0000-0000-C000-000000000049")) C2 {};
+
+// expected-note@+1 {{previous uuid specified here}}
+class __declspec(uuid("000000A0-0000-0000-C000-000000000049")) C2_2;
+class C2_2;
+// expected-error@+1 {{uuid does not match previous declaration}}
+class __declspec(uuid("110000A0-0000-0000-C000-000000000049")) C2_2;
+
+// clang-cl accepts this, but cl errors out:
+[uuid("000000A0-0000-0000-C000-000000000049")] class C3;
+[uuid("000000A0-0000-0000-C000-000000000049")] class C3;
+[uuid("000000A0-0000-0000-C000-000000000049")] class C3 {};
+
+// Both cl and clang-cl error out on this (but for different reasons):
+// expected-note@+1 2{{previous uuid specified here}}
+[uuid("000000A0-0000-0000-C000-000000000049")] class C4;
+// expected-error@+1 {{uuid does not match previous declaration}}
+[uuid("110000A0-0000-0000-C000-000000000049")] class C4;
+// expected-error@+1 {{uuid does not match previous declaration}}
+[uuid("220000A0-0000-0000-C000-000000000049")] class C4 {};
+
+// Both cl and clang-cl error out on this:
+// expected-note@+1 {{previous uuid specified here}}
+class __declspec(uuid("000000A0-0000-0000-C000-000000000049"))
+// expected-error@+1 {{uuid does not match previous declaration}}
+ __declspec(uuid("110000A0-0000-0000-C000-000000000049")) C5;
+
+// expected-note@+1 {{previous uuid specified here}}
+[uuid("000000A0-0000-0000-C000-000000000049"),
+// expected-error@+1 {{uuid does not match previous declaration}}
+ uuid("110000A0-0000-0000-C000-000000000049")] class C6;
+
+// cl doesn't diagnose having one uuid each as []-style attributes and as
+// __declspec, even if the uuids differ. clang-cl errors if they differ.
+[uuid("000000A0-0000-0000-C000-000000000049")]
+class __declspec(uuid("000000A0-0000-0000-C000-000000000049")) C7;
+
+// expected-note@+1 {{previous uuid specified here}}
+[uuid("000000A0-0000-0000-C000-000000000049")]
+// expected-error@+1 {{uuid does not match previous declaration}}
+class __declspec(uuid("110000A0-0000-0000-C000-000000000049")) C8;
+
+
+// cl warns on this, but clang-cl is fine with it (which is consistent with
+// e.g. specifying __multiple_inheritance several times, which cl accepts
+// without warning too).
+class __declspec(uuid("000000A0-0000-0000-C000-000000000049"))
+ __declspec(uuid("000000A0-0000-0000-C000-000000000049")) C9;
+
+// cl errors out on this, but clang-cl is fine with it (to be consistent with
+// the previous case).
+[uuid("000000A0-0000-0000-C000-000000000049"),
+ uuid("000000A0-0000-0000-C000-000000000049")] class C10;
+}
diff --git a/test/SemaCXX/new-delete-cxx0x.cpp b/test/SemaCXX/new-delete-cxx0x.cpp
index 899cb4cda87a..c55152510e1b 100644
--- a/test/SemaCXX/new-delete-cxx0x.cpp
+++ b/test/SemaCXX/new-delete-cxx0x.cpp
@@ -1,13 +1,19 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -triple=i686-pc-linux-gnu
void ugly_news(int *ip) {
- // These are ill-formed according to one reading of C++98, and at the least
- // have undefined behavior.
- // FIXME: They're ill-formed in C++11.
- (void)new int[-1]; // expected-warning {{array size is negative}}
- (void)new int[2000000000]; // expected-warning {{array is too large}}
+ (void)new int[-1]; // expected-error {{array size is negative}}
+ (void)new int[2000000000]; // expected-error {{array is too large}}
}
+void pr22845a() {
+ constexpr int i = -1;
+ int *p = new int[i]; // expected-error {{array size is negative}}
+}
+
+void pr22845b() {
+ constexpr int i = 1;
+ int *p = new int[i]{1, 2}; // expected-error {{excess elements in array initializer}}
+}
struct S {
S(int);
@@ -15,13 +21,14 @@ struct S {
~S();
};
-struct T { // expected-note 2 {{not viable}}
- T(int); // expected-note {{not viable}}
+struct T { // expected-note 1+{{not viable}}
+ T(int); // expected-note 1+{{not viable}}
};
-void fn() {
+void fn(int n) {
(void) new int[2] {1, 2};
(void) new S[2] {1, 2};
+ (void) new S[3] {1, 2};
// C++11 [expr.new]p19:
// If the new-expression creates an object or an array of objects of class
// type, access and ambiguity control are done for the allocation function,
@@ -29,5 +36,28 @@ void fn() {
//
// Note that this happens even if the array bound is constant and the
// initializer initializes every array element.
- (void) new T[2] {1, 2}; // expected-error {{no matching constructor}} expected-note {{in implicit initialization of array element 2}}
+ //
+ // It's not clear that this is the intended interpretation, however -- we
+ // obviously don't want to check for a default constructor for 'new S(0)'.
+ // Instead, we only check for a default constructor in the case of an array
+ // new with a non-constant bound or insufficient initializers.
+ (void) new T[2] {1, 2}; // ok
+ (void) new T[3] {1, 2}; // expected-error {{no matching constructor}} expected-note {{in implicit initialization of array element 2}}
+ (void) new T[n] {1, 2}; // expected-error {{no matching constructor}} expected-note {{in implicit initialization of trailing array elements in runtime-sized array new}}
+}
+
+struct U {
+ T t; // expected-note 3{{in implicit initialization of field 't'}}
+ S s;
+};
+void g(int n) {
+ // Aggregate initialization, brace-elision, and array new combine to create
+ // this monstrosity.
+ (void) new U[2] {1, 2}; // expected-error {{no matching constructor}} expected-note {{in implicit initialization of array element 1}}
+ (void) new U[2] {1, 2, 3}; // ok
+ (void) new U[2] {1, 2, 3, 4}; // ok
+ (void) new U[2] {1, 2, 3, 4, 5}; // expected-error {{excess elements in array initializer}}
+
+ (void) new U[n] {1, 2}; // expected-error {{no matching constructor}} expected-note {{in implicit initialization of trailing array elements}}
+ (void) new U[n] {1, 2, 3}; // expected-error {{no matching constructor}} expected-note {{in implicit initialization of trailing array elements}}
}
diff --git a/test/SemaCXX/null_in_arithmetic_ops.cpp b/test/SemaCXX/null_in_arithmetic_ops.cpp
index 3b42ab44feb9..ee695ff24209 100644
--- a/test/SemaCXX/null_in_arithmetic_ops.cpp
+++ b/test/SemaCXX/null_in_arithmetic_ops.cpp
@@ -71,8 +71,8 @@ void f() {
b = a == NULL || a != NULL; // expected-warning 2{{comparison between NULL and non-pointer ('int' and NULL)}}
b = NULL == a || NULL != a; // expected-warning 2{{comparison between NULL and non-pointer (NULL and 'int')}}
- b = &a < NULL || NULL < &a || &a > NULL || NULL > &a;
- b = &a <= NULL || NULL <= &a || &a >= NULL || NULL >= &a;
+ b = &a < NULL || NULL < &a || &a > NULL || NULL > &a; // expected-error 4{{ordered comparison between pointer and zero}}
+ b = &a <= NULL || NULL <= &a || &a >= NULL || NULL >= &a; // expected-error 4{{ordered comparison between pointer and zero}}
b = &a == NULL || NULL == &a || &a != NULL || NULL != &a;
b = 0 == a;
diff --git a/test/SemaCXX/nullability.cpp b/test/SemaCXX/nullability.cpp
index c73c01a0a862..160741b1409c 100644
--- a/test/SemaCXX/nullability.cpp
+++ b/test/SemaCXX/nullability.cpp
@@ -97,3 +97,36 @@ void AssignAndInitNonNullFromFn() {
TakeNonnull(ReturnNullable()); //expected-warning{{implicit conversion from nullable pointer 'void * _Nullable' to non-nullable pointer type 'void * _Nonnull}}
}
+
+void ConditionalExpr(bool c) {
+ struct Base {};
+ struct Derived : Base {};
+
+ Base * _Nonnull p;
+ Base * _Nonnull nonnullB;
+ Base * _Nullable nullableB;
+ Derived * _Nonnull nonnullD;
+ Derived * _Nullable nullableD;
+
+ p = c ? nonnullB : nonnullD;
+ p = c ? nonnullB : nullableD; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}}
+ p = c ? nullableB : nonnullD; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}}
+ p = c ? nullableB : nullableD; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}}
+ p = c ? nonnullD : nonnullB;
+ p = c ? nonnullD : nullableB; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}}
+ p = c ? nullableD : nonnullB; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}}
+ p = c ? nullableD : nullableB; // expected-warning{{implicit conversion from nullable pointer 'Base * _Nullable' to non-nullable pointer type 'Base * _Nonnull}}
+}
+
+void arraysInLambdas() {
+ typedef int INTS[4];
+ auto simple = [](int [_Nonnull 2]) {};
+ simple(nullptr); // expected-warning {{null passed to a callee that requires a non-null argument}}
+ auto nested = [](void *_Nullable [_Nonnull 2]) {};
+ nested(nullptr); // expected-warning {{null passed to a callee that requires a non-null argument}}
+ auto nestedBad = [](int [2][_Nonnull 2]) {}; // expected-error {{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'int [2]'}}
+
+ auto withTypedef = [](INTS _Nonnull) {};
+ withTypedef(nullptr); // expected-warning {{null passed to a callee that requires a non-null argument}}
+ auto withTypedefBad = [](INTS _Nonnull[2]) {}; // expected-error {{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'INTS' (aka 'int [4]')}}
+}
diff --git a/test/SemaCXX/nullptr.cpp b/test/SemaCXX/nullptr.cpp
index 7d765b482c73..9a092910b6f9 100644
--- a/test/SemaCXX/nullptr.cpp
+++ b/test/SemaCXX/nullptr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 -ffreestanding -Wno-null-conversion %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 -ffreestanding -Wno-null-conversion -Wno-tautological-compare %s
#include <stdint.h>
typedef decltype(nullptr) nullptr_t;
@@ -32,17 +32,17 @@ nullptr_t f(nullptr_t null)
// Operators
(void)(null == nullptr);
- (void)(null <= nullptr);
+ (void)(null <= nullptr); // expected-error {{invalid operands to binary expression}}
(void)(null == 0);
(void)(null == (void*)0);
(void)((void*)0 == nullptr);
- (void)(null <= 0);
- (void)(null <= (void*)0);
- (void)((void*)0 <= nullptr);
+ (void)(null <= 0); // expected-error {{invalid operands to binary expression}}
+ (void)(null <= (void*)0); // expected-error {{invalid operands to binary expression}}
+ (void)((void*)0 <= nullptr); // expected-error {{invalid operands to binary expression}}
(void)(0 == nullptr);
(void)(nullptr == 0);
- (void)(nullptr <= 0);
- (void)(0 <= nullptr);
+ (void)(nullptr <= 0); // expected-error {{invalid operands to binary expression}}
+ (void)(0 <= nullptr); // expected-error {{invalid operands to binary expression}}
(void)(1 > nullptr); // expected-error {{invalid operands to binary expression}}
(void)(1 != nullptr); // expected-error {{invalid operands to binary expression}}
(void)(1 + nullptr); // expected-error {{invalid operands to binary expression}}
@@ -118,24 +118,24 @@ static_assert(__is_scalar(nullptr_t), "");
static_assert(__is_pod(nullptr_t), "");
static_assert(sizeof(nullptr_t) == sizeof(void*), "");
-static_assert(!(nullptr < nullptr), "");
-static_assert(!(nullptr > nullptr), "");
-static_assert( nullptr <= nullptr, "");
-static_assert( nullptr >= nullptr, "");
+static_assert(!(nullptr < nullptr), ""); // expected-error {{invalid operands to binary expression}}
+static_assert(!(nullptr > nullptr), ""); // expected-error {{invalid operands to binary expression}}
+static_assert( nullptr <= nullptr, ""); // expected-error {{invalid operands to binary expression}}
+static_assert( nullptr >= nullptr, ""); // expected-error {{invalid operands to binary expression}}
static_assert( nullptr == nullptr, "");
static_assert(!(nullptr != nullptr), "");
-static_assert(!(0 < nullptr), "");
-static_assert(!(0 > nullptr), "");
-static_assert( 0 <= nullptr, "");
-static_assert( 0 >= nullptr, "");
+static_assert(!(0 < nullptr), ""); // expected-error {{invalid operands to binary expression}}
+static_assert(!(0 > nullptr), ""); // expected-error {{invalid operands to binary expression}}
+static_assert( 0 <= nullptr, ""); // expected-error {{invalid operands to binary expression}}
+static_assert( 0 >= nullptr, ""); // expected-error {{invalid operands to binary expression}}
static_assert( 0 == nullptr, "");
static_assert(!(0 != nullptr), "");
-static_assert(!(nullptr < 0), "");
-static_assert(!(nullptr > 0), "");
-static_assert( nullptr <= 0, "");
-static_assert( nullptr >= 0, "");
+static_assert(!(nullptr < 0), ""); // expected-error {{invalid operands to binary expression}}
+static_assert(!(nullptr > 0), ""); // expected-error {{invalid operands to binary expression}}
+static_assert( nullptr <= 0, ""); // expected-error {{invalid operands to binary expression}}
+static_assert( nullptr >= 0, ""); // expected-error {{invalid operands to binary expression}}
static_assert( nullptr == 0, "");
static_assert(!(nullptr != 0), "");
@@ -154,10 +154,10 @@ namespace overloading {
void test_conversion(ConvertsToNullPtr ctn) {
(void)(ctn == ctn);
(void)(ctn != ctn);
- (void)(ctn <= ctn);
- (void)(ctn >= ctn);
- (void)(ctn < ctn);
- (void)(ctn > ctn);
+ (void)(ctn <= ctn); // expected-error {{invalid operands to binary expression}}
+ (void)(ctn >= ctn); // expected-error {{invalid operands to binary expression}}
+ (void)(ctn < ctn); // expected-error {{invalid operands to binary expression}}
+ (void)(ctn > ctn); // expected-error {{invalid operands to binary expression}}
}
}
diff --git a/test/SemaCXX/nullptr_in_arithmetic_ops.cpp b/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
index 60b4670b3a5e..6273d9c42e0b 100644
--- a/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
+++ b/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
@@ -45,12 +45,12 @@ void foo() {
b = a == nullptr || nullptr == a; // expected-error 2{{invalid operands to binary expression}}
b = a != nullptr || nullptr != a; // expected-error 2{{invalid operands to binary expression}}
- b = &a < nullptr || nullptr < &a || &a > nullptr || nullptr > &a;
- b = &a <= nullptr || nullptr <= &a || &a >= nullptr || nullptr >= &a;
+ b = &a < nullptr || nullptr < &a || &a > nullptr || nullptr > &a; // expected-error 4{{invalid operands}}
+ b = &a <= nullptr || nullptr <= &a || &a >= nullptr || nullptr >= &a; // expected-error 4{{invalid operands}}
b = &a == nullptr || nullptr == &a || &a != nullptr || nullptr != &a;
- b = nullptr < nullptr || nullptr > nullptr;
- b = nullptr <= nullptr || nullptr >= nullptr;
+ b = nullptr < nullptr || nullptr > nullptr; // expected-error 2{{invalid operands to binary expression}}
+ b = nullptr <= nullptr || nullptr >= nullptr; // expected-error 2{{invalid operands to binary expression}}
b = nullptr == nullptr || nullptr != nullptr;
b = ((nullptr)) != a; // expected-error{{invalid operands to binary expression}}
diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp
index 7eaf98b601c1..3a01bf24b31a 100644
--- a/test/SemaCXX/overload-call.cpp
+++ b/test/SemaCXX/overload-call.cpp
@@ -647,3 +647,14 @@ namespace PR20218 {
g(y); // expected-error {{ambiguous}}
}
}
+
+namespace StringLiteralToCharAmbiguity {
+ void f(char *, int);
+ void f(const char *, unsigned);
+ void g() { f("foo", 0); }
+#if __cplusplus <= 199711L
+ // expected-error@-2 {{call to 'f' is ambiguous}}
+ // expected-note@-5 {{candidate function}}
+ // expected-note@-5 {{candidate function}}
+#endif
+}
diff --git a/test/SemaCXX/pr28050.cpp b/test/SemaCXX/pr28050.cpp
new file mode 100644
index 000000000000..57e90eb75169
--- /dev/null
+++ b/test/SemaCXX/pr28050.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -std=c++11 %s -fsyntax-only
+//
+// expected-no-diagnostics
+
+class A {
+public:
+ A(char *s) {}
+ A(A &&) = delete;
+};
+
+int main() { A a("OK"); }
diff --git a/test/SemaCXX/predefined-expr.cpp b/test/SemaCXX/predefined-expr.cpp
index f4a155da6678..8cba0d41a299 100644
--- a/test/SemaCXX/predefined-expr.cpp
+++ b/test/SemaCXX/predefined-expr.cpp
@@ -33,11 +33,10 @@ int baz() {
();
^{
- static_assert(sizeof(__func__) == 27, "___Z3bazIiEiv_block_invoke");
- static_assert(sizeof(__FUNCTION__) == 27, "___Z3bazIiEiv_block_invoke");
- static_assert(sizeof(__PRETTY_FUNCTION__) == 27, "___Z3bazIiEiv_block_invoke");
- }
- ();
+ static_assert(sizeof(__func__) == 17, "baz_block_invoke");
+ static_assert(sizeof(__FUNCTION__) == 17, "baz_block_invoke");
+ static_assert(sizeof(__PRETTY_FUNCTION__) == 33, "int baz() [T = int]_block_invoke");
+ }();
#pragma clang __debug captured
{
@@ -64,11 +63,10 @@ int main() {
();
^{
- static_assert(sizeof(__func__) == 20, "__main_block_invoke");
- static_assert(sizeof(__FUNCTION__) == 20, "__main_block_invoke");
- static_assert(sizeof(__PRETTY_FUNCTION__) == 20, "__main_block_invoke");
- }
- ();
+ static_assert(sizeof(__func__) == 18, "main_block_invoke");
+ static_assert(sizeof(__FUNCTION__) == 18, "main_block_invoke");
+ static_assert(sizeof(__PRETTY_FUNCTION__) == 24, "int main()_block_invoke");
+ }();
#pragma clang __debug captured
{
diff --git a/test/SemaCXX/reinterpret-cast.cpp b/test/SemaCXX/reinterpret-cast.cpp
index 7c88dc0302ad..6cc46d8b0d9f 100644
--- a/test/SemaCXX/reinterpret-cast.cpp
+++ b/test/SemaCXX/reinterpret-cast.cpp
@@ -125,7 +125,7 @@ void const_arrays() {
namespace PR9564 {
struct a { int a : 10; }; a x;
- int *y = &reinterpret_cast<int&>(x.a); // expected-error {{not allowed}}
+ int *y = &reinterpret_cast<int&>(x.a); // expected-error {{reinterpret_cast from bit-field lvalue to reference type 'int &'}}
__attribute((ext_vector_type(4))) typedef float v4;
float& w(v4 &a) { return reinterpret_cast<float&>(a[1]); } // expected-error {{not allowed}}
diff --git a/test/SemaCXX/rval-references.cpp b/test/SemaCXX/rval-references.cpp
index 4c2050494b69..94b09ce2cb2a 100644
--- a/test/SemaCXX/rval-references.cpp
+++ b/test/SemaCXX/rval-references.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 %s
typedef int&& irr;
typedef irr& ilr_c1; // Collapses to int&
@@ -30,11 +30,15 @@ void f() {
int &&virr2 = 0;
int &&virr3 = virr2; // expected-error {{rvalue reference to type 'int' cannot bind to lvalue of type 'int'}}
int i1 = 0;
+ const double d1 = 0;
+ const int ci1 = 1;
int &&virr4 = i1; // expected-error {{rvalue reference to type 'int' cannot bind to lvalue of type 'int'}}
int &&virr5 = ret_irr();
int &&virr6 = static_cast<int&&>(i1);
- (void)static_cast<not_int&&>(i1); // expected-error {{types are not compatible}}
-
+ (void)static_cast<not_int &&>(i1); // expected-error {{reference to type 'not_int' could not bind to an lvalue of type 'int'}}
+ (void)static_cast<int &&>(static_cast<int const&&>(i1)); // expected-error {{cannot cast from rvalue of type 'const int' to rvalue reference type 'int &&'}}
+ (void)static_cast<int &&>(ci1); // expected-error {{types are not compatible}}
+ (void)static_cast<int &&>(d1);
int i2 = over(i1);
not_int ni1 = over(0);
int i3 = over(virr2);
diff --git a/test/SemaCXX/switch.cpp b/test/SemaCXX/switch.cpp
index 392dcd869802..0c60ce02097b 100644
--- a/test/SemaCXX/switch.cpp
+++ b/test/SemaCXX/switch.cpp
@@ -100,3 +100,33 @@ namespace Conversion {
}
template void f(S); // expected-note {{instantiation of}}
}
+
+// rdar://29230764
+namespace OpaqueEnumWarnings {
+
+enum Opaque : int;
+enum class OpaqueClass : int;
+
+enum class Defined : int;
+enum class Defined : int { a };
+
+void test(Opaque o, OpaqueClass oc, Defined d) {
+ // Don't warn that case value is not present in opaque enums.
+ switch (o) {
+ case (Opaque)1:
+ break;
+ }
+ switch (oc) {
+ case (OpaqueClass)1:
+ break;
+ }
+
+ switch (d) {
+ case Defined::a:
+ break;
+ case (Defined)2: // expected-warning {{case value not in enumerated type 'OpaqueEnumWarnings::Defined'}}
+ break;
+ }
+}
+
+}
diff --git a/test/SemaCXX/template-ambiguous-overload.cpp b/test/SemaCXX/template-ambiguous-overload.cpp
new file mode 100644
index 000000000000..bbb7e397b844
--- /dev/null
+++ b/test/SemaCXX/template-ambiguous-overload.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace n {
+template <int>
+void f(); // expected-note{{explicit instantiation candidate function 'n::f<0>' template here [with $0 = 0]}}
+
+extern template void f<0>();
+}
+
+using namespace n;
+
+template <int>
+void f() {} // expected-note{{explicit instantiation candidate function 'f<0>' template here [with $0 = 0]}}
+
+template void f<0>(); // expected-error{{partial ordering for explicit instantiation of 'f' is ambiguous}}
+
diff --git a/test/SemaCXX/type-definition-in-specifier.cpp b/test/SemaCXX/type-definition-in-specifier.cpp
index 43443a00e44b..74ba058b4f12 100644
--- a/test/SemaCXX/type-definition-in-specifier.cpp
+++ b/test/SemaCXX/type-definition-in-specifier.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -verify %s
struct S0;
struct S1;
@@ -30,7 +30,7 @@ struct pr19018 {
void pr19018_1 (enum e19018_1 {qq} x); // expected-error{{cannot be defined in a parameter type}}
void pr19018_1a (enum e19018_1 {qq} x); // expected-error{{cannot be defined in a parameter type}}
-e19018_1 x2; // expected-error{{unknown type name 'e19018_1'}}
+e19018_1 x2;
void pr19018_2 (enum {qq} x); // expected-error{{cannot be defined in a parameter type}}
void pr19018_3 (struct s19018_2 {int qq;} x); // expected-error{{cannot be defined in a parameter type}}
@@ -53,14 +53,19 @@ struct pr19018a {
struct s19018b {
void func1 (enum en_2 {qq} x); // expected-error{{cannot be defined in a parameter type}}
- en_2 x1; // expected-error{{unknown type name 'en_2'}}
+ en_2 x1;
void func2 (enum en_3 {qq} x); // expected-error{{cannot be defined in a parameter type}}
- enum en_3 x2; // expected-error{{ISO C++ forbids forward references to 'enum' types}} \
- // expected-error{{field has incomplete type 'enum en_3'}} \
- // expected-note{{forward declaration of 'en_3'}}
+ enum en_3 x2;
};
struct pr18963 {
- short bar5 (struct foo4 {} bar2); // expected-error{{'foo4' cannot be defined in a parameter type}}
- long foo5 (float foo6 = foo4); // expected-error{{use of undeclared identifier 'foo4'}}
+ short bar5 (struct foo4 {} bar2); // expected-error{{'foo4' cannot be defined in a parameter type}} \
+ // expected-note{{declared here}}
+
+ long foo5 (float foo6 = foo4); // expected-error{{'foo4' does not refer to a value}}
};
+
+// expected-error@+2 {{cannot be defined in a parameter type}}
+// expected-note@+1 {{previous definition is here}}
+void func_with_eh_and_type(struct type_in_eh {} o) throw(int) {}
+struct type_in_eh {}; // expected-error {{redefinition of 'type_in_eh'}}
diff --git a/test/SemaCXX/unknown-anytype.cpp b/test/SemaCXX/unknown-anytype.cpp
index 95ad04093405..78a01ba2d358 100644
--- a/test/SemaCXX/unknown-anytype.cpp
+++ b/test/SemaCXX/unknown-anytype.cpp
@@ -56,3 +56,15 @@ namespace test5 {
(X<int>)test0(); // expected-error{{implicit instantiation of undefined template 'test5::X<int>'}}
}
}
+
+namespace test6 {
+ extern __unknown_anytype func();
+ extern __unknown_anytype var;
+ double *d;
+
+ void test() {
+ d = (double*)&func(); // expected-error{{address-of operator cannot be applied to a call to a function with unknown return type}}
+ d = (double*)&var;
+ }
+
+}
diff --git a/test/SemaCXX/using-decl-templates.cpp b/test/SemaCXX/using-decl-templates.cpp
index d766bb3ac6bf..d5cc3a08eb75 100644
--- a/test/SemaCXX/using-decl-templates.cpp
+++ b/test/SemaCXX/using-decl-templates.cpp
@@ -90,5 +90,14 @@ namespace aliastemplateinst {
template<typename T> struct A { };
template<typename T> using APtr = A<T*>; // expected-note{{previous use is here}}
- template struct APtr<int>; // expected-error{{elaborated type refers to a type alias template}}
+ template struct APtr<int>; // expected-error{{type alias template 'APtr' cannot be referenced with a struct specifier}}
}
+
+namespace DontDiagnoseInvalidTest {
+template <bool Value> struct Base {
+ static_assert(Value, ""); // expected-error {{static_assert failed}}
+};
+struct Derived : Base<false> { // expected-note {{requested here}}
+ using Base<false>::Base; // OK. Don't diagnose that 'Base' isn't a base class of Derived.
+};
+} // namespace DontDiagnoseInvalidTest
diff --git a/test/SemaCXX/vartemplate-lambda.cpp b/test/SemaCXX/vartemplate-lambda.cpp
index 9dab6da3d1e3..5b91e232e3a6 100644
--- a/test/SemaCXX/vartemplate-lambda.cpp
+++ b/test/SemaCXX/vartemplate-lambda.cpp
@@ -1,18 +1,36 @@
// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s
-// expected-no-diagnostics
template <class> auto fn0 = [] {};
template <typename> void foo0() { fn0<char>(); }
template<typename T> auto fn1 = [](auto a) { return a + T(1); };
+template<typename T> auto v1 = [](int a = T(1)) { return a; }();
+
+struct S {
+ template<class T>
+ static constexpr T t = [](int f = T(7)){return f;}(); // expected-error{{constexpr variable 't<int>' must be initialized by a constant expression}} expected-error{{a lambda expression may not appear inside of a constant expression}} expected-note{{cannot be used in a constant expression}}
+};
template <typename X>
int foo2() {
X a = 0x61;
fn1<char>(a);
+ (void)v1<int>;
+ (void)S::t<int>; // expected-note{{in instantiation of static data member 'S::t<int>' requested here}}
return 0;
}
+template<class C>
+int foo3() {
+ C::m1(); // expected-error{{type 'long long' cannot be used prior to '::' because it has no members}}
+ return 1;
+}
+
+template<class C>
+auto v2 = [](int a = foo3<C>()){}; // expected-note{{in instantiation of function template specialization 'foo3<long long>' requested here}}
+
int main() {
+ v2<long long>(); // This line causes foo3<long long> to be instantiated.
+ v2<long long>(2); // This line does not.
foo2<int>();
}
diff --git a/test/SemaCXX/warn-c++1z-extensions.cpp b/test/SemaCXX/warn-c++1z-extensions.cpp
new file mode 100644
index 000000000000..9b5e1c205cf3
--- /dev/null
+++ b/test/SemaCXX/warn-c++1z-extensions.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s
+
+void f() {
+ if (bool b = true; b) {} // expected-warning {{'if' initialization statements are a C++1z extension}}
+ switch (int n = 5; n) { // expected-warning {{'switch' initialization statements are a C++1z extension}}
+ case 5: break;
+ }
+}
diff --git a/test/SemaCXX/warn-everthing.cpp b/test/SemaCXX/warn-everthing.cpp
index ad3dd8a24d88..ff66c78cdf97 100644
--- a/test/SemaCXX/warn-everthing.cpp
+++ b/test/SemaCXX/warn-everthing.cpp
@@ -9,5 +9,5 @@ public:
};
void testPR12271() { // expected-warning {{no previous prototype for function 'testPR12271'}}
- PR12271 a[1][1]; // expected-warning {{unused variable 'a'}}
+ PR12271 a[1][1];
}
diff --git a/test/SemaCXX/warn-logical-not-compare.cpp b/test/SemaCXX/warn-logical-not-compare.cpp
index 280ab22d7235..8b332c3c0e8a 100644
--- a/test/SemaCXX/warn-logical-not-compare.cpp
+++ b/test/SemaCXX/warn-logical-not-compare.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -Wlogical-not-parentheses -verify %s
-// RUN: %clang_cc1 -fsyntax-only -Wlogical-not-parentheses -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -fsyntax-only -Wlogical-not-parentheses -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
bool getBool();
int getInt();
@@ -189,6 +189,45 @@ bool test2 (E e) {
return ret;
}
+bool test_bitwise_op(int x) {
+ bool ret;
+
+ ret = !x & 1;
+ // expected-warning@-1 {{logical not is only applied to the left hand side of this bitwise operator}}
+ // expected-note@-2 {{add parentheses after the '!' to evaluate the bitwise operator first}}
+ // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
+ // CHECK: warn-logical-not-compare.cpp:[[line:[0-9]*]]:9: warning
+ // CHECK: to evaluate the bitwise operator first
+ // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("
+ // CHECK: fix-it:"{{.*}}":{[[line]]:15-[[line]]:15}:")"
+ // CHECK: to silence this warning
+ // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"("
+ // CHECK: fix-it:"{{.*}}":{[[line]]:11-[[line]]:11}:")"
+ ret = !(x & 1);
+ ret = (!x) & 1;
+
+ // This warning is really about !x & FOO since that's a common misspelling
+ // of the negated bit test !(x & FOO). Don't warn for | and ^, since
+ // it's at least conceivable that the user wants to use | as an
+ // alternative to || that evaluates both branches. (The warning above is
+ // only emitted if the operand to ! is not a bool, but in C that's common.)
+ // And there's no logical ^.
+ ret = !x | 1;
+ ret = !(x | 1);
+ ret = (!x) | 1;
+
+ ret = !x ^ 1;
+ ret = !(x ^ 1);
+ ret = (!x) ^ 1;
+
+ // These already err, don't also warn.
+ !x &= 1; // expected-error{{expression is not assignable}}
+ !x |= 1; // expected-error{{expression is not assignable}}
+ !x ^= 1; // expected-error{{expression is not assignable}}
+
+ return ret;
+}
+
bool PR16673(int x) {
bool ret;
// Make sure we don't emit a fixit for the left paren, but not the right paren.
diff --git a/test/SemaCXX/warn-max-unsigned-zero.cpp b/test/SemaCXX/warn-max-unsigned-zero.cpp
new file mode 100644
index 000000000000..5564b101d8ec
--- /dev/null
+++ b/test/SemaCXX/warn-max-unsigned-zero.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -fsyntax-only -Wmax-unsigned-zero -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -Wmax-unsigned-zero %s -std=c++11 -fdiagnostics-parseable-fixits 2>&1 | FileCheck %s
+
+namespace std {
+template <typename T>
+T max(const T &, const T &);
+}
+
+void test(unsigned u) {
+ auto a = std::max(55u, 0u);
+ // expected-warning@-1{{taking the max of a value and unsigned zero is always equal to the other value}}
+ // expected-note@-2{{remove call to max function and unsigned zero argument}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:20}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:24-[[@LINE-4]]:28}:""
+ auto b = std::max(u, 0u);
+ // expected-warning@-1{{taking the max of a value and unsigned zero is always equal to the other value}}
+ // expected-note@-2{{remove call to max function and unsigned zero argument}}
+ // fix-it:"/usr/local/google/home/rtrieu/clang/open/llvm/tools/clang/test/SemaCXX/warn-max-unsigned-zero.cpp":{13:12-13:20}:""
+ // fix-it:"/usr/local/google/home/rtrieu/clang/open/llvm/tools/clang/test/SemaCXX/warn-max-unsigned-zero.cpp":{13:22-13:26}:""
+ auto c = std::max(0u, 55u);
+ // expected-warning@-1{{taking the max of unsigned zero and a value is always equal to the other value}}
+ // expected-note@-2{{remove call to max function and unsigned zero argument}}
+ // fix-it:"/usr/local/google/home/rtrieu/clang/open/llvm/tools/clang/test/SemaCXX/warn-max-unsigned-zero.cpp":{16:12-16:20}:""
+ // fix-it:"/usr/local/google/home/rtrieu/clang/open/llvm/tools/clang/test/SemaCXX/warn-max-unsigned-zero.cpp":{16:21-16:24}:""
+ auto d = std::max(0u, u);
+ // expected-warning@-1{{taking the max of unsigned zero and a value is always equal to the other value}}
+ // expected-note@-2{{remove call to max function and unsigned zero argument}}
+ // fix-it:"/usr/local/google/home/rtrieu/clang/open/llvm/tools/clang/test/SemaCXX/warn-max-unsigned-zero.cpp":{19:12-19:20}:""
+ // fix-it:"/usr/local/google/home/rtrieu/clang/open/llvm/tools/clang/test/SemaCXX/warn-max-unsigned-zero.cpp":{19:21-19:24}:""
+}
+
+void negative_test(signed s) {
+ auto a = std::max(0, s);
+ auto b = std::max(s, 0);
+ auto c = std::max(22, 0);
+ auto d = std::max(0, 22);
+}
+
+template <unsigned x>
+unsigned template_test() {
+ return std::max(x, 0u);
+ // expected-warning@-1{{taking the max of a value and unsigned zero is always equal to the other value}}
+ // expected-note@-2{{remove call to max function and unsigned zero argument}}
+ // fix-it:"/usr/local/google/home/rtrieu/clang/open/llvm/tools/clang/test/SemaCXX/warn-max-unsigned-zero.cpp":{33:10-33:18}:""
+ // fix-it:"/usr/local/google/home/rtrieu/clang/open/llvm/tools/clang/test/SemaCXX/warn-max-unsigned-zero.cpp":{33:20-33:24}:""
+}
+
+int a = template_test<0>() + template_test<1>() + template_test<2>();
+
+#define comp(x,y) std::max(x, y)
+
+int b = comp(0, 1);
+int c = comp(0u, 1u);
+int d = comp(2u, 0u);
+
diff --git a/test/SemaCXX/warn-memset-bad-sizeof.cpp b/test/SemaCXX/warn-memset-bad-sizeof.cpp
index cca15fc8ef3c..0a78caa924ea 100644
--- a/test/SemaCXX/warn-memset-bad-sizeof.cpp
+++ b/test/SemaCXX/warn-memset-bad-sizeof.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-sizeof-array-argument %s
//
+extern "C" void *bzero(void *, unsigned);
extern "C" void *memset(void *, int, unsigned);
extern "C" void *memmove(void *s1, const void *s2, unsigned n);
extern "C" void *memcpy(void *s1, const void *s2, unsigned n);
@@ -47,6 +48,19 @@ void f(Mat m, const Foo& const_foo, char *buffer) {
memset(heap_buffer, 0, sizeof(heap_buffer)); // \
// expected-warning {{'memset' call operates on objects of type 'char' while the size is based on a different type 'char *'}} expected-note{{did you mean to provide an explicit length?}}
+ bzero(&s, sizeof(&s)); // \
+ // expected-warning {{'bzero' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to remove the addressof in the argument to 'sizeof' (and multiply it by the number of elements)?}}
+ bzero(ps, sizeof(ps)); // \
+ // expected-warning {{'bzero' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)?}}
+ bzero(ps2, sizeof(ps2)); // \
+ // expected-warning {{'bzero' call operates on objects of type 'S' while the size is based on a different type 'PS' (aka 'S *')}} expected-note{{did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)?}}
+ bzero(ps2, sizeof(typeof(ps2))); // \
+ // expected-warning {{argument to 'sizeof' in 'bzero' call is the same pointer type}}
+ bzero(ps2, sizeof(PS)); // \
+ // expected-warning {{argument to 'sizeof' in 'bzero' call is the same pointer type}}
+ bzero(heap_buffer, sizeof(heap_buffer)); // \
+ // expected-warning {{'bzero' call operates on objects of type 'char' while the size is based on a different type 'char *'}} expected-note{{did you mean to provide an explicit length?}}
+
memcpy(&s, 0, sizeof(&s)); // \
// expected-warning {{'memcpy' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to remove the addressof in the argument to 'sizeof' (and multiply it by the number of elements)?}}
memcpy(0, &s, sizeof(&s)); // \
@@ -73,6 +87,21 @@ void f(Mat m, const Foo& const_foo, char *buffer) {
memset(arr, 0, sizeof(arr));
memset(parr, 0, sizeof(parr));
+ bzero((void*)&s, sizeof(&s));
+ bzero(&s, sizeof(s));
+ bzero(&s, sizeof(S));
+ bzero(&s, sizeof(const S));
+ bzero(&s, sizeof(volatile S));
+ bzero(&s, sizeof(volatile const S));
+ bzero(&foo, sizeof(CFoo));
+ bzero(&foo, sizeof(VFoo));
+ bzero(&foo, sizeof(CVFoo));
+ bzero(ps, sizeof(*ps));
+ bzero(ps2, sizeof(*ps2));
+ bzero(ps2, sizeof(typeof(*ps2)));
+ bzero(arr, sizeof(arr));
+ bzero(parr, sizeof(parr));
+
memcpy(&foo, &const_foo, sizeof(Foo));
memcpy((void*)&s, 0, sizeof(&s));
memcpy(0, (void*)&s, sizeof(&s));
@@ -96,12 +125,17 @@ void f(Mat m, const Foo& const_foo, char *buffer) {
int iarr[14];
memset(&iarr[0], 0, sizeof iarr);
memset(iarr, 0, sizeof iarr);
+ bzero(&iarr[0], sizeof iarr);
+ bzero(iarr, sizeof iarr);
int* iparr[14];
memset(&iparr[0], 0, sizeof iparr);
memset(iparr, 0, sizeof iparr);
+ bzero(&iparr[0], sizeof iparr);
+ bzero(iparr, sizeof iparr);
memset(m, 0, sizeof(Mat));
+ bzero(m, sizeof(Mat));
// Copy to raw buffer shouldn't warn either
memcpy(&foo, &arr, sizeof(Foo));
@@ -114,12 +148,21 @@ void f(Mat m, const Foo& const_foo, char *buffer) {
for (;;) {}
&s;
}), 0, sizeof(s));
+
+ bzero(({
+ if (0) {}
+ while (0) {}
+ for (;;) {}
+ &s;
+ }), sizeof(s));
}
namespace ns {
void memset(void* s, char c, int n);
+void bzero(void* s, int n);
void f(int* i) {
memset(i, 0, sizeof(i));
+ bzero(i, sizeof(i));
}
}
diff --git a/test/SemaCXX/warn-memsize-comparison.cpp b/test/SemaCXX/warn-memsize-comparison.cpp
index 54c410e3dc0b..b5c7a9d6969c 100644
--- a/test/SemaCXX/warn-memsize-comparison.cpp
+++ b/test/SemaCXX/warn-memsize-comparison.cpp
@@ -5,7 +5,7 @@ typedef __SIZE_TYPE__ size_t;
extern "C" void *memset(void *, int, size_t);
extern "C" void *memmove(void *s1, const void *s2, size_t n);
extern "C" void *memcpy(void *s1, const void *s2, size_t n);
-extern "C" void *memcmp(void *s1, const void *s2, size_t n);
+extern "C" int memcmp(void *s1, const void *s2, size_t n);
extern "C" int strncmp(const char *s1, const char *s2, size_t n);
extern "C" int strncasecmp(const char *s1, const char *s2, size_t n);
extern "C" char *strncpy(char *dst, const char *src, size_t n);
@@ -28,11 +28,12 @@ void f() {
expected-note {{explicitly cast the argument}}
if (memmove(b1, b2, sizeof(b1)) == 0) {}
+ // FIXME: This fixit is bogus.
if (memcpy(b1, b2, sizeof(b1) < 0)) {} // \
expected-warning{{size argument in 'memcpy' call is a comparison}} \
expected-note {{did you mean to compare}} \
expected-note {{explicitly cast the argument}}
- if (memcpy(b1, b2, sizeof(b1)) < 0) {}
+ if (memcpy(b1, b2, sizeof(b1)) < 0) {} // expected-error {{ordered comparison between pointer and zero}}
if (memcmp(b1, b2, sizeof(b1) <= 0)) {} // \
expected-warning{{size argument in 'memcmp' call is a comparison}} \
@@ -58,11 +59,12 @@ void f() {
expected-note {{explicitly cast the argument}}
if (strncpy(b1, b2, sizeof(b1)) == 0 || true) {}
+ // FIXME: This fixit is bogus.
if (strncat(b1, b2, sizeof(b1) - 1 >= 0 && true)) {} // \
expected-warning{{size argument in 'strncat' call is a comparison}} \
expected-note {{did you mean to compare}} \
expected-note {{explicitly cast the argument}}
- if (strncat(b1, b2, sizeof(b1) - 1) >= 0 && true) {}
+ if (strncat(b1, b2, sizeof(b1) - 1) >= 0 && true) {} // expected-error {{ordered comparison between pointer and zero}}
if (strndup(b1, sizeof(b1) != 0)) {} // \
expected-warning{{size argument in 'strndup' call is a comparison}} \
diff --git a/test/SemaCXX/warn-missing-variable-declarations.cpp b/test/SemaCXX/warn-missing-variable-declarations.cpp
index ad23e0429bbd..5b882845f3c6 100644
--- a/test/SemaCXX/warn-missing-variable-declarations.cpp
+++ b/test/SemaCXX/warn-missing-variable-declarations.cpp
@@ -47,3 +47,8 @@ class C {
static int x = 0; // no-warn
}
};
+
+// There is also no need to use static in anonymous namespaces.
+namespace {
+ int vgood4;
+}
diff --git a/test/SemaCXX/warn-msvc-enum-bitfield.cpp b/test/SemaCXX/warn-msvc-enum-bitfield.cpp
new file mode 100644
index 000000000000..99e1669018ab
--- /dev/null
+++ b/test/SemaCXX/warn-msvc-enum-bitfield.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -Wsigned-enum-bitfield -verify %s --std=c++11
+
+// Enums used in bitfields with no explicitly specified underlying type.
+void test0() {
+ enum E { E1, E2 };
+ enum F { F1, F2 };
+ struct { E e1 : 1; E e2; F f1 : 1; F f2; } s;
+
+ s.e1 = E1; // expected-warning {{enums in the Microsoft ABI are signed integers by default; consider giving the enum E an unsigned underlying type to make this code portable}}
+ s.f1 = F1; // expected-warning {{enums in the Microsoft ABI are signed integers by default; consider giving the enum F an unsigned underlying type to make this code portable}}
+
+ s.e2 = E2;
+ s.f2 = F2;
+}
+
+// Enums used in bitfields with an explicit signed underlying type.
+void test1() {
+ enum E : signed { E1, E2 };
+ enum F : long { F1, F2 };
+ struct { E e1 : 1; E e2; F f1 : 1; F f2; } s;
+
+ s.e1 = E1;
+ s.f1 = F1;
+
+ s.e2 = E2;
+ s.f2 = F2;
+}
+
+// Enums used in bitfields with an explicitly unsigned underlying type.
+void test3() {
+ enum E : unsigned { E1, E2 };
+ enum F : unsigned long { F1, F2 };
+ struct { E e1 : 1; E e2; F f1 : 1; F f2; } s;
+
+ s.e1 = E1;
+ s.f1 = F1;
+
+ s.e2 = E2;
+ s.f2 = F2;
+}
diff --git a/test/SemaCXX/warn-range-loop-analysis.cpp b/test/SemaCXX/warn-range-loop-analysis.cpp
index 91756b970e97..98c4a18776a1 100644
--- a/test/SemaCXX/warn-range-loop-analysis.cpp
+++ b/test/SemaCXX/warn-range-loop-analysis.cpp
@@ -29,7 +29,7 @@ struct Bar {
// test1-6 are set in pairs, the odd numbers are the non-reference returning
// versions of the even numbers.
// test7-9 use an array instead of a range object
-// tests use all four versions of the loop varaible, const &T, const T, T&, and
+// tests use all four versions of the loop variable, const &T, const T, T&, and
// T. Versions producing errors and are commented out.
//
// Conversion chart:
diff --git a/test/SemaCXX/warn-shadow-in-lambdas.cpp b/test/SemaCXX/warn-shadow-in-lambdas.cpp
new file mode 100644
index 000000000000..575664482dbe
--- /dev/null
+++ b/test/SemaCXX/warn-shadow-in-lambdas.cpp
@@ -0,0 +1,139 @@
+// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -Wshadow -D AVOID %s
+// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -Wshadow -Wshadow-uncaptured-local %s
+// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -Wshadow-all %s
+
+void foo(int param) { // expected-note 1+ {{previous declaration is here}}
+ int var = 0; // expected-note 1+ {{previous declaration is here}}
+
+ // Avoid warnings for variables that aren't implicitly captured.
+ {
+#ifdef AVOID
+ auto f1 = [=] { int var = 1; }; // no warning
+ auto f2 = [&] { int var = 2; }; // no warning
+ auto f3 = [=] (int param) { ; }; // no warning
+ auto f4 = [&] (int param) { ; }; // no warning
+#else
+ auto f1 = [=] { int var = 1; }; // expected-warning {{declaration shadows a local variable}}
+ auto f2 = [&] { int var = 2; }; // expected-warning {{declaration shadows a local variable}}
+ auto f3 = [=] (int param) { ; }; // expected-warning {{declaration shadows a local variable}}
+ auto f4 = [&] (int param) { ; }; // expected-warning {{declaration shadows a local variable}}
+#endif
+ }
+
+ // Warn for variables that are implicitly captured.
+ {
+ auto f1 = [=] () {
+ {
+ int var = 1; // expected-warning {{declaration shadows a local variable}}
+ }
+ int x = var; // expected-note {{variable 'var' is captured here}}
+ };
+ auto f2 = [&]
+#ifdef AVOID
+ (int param) {
+#else
+ (int param) { // expected-warning {{declaration shadows a local variable}}
+#endif
+ int x = var; // expected-note {{variable 'var' is captured here}}
+ int var = param; // expected-warning {{declaration shadows a local variable}}
+ };
+ }
+
+ // Warn for variables that are explicitly captured when a lambda has a default
+ // capture specifier.
+ {
+ auto f1 = [=, &var] () { // expected-note {{variable 'var' is captured here}}
+ int x = param; // expected-note {{variable 'param' is captured here}}
+ int var = 0; // expected-warning {{declaration shadows a local variable}}
+ int param = 0; // expected-warning {{declaration shadows a local variable}}
+ };
+ }
+
+ // Warn normally inside of lambdas.
+ auto l1 = [] { // expected-note {{previous declaration is here}}
+ int x = 1; // expected-note {{previous declaration is here}}
+ { int x = 2; } // expected-warning {{declaration shadows a local variable}}
+ };
+ auto l2 = [] (int x) { // expected-note {{previous declaration is here}}
+ { int x = 1; } // expected-warning {{declaration shadows a local variable}}
+ };
+
+ // Avoid warnings for variables that aren't explicitly captured.
+ {
+#ifdef AVOID
+ auto f1 = [] { int var = 1; }; // no warning
+ auto f2 = [] (int param) { ; }; // no warning
+ auto f3 = [param] () { int var = 1; }; // no warning
+ auto f4 = [var] (int param) { ; }; // no warning
+#else
+ auto f1 = [] { int var = 1; }; // expected-warning {{declaration shadows a local variable}}
+ auto f2 = [] (int param) { ; }; // expected-warning {{declaration shadows a local variable}}
+ auto f3 = [param] () { int var = 1; }; // expected-warning {{declaration shadows a local variable}}
+ auto f4 = [var] (int param) { ; }; // expected-warning {{declaration shadows a local variable}}
+#endif
+ };
+
+ // Warn for variables that are explicitly captured.
+ {
+ auto f1 = [var] () { // expected-note {{variable 'var' is explicitly captured here}}
+ int var = 1; // expected-warning {{declaration shadows a local variable}}
+ };
+ auto f2 = [param] // expected-note {{variable 'param' is explicitly captured here}}
+ (int param) { ; }; // expected-warning {{declaration shadows a local variable}}
+ }
+
+ // Warn for variables defined in the capture list.
+ auto l3 = [z = var] { // expected-note {{previous declaration is here}}
+#ifdef AVOID
+ int var = 1; // no warning
+#else
+ int var = 1; // expected-warning {{declaration shadows a local variable}}
+#endif
+ { int z = 1; } // expected-warning {{declaration shadows a local variable}}
+ };
+#ifdef AVOID
+ auto l4 = [var = param] (int param) { ; }; // no warning
+#else
+ auto l4 = [var = param] (int param) { ; }; // expected-warning {{declaration shadows a local variable}}
+#endif
+
+ // Make sure that inner lambdas work as well.
+ auto l5 = [var, l1] { // expected-note {{variable 'l1' is explicitly captured here}}
+ auto l1 = [] { // expected-warning {{declaration shadows a local variable}}
+#ifdef AVOID
+ int var = 1; // no warning
+#else
+ int var = 1; // expected-warning {{declaration shadows a local variable}}
+#endif
+ };
+#ifdef AVOID
+ auto f1 = [] { int var = 1; }; // no warning
+ auto f2 = [=] { int var = 1; }; // no warning
+#else
+ auto f1 = [] { int var = 1; }; // expected-warning {{declaration shadows a local variable}}
+ auto f2 = [=] { int var = 1; }; // expected-warning {{declaration shadows a local variable}}
+#endif
+ auto f3 = [var] // expected-note {{variable 'var' is explicitly captured here}}
+ { int var = 1; }; // expected-warning {{declaration shadows a local variable}}
+ auto f4 = [&] {
+ int x = var; // expected-note {{variable 'var' is captured here}}
+ int var = 2; // expected-warning {{declaration shadows a local variable}}
+ };
+ };
+ auto l6 = [&] {
+ auto f1 = [param] { // expected-note {{variable 'param' is explicitly captured here}}
+ int param = 0; // expected-warning {{declaration shadows a local variable}}
+ };
+ };
+
+ // Generic lambda arguments should work.
+#ifdef AVOID
+ auto g1 = [](auto param) { ; }; // no warning
+ auto g2 = [=](auto param) { ; }; // no warning
+#else
+ auto g1 = [](auto param) { ; }; // expected-warning {{declaration shadows a local variable}}
+ auto g2 = [=](auto param) { ; }; // expected-warning {{declaration shadows a local variable}}
+#endif
+ auto g3 = [param] // expected-note {{variable 'param' is explicitly captured here}}
+ (auto param) { ; }; // expected-warning {{declaration shadows a local variable}}
+}
diff --git a/test/SemaCXX/warn-unused-variables.cpp b/test/SemaCXX/warn-unused-variables.cpp
index 8dcbe7271d69..d7be785b35a6 100644
--- a/test/SemaCXX/warn-unused-variables.cpp
+++ b/test/SemaCXX/warn-unused-variables.cpp
@@ -150,3 +150,47 @@ namespace ctor_with_cleanups {
}
#include "Inputs/warn-unused-variables.h"
+
+namespace arrayRecords {
+
+class NonTriviallyDestructible {
+public:
+ ~NonTriviallyDestructible() {}
+};
+
+struct Foo {
+ int x;
+ Foo(int x) : x(x) {}
+};
+
+struct Elidable {
+ Elidable();
+};
+
+void foo(int size) {
+ Elidable elidable; // no warning
+ Elidable elidableArray[2]; // no warning
+ Elidable elidableDynArray[size]; // no warning
+ Elidable elidableNestedArray[1][2][3]; // no warning
+
+ NonTriviallyDestructible scalar; // no warning
+ NonTriviallyDestructible array[2]; // no warning
+ NonTriviallyDestructible nestedArray[2][2]; // no warning
+
+ Foo fooScalar = 1; // expected-warning {{unused variable 'fooScalar'}}
+ Foo fooArray[] = {1,2}; // expected-warning {{unused variable 'fooArray'}}
+ Foo fooNested[2][2] = { {1,2}, {3,4} }; // expected-warning {{unused variable 'fooNested'}}
+}
+
+template<int N>
+void bar() {
+ NonTriviallyDestructible scaler; // no warning
+ NonTriviallyDestructible array[N]; // no warning
+}
+
+void test() {
+ foo(10);
+ bar<2>();
+}
+
+}
diff --git a/test/SemaCXX/warn-weak-vtables.cpp b/test/SemaCXX/warn-weak-vtables.cpp
index d30665387153..e678f9e461ef 100644
--- a/test/SemaCXX/warn-weak-vtables.cpp
+++ b/test/SemaCXX/warn-weak-vtables.cpp
@@ -1,5 +1,8 @@
// RUN: %clang_cc1 %s -fsyntax-only -verify -triple %itanium_abi_triple -Wweak-vtables -Wweak-template-vtables
-// RUN: %clang_cc1 %s -fsyntax-only -triple %ms_abi_triple -Werror -Wno-weak-vtables -Wno-weak-template-vtables
+//
+// Check that this warning is disabled on MS ABI targets which don't have key
+// functions.
+// RUN: %clang_cc1 %s -fsyntax-only -triple %ms_abi_triple -Werror -Wweak-vtables -Wweak-template-vtables
struct A { // expected-warning {{'A' has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit}}
virtual void f() { }