aboutsummaryrefslogtreecommitdiff
path: root/test/SemaCXX
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2014-11-24 09:15:30 +0000
committerDimitry Andric <dim@FreeBSD.org>2014-11-24 09:15:30 +0000
commit9f4dbff6669c8037f3b036bcf580d14f1a4f12a5 (patch)
tree47df2c12b57214af6c31e47404b005675b8b7ffc /test/SemaCXX
parentf73d5f23a889b93d89ddef61ac0995df40286bb8 (diff)
Notes
Diffstat (limited to 'test/SemaCXX')
-rw-r--r--test/SemaCXX/MicrosoftCompatibility.cpp31
-rw-r--r--test/SemaCXX/MicrosoftExtensions.cpp68
-rw-r--r--test/SemaCXX/PR19955.cpp16
-rw-r--r--test/SemaCXX/PR20110.cpp15
-rw-r--r--test/SemaCXX/PR8012.cpp2
-rw-r--r--test/SemaCXX/__try.cpp12
-rw-r--r--test/SemaCXX/abstract.cpp20
-rw-r--r--test/SemaCXX/access.cpp22
-rw-r--r--test/SemaCXX/addr-of-overloaded-function-casting.cpp13
-rw-r--r--test/SemaCXX/addr-of-overloaded-function.cpp20
-rw-r--r--test/SemaCXX/aggregate-initialization.cpp2
-rw-r--r--test/SemaCXX/alias-template.cpp10
-rw-r--r--test/SemaCXX/alignof.cpp15
-rw-r--r--test/SemaCXX/anonymous-struct.cpp7
-rw-r--r--test/SemaCXX/anonymous-union-cxx11.cpp9
-rw-r--r--test/SemaCXX/ast-print.cpp46
-rw-r--r--test/SemaCXX/atomic-type.cpp (renamed from test/SemaCXX/atomic-type.cxx)31
-rw-r--r--test/SemaCXX/attr-common.cpp2
-rw-r--r--test/SemaCXX/attr-cxx0x.cpp5
-rw-r--r--test/SemaCXX/attr-deprecated.cpp48
-rw-r--r--test/SemaCXX/attr-flatten.cpp34
-rw-r--r--test/SemaCXX/attr-no-sanitize-address.cpp10
-rw-r--r--test/SemaCXX/attr-no-sanitize-memory.cpp10
-rw-r--r--test/SemaCXX/attr-no-sanitize-thread.cpp10
-rw-r--r--test/SemaCXX/attr-no-split-stack.cpp34
-rw-r--r--test/SemaCXX/attr-optnone.cpp47
-rw-r--r--test/SemaCXX/attr-selectany.cpp5
-rw-r--r--test/SemaCXX/attr-unavailable.cpp21
-rw-r--r--test/SemaCXX/attr-used.cpp4
-rw-r--r--test/SemaCXX/attr-weak.cpp10
-rw-r--r--test/SemaCXX/attr-weakref.cpp4
-rw-r--r--test/SemaCXX/bool-compare.cpp207
-rw-r--r--test/SemaCXX/c99-variable-length-array.cpp21
-rw-r--r--test/SemaCXX/calling-conv-compat.cpp21
-rw-r--r--test/SemaCXX/compare.cpp2
-rw-r--r--test/SemaCXX/conditional-expr.cpp27
-rw-r--r--test/SemaCXX/const-cast.cpp2
-rw-r--r--test/SemaCXX/constant-expression-cxx11.cpp21
-rw-r--r--test/SemaCXX/constant-expression.cpp17
-rw-r--r--test/SemaCXX/constexpr-value-init.cpp2
-rw-r--r--test/SemaCXX/constructor-initializer.cpp7
-rw-r--r--test/SemaCXX/constructor.cpp2
-rw-r--r--test/SemaCXX/conversion-function.cpp14
-rw-r--r--test/SemaCXX/crashes.cpp13
-rw-r--r--test/SemaCXX/cstyle-cast.cpp4
-rw-r--r--test/SemaCXX/cxx-altivec.cpp5
-rw-r--r--test/SemaCXX/cxx0x-compat.cpp3
-rw-r--r--test/SemaCXX/cxx0x-cursory-default-delete.cpp4
-rw-r--r--test/SemaCXX/cxx0x-delegating-ctors.cpp2
-rw-r--r--test/SemaCXX/cxx0x-deleted-default-ctor.cpp4
-rw-r--r--test/SemaCXX/cxx0x-initializer-constructor.cpp46
-rw-r--r--test/SemaCXX/cxx0x-initializer-scalars.cpp4
-rw-r--r--test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp23
-rw-r--r--test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp29
-rw-r--r--test/SemaCXX/cxx0x-type-convert-construct.cpp4
-rw-r--r--test/SemaCXX/cxx11-attr-print.cpp3
-rw-r--r--test/SemaCXX/cxx11-gnu-attrs.cpp2
-rw-r--r--test/SemaCXX/cxx11-inheriting-ctors.cpp8
-rw-r--r--test/SemaCXX/cxx11-unused.cpp33
-rw-r--r--test/SemaCXX/cxx11-user-defined-literals.cpp24
-rw-r--r--test/SemaCXX/cxx1y-deduced-return-type.cpp7
-rw-r--r--test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp17
-rw-r--r--test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp100
-rw-r--r--test/SemaCXX/cxx1y-generic-lambdas.cpp25
-rw-r--r--test/SemaCXX/cxx1y-init-captures.cpp2
-rw-r--r--test/SemaCXX/cxx1y-variable-templates_in_class.cpp32
-rw-r--r--test/SemaCXX/cxx1y-variable-templates_top_level.cpp44
-rw-r--r--test/SemaCXX/cxx98-compat.cpp49
-rw-r--r--test/SemaCXX/dcl_init_aggr.cpp4
-rw-r--r--test/SemaCXX/decl-expr-ambiguity.cpp2
-rw-r--r--test/SemaCXX/decl-microsoft-call-conv.cpp42
-rw-r--r--test/SemaCXX/declspec-thread.cpp42
-rw-r--r--test/SemaCXX/decltype.cpp31
-rw-r--r--test/SemaCXX/default1.cpp3
-rw-r--r--test/SemaCXX/deleted-function.cpp6
-rw-r--r--test/SemaCXX/deleted-operator.cpp5
-rw-r--r--test/SemaCXX/deprecated.cpp9
-rw-r--r--test/SemaCXX/destructor.cpp25
-rw-r--r--test/SemaCXX/dllexport.cpp1010
-rw-r--r--test/SemaCXX/dllimport.cpp1085
-rw-r--r--test/SemaCXX/elaborated-type-specifier.cpp9
-rw-r--r--test/SemaCXX/enable_if.cpp79
-rw-r--r--test/SemaCXX/enum-bitfield.cpp12
-rw-r--r--test/SemaCXX/enum-scoped.cpp13
-rw-r--r--test/SemaCXX/err_init_conversion_failed.cpp16
-rw-r--r--test/SemaCXX/explicit.cpp5
-rw-r--r--test/SemaCXX/expression-traits.cpp15
-rw-r--r--test/SemaCXX/expressions.cpp17
-rw-r--r--test/SemaCXX/flexible-array-test.cpp21
-rw-r--r--test/SemaCXX/for-range-dereference.cpp2
-rw-r--r--test/SemaCXX/for-range-examples.cpp34
-rw-r--r--test/SemaCXX/format-strings.cpp2
-rw-r--r--test/SemaCXX/friend.cpp8
-rw-r--r--test/SemaCXX/funcdname.cpp32
-rw-r--r--test/SemaCXX/functional-cast.cpp4
-rw-r--r--test/SemaCXX/goto.cpp2
-rw-r--r--test/SemaCXX/implicit-member-functions.cpp2
-rw-r--r--test/SemaCXX/implicit-virtual-member-functions.cpp8
-rw-r--r--test/SemaCXX/init-priority-attr.cpp3
-rw-r--r--test/SemaCXX/lambda-expressions.cpp65
-rw-r--r--test/SemaCXX/linkage.cpp19
-rw-r--r--test/SemaCXX/linkage2.cpp4
-rw-r--r--test/SemaCXX/member-expr.cpp4
-rw-r--r--test/SemaCXX/member-init.cpp10
-rw-r--r--test/SemaCXX/member-pointer-ms.cpp122
-rw-r--r--test/SemaCXX/member-pointer.cpp10
-rw-r--r--test/SemaCXX/microsoft-cxx0x.cpp2
-rw-r--r--test/SemaCXX/microsoft-dtor-lookup-cxx11.cpp13
-rw-r--r--test/SemaCXX/microsoft-dtor-lookup.cpp66
-rw-r--r--test/SemaCXX/microsoft-new-delete.cpp26
-rw-r--r--test/SemaCXX/microsoft-varargs-diagnostics.cpp42
-rw-r--r--test/SemaCXX/microsoft-varargs.cpp22
-rw-r--r--test/SemaCXX/missing-members.cpp9
-rw-r--r--test/SemaCXX/ms-friend-lookup.cpp104
-rw-r--r--test/SemaCXX/ms-interface.cpp2
-rw-r--r--test/SemaCXX/ms_integer_suffix.cpp18
-rw-r--r--test/SemaCXX/ms_struct.cpp26
-rw-r--r--test/SemaCXX/nested-name-spec.cpp121
-rw-r--r--test/SemaCXX/new-delete-cxx0x.cpp13
-rw-r--r--test/SemaCXX/new-delete.cpp9
-rw-r--r--test/SemaCXX/new-null.cpp63
-rw-r--r--test/SemaCXX/nonnull.cpp15
-rw-r--r--test/SemaCXX/ns_returns_retained_block_return.cpp17
-rw-r--r--test/SemaCXX/null_in_arithmetic_ops.cpp2
-rw-r--r--test/SemaCXX/nullptr_in_arithmetic_ops.cpp2
-rw-r--r--test/SemaCXX/old-style-cast.cpp11
-rw-r--r--test/SemaCXX/operator-arrow-depth.cpp4
-rw-r--r--test/SemaCXX/overload-0x.cpp84
-rw-r--r--test/SemaCXX/overload-call.cpp30
-rw-r--r--test/SemaCXX/overloaded-operator.cpp67
-rw-r--r--test/SemaCXX/pr13394-crash-on-invalid.cpp4
-rw-r--r--test/SemaCXX/pr18284-crash-on-invalid.cpp24
-rw-r--r--test/SemaCXX/pr9812.c21
-rw-r--r--test/SemaCXX/pr9812.cpp9
-rw-r--r--test/SemaCXX/pragma-init_seg.cpp21
-rw-r--r--test/SemaCXX/pragma-optimize.cpp113
-rw-r--r--test/SemaCXX/pragma-vtordisp.cpp40
-rw-r--r--test/SemaCXX/pragma-weak.cpp3
-rw-r--r--test/SemaCXX/primary-base.cpp2
-rw-r--r--test/SemaCXX/qualified-id-lookup.cpp2
-rw-r--r--test/SemaCXX/references.cpp12
-rw-r--r--test/SemaCXX/reinterpret-cast.cpp6
-rw-r--r--test/SemaCXX/return-noreturn.cpp30
-rw-r--r--test/SemaCXX/return-stack-addr.cpp23
-rw-r--r--test/SemaCXX/return.cpp10
-rw-r--r--test/SemaCXX/rval-references-examples.cpp2
-rw-r--r--test/SemaCXX/scope-check.cpp158
-rw-r--r--test/SemaCXX/sourceranges.cpp11
-rw-r--r--test/SemaCXX/static-assert.cpp3
-rw-r--r--test/SemaCXX/static-cast.cpp5
-rw-r--r--test/SemaCXX/switch-implicit-fallthrough-blocks.cpp19
-rw-r--r--test/SemaCXX/switch-implicit-fallthrough.cpp71
-rw-r--r--test/SemaCXX/template-implicit-vars.cpp14
-rw-r--r--test/SemaCXX/trailing-return-0x.cpp4
-rw-r--r--test/SemaCXX/type-definition-in-specifier.cpp45
-rw-r--r--test/SemaCXX/type-traits.cpp40
-rw-r--r--test/SemaCXX/typeid-ref.cpp4
-rw-r--r--test/SemaCXX/types_compatible_p.cpp10
-rw-r--r--test/SemaCXX/typo-correction-pt2.cpp117
-rw-r--r--test/SemaCXX/typo-correction.cpp15
-rw-r--r--test/SemaCXX/undefined-inline.cpp8
-rw-r--r--test/SemaCXX/undefined-internal.cpp46
-rw-r--r--test/SemaCXX/underlying_type.cpp14
-rw-r--r--test/SemaCXX/uninit-variables.cpp5
-rw-r--r--test/SemaCXX/uninitialized.cpp2
-rw-r--r--test/SemaCXX/unreachable-code.cpp20
-rw-r--r--test/SemaCXX/using-decl-1.cpp97
-rw-r--r--test/SemaCXX/vararg-class.cpp48
-rw-r--r--test/SemaCXX/vector-casts.cpp47
-rw-r--r--test/SemaCXX/vector.cpp10
-rw-r--r--test/SemaCXX/virtual-base-used.cpp49
-rw-r--r--test/SemaCXX/virtual-override-x86.cpp2
-rw-r--r--test/SemaCXX/virtual-override.cpp3
-rw-r--r--test/SemaCXX/vla.cpp14
-rw-r--r--test/SemaCXX/vtordisp-mode.cpp26
-rw-r--r--test/SemaCXX/warn-absolute-value-header.cpp53
-rw-r--r--test/SemaCXX/warn-absolute-value.cpp823
-rw-r--r--test/SemaCXX/warn-address.cpp20
-rw-r--r--test/SemaCXX/warn-bad-memaccess.cpp29
-rw-r--r--test/SemaCXX/warn-bool-conversion.cpp96
-rw-r--r--test/SemaCXX/warn-consumed-analysis.cpp176
-rw-r--r--test/SemaCXX/warn-consumed-parsing.cpp16
-rw-r--r--test/SemaCXX/warn-exit-time-destructors.cpp20
-rw-r--r--test/SemaCXX/warn-float-conversion.cpp38
-rw-r--r--test/SemaCXX/warn-func-as-bool.cpp40
-rw-r--r--test/SemaCXX/warn-global-constructors.cpp21
-rw-r--r--test/SemaCXX/warn-infinite-recursion.cpp152
-rw-r--r--test/SemaCXX/warn-memsize-comparison.cpp93
-rw-r--r--test/SemaCXX/warn-new-overaligned.cpp4
-rw-r--r--test/SemaCXX/warn-reinterpret-base-class.cpp18
-rw-r--r--test/SemaCXX/warn-self-assign.cpp3
-rw-r--r--test/SemaCXX/warn-shadow.cpp2
-rw-r--r--test/SemaCXX/warn-sign-conversion.cpp32
-rw-r--r--test/SemaCXX/warn-string-conversion.cpp8
-rw-r--r--test/SemaCXX/warn-sysheader-macro.cpp35
-rw-r--r--test/SemaCXX/warn-tautological-compare.cpp138
-rw-r--r--test/SemaCXX/warn-tautological-undefined-compare.cpp112
-rw-r--r--test/SemaCXX/warn-thread-safety-analysis.cpp670
-rw-r--r--test/SemaCXX/warn-thread-safety-parsing.cpp216
-rw-r--r--test/SemaCXX/warn-undefined-bool-conversion.cpp97
-rw-r--r--test/SemaCXX/warn-unreachable.cpp302
-rw-r--r--test/SemaCXX/warn-unused-attribute.cpp28
-rw-r--r--test/SemaCXX/warn-unused-comparison.cpp41
-rw-r--r--test/SemaCXX/warn-unused-filescoped.cpp15
-rw-r--r--test/SemaCXX/warn-unused-label-error.cpp26
-rw-r--r--test/SemaCXX/warn-unused-value.cpp2
-rw-r--r--test/SemaCXX/warn-unused-variables.cpp47
-rw-r--r--test/SemaCXX/warn-weak-vtables.cpp3
-rw-r--r--test/SemaCXX/windows-arm-valist.cpp17
-rw-r--r--test/SemaCXX/writable-strings-deprecated.cpp13
210 files changed, 8594 insertions, 1004 deletions
diff --git a/test/SemaCXX/MicrosoftCompatibility.cpp b/test/SemaCXX/MicrosoftCompatibility.cpp
index 05037ac6a0d03..fb7d9751d1a5a 100644
--- a/test/SemaCXX/MicrosoftCompatibility.cpp
+++ b/test/SemaCXX/MicrosoftCompatibility.cpp
@@ -3,6 +3,7 @@
typedef unsigned short char16_t;
typedef unsigned int char32_t;
+struct _Atomic {};
typename decltype(3) a; // expected-warning {{expected a qualified name after 'typename'}}
@@ -21,6 +22,12 @@ void test()
}
+namespace ms_predefined_types {
+ // ::type_info is a built-in forward class declaration.
+ void f(const type_info &a);
+ void f(size_t);
+}
+
namespace ms_protected_scope {
struct C { C(); };
@@ -105,6 +112,9 @@ public:
class B : public A {
private:
using A::f;
+ void g() {
+ f(); // no diagnostic
+ }
};
class C : public B {
@@ -114,6 +124,27 @@ private:
}
+namespace using_tag_redeclaration
+{
+ struct S;
+ namespace N {
+ using ::using_tag_redeclaration::S;
+ struct S {}; // expected-note {{previous definition is here}}
+ }
+ void f() {
+ N::S s1;
+ S s2;
+ }
+ void g() {
+ struct S; // expected-note {{forward declaration of 'S'}}
+ S s3; // expected-error {{variable has incomplete type 'S'}}
+ }
+ void h() {
+ using ::using_tag_redeclaration::S;
+ struct S {}; // expected-error {{redefinition of 'S'}}
+ }
+}
+
namespace MissingTypename {
diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp
index c5b45a2905c8b..6d221a409e7bc 100644
--- a/test/SemaCXX/MicrosoftExtensions.cpp
+++ b/test/SemaCXX/MicrosoftExtensions.cpp
@@ -1,10 +1,6 @@
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify -fms-extensions -fexceptions -fcxx-exceptions
-// ::type_info is predeclared with forward class declartion
-void f(const type_info &a);
-
-
// Microsoft doesn't validate exception specification.
namespace microsoft_exception_spec {
@@ -37,11 +33,11 @@ class B : public A {
// MSVC allows type definition in anonymous union and struct
struct A
{
- union
+ union
{
int a;
struct B // expected-warning {{types declared in an anonymous union are a Microsoft extension}}
- {
+ {
int c;
} d;
@@ -63,7 +59,7 @@ struct A
{
int c2;
} d2;
-
+
union C2 // expected-warning {{types declared in an anonymous struct are a Microsoft extension}}
{
int e2;
@@ -78,7 +74,7 @@ struct A
// __stdcall handling
struct M {
int __stdcall addP();
- float __stdcall subtractP();
+ float __stdcall subtractP();
};
// __unaligned handling
@@ -90,7 +86,7 @@ template<typename T> void h1(T (__stdcall M::* const )()) { }
void m1() {
h1<int>(&M::addP);
h1(&M::subtractP);
-}
+}
@@ -98,7 +94,7 @@ void m1() {
void f(long long);
void f(int);
-
+
int main()
{
// This is an ambiguous call in standard C++.
@@ -123,10 +119,11 @@ enum : long long { // expected-warning{{enumeration types with a fixed underlyi
class AAA {
__declspec(dllimport) void f(void) { }
-void f2(void);
+void f2(void); // expected-note{{previous declaration is here}}
};
-__declspec(dllimport) void AAA::f2(void) { // expected-error {{dllimport attribute can be applied only to symbol}}
+__declspec(dllimport) void AAA::f2(void) { // expected-error{{dllimport cannot be applied to non-inline function definition}}
+ // expected-error@-1{{redeclaration of 'AAA::f2' cannot add 'dllimport' attribute}}
}
@@ -147,11 +144,14 @@ extern void static_func();
void static_func(); // expected-note {{previous declaration is here}}
-static void static_func() // expected-warning {{static declaration of 'static_func' follows non-static declaration}}
+static void static_func() // expected-warning {{redeclaring non-static 'static_func' as static is a Microsoft extension}}
{
}
+extern const int static_var; // expected-note {{previous declaration is here}}
+static const int static_var = 3; // expected-warning {{redeclaring non-static 'static_var' as static is a Microsoft extension}}
+
long function_prototype(int a);
long (*function_ptr)(int a);
@@ -176,29 +176,6 @@ void pointer_to_integral_type_conv(char* ptr) {
b = reinterpret_cast<bool>(ptr); // expected-error {{cast from pointer to smaller type 'bool' loses information}}
}
-namespace friend_as_a_forward_decl {
-
-class A {
- class Nested {
- friend class B;
- B* b;
- };
- B* b;
-};
-B* global_b;
-
-
-void f()
-{
- class Local {
- friend class Z;
- Z* b;
- };
- Z* b;
-}
-
-}
-
struct PR11150 {
class X {
virtual void f() = 0;
@@ -307,7 +284,7 @@ struct SP9 {
__declspec(property(get=GetV, put=SetV)) T V;
T GetV() { return 0; }
void SetV(T v) {}
- void f() { V = this->V; V < this->V; }
+ bool f() { V = this->V; return V < this->V; }
void g() { V++; }
void h() { V*=2; }
};
@@ -368,18 +345,18 @@ struct StructWithUnnamedMember {
namespace rdar14250378 {
class Bar {};
-
+
namespace NyNamespace {
class Foo {
public:
Bar* EnsureBar();
};
-
+
class Baz : public Foo {
public:
friend class Bar;
};
-
+
Bar* Foo::EnsureBar() {
return 0;
}
@@ -410,3 +387,14 @@ struct SealedType sealed : SomeBase {
// expected-error@+1 {{base 'SealedType' is marked 'sealed'}}
struct InheritFromSealed : SealedType {};
+
+void AfterClassBody() {
+ // expected-warning@+1 {{attribute 'deprecated' is ignored, place it after "struct" to apply attribute to type declaration}}
+ struct D {} __declspec(deprecated);
+
+ struct __declspec(align(4)) S {} __declspec(align(8)) s1;
+ S s2;
+ _Static_assert(__alignof(S) == 4, "");
+ _Static_assert(__alignof(s1) == 8, "");
+ _Static_assert(__alignof(s2) == 4, "");
+}
diff --git a/test/SemaCXX/PR19955.cpp b/test/SemaCXX/PR19955.cpp
new file mode 100644
index 0000000000000..cbbe2fe9af164
--- /dev/null
+++ b/test/SemaCXX/PR19955.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple i686-win32 -verify -std=c++11 %s
+// RUN: %clang_cc1 -triple i686-mingw32 -verify -std=c++11 %s
+
+extern int __attribute__((dllimport)) var;
+constexpr int *varp = &var; // expected-error {{must be initialized by a constant expression}}
+
+extern __attribute__((dllimport)) void fun();
+constexpr void (*funp)(void) = &fun; // expected-error {{must be initialized by a constant expression}}
+
+template <void (*)()>
+struct S {};
+S<&fun> x;
+
+template <int *>
+struct U {};
+U<&var> y;
diff --git a/test/SemaCXX/PR20110.cpp b/test/SemaCXX/PR20110.cpp
new file mode 100644
index 0000000000000..e540a738b87b6
--- /dev/null
+++ b/test/SemaCXX/PR20110.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// expected-no-diagnostics
+
+// FIXME: These templates should trigger errors in C++11 mode.
+
+template <char const *p>
+class A {
+ char const *get_p() { return *p; }
+};
+template <int p>
+class B {
+ char const *get_p() { return p; }
+};
+
diff --git a/test/SemaCXX/PR8012.cpp b/test/SemaCXX/PR8012.cpp
index 9cfc2b000c014..0a43af7c297cd 100644
--- a/test/SemaCXX/PR8012.cpp
+++ b/test/SemaCXX/PR8012.cpp
@@ -1,3 +1,3 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
-void foo (int operator+); // expected-error{{cannot be the name of a parameter}}
+void foo(int operator+); // expected-error{{'operator+' cannot be the name of a parameter}}
diff --git a/test/SemaCXX/__try.cpp b/test/SemaCXX/__try.cpp
index 1c45581b32f9d..28a3701488785 100644
--- a/test/SemaCXX/__try.cpp
+++ b/test/SemaCXX/__try.cpp
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -verify -fborland-extensions -fcxx-exceptions %s
-// expected-no-diagnostics
// This test is from http://docwiki.embarcadero.com/RADStudio/en/Try
@@ -77,3 +76,14 @@ template void Except<void>();
template void Finally<void>();
}
+
+void test___leave() {
+ // Most tests are in __try.c.
+
+ // Clang accepts try with __finally. MSVC doesn't. (Maybe a Borland thing?)
+ // __leave in mixed blocks isn't supported.
+ try {
+ __leave; // expected-error{{'__leave' statement not in __try block}}
+ } __finally {
+ }
+}
diff --git a/test/SemaCXX/abstract.cpp b/test/SemaCXX/abstract.cpp
index d7e2d0a3dcf9a..b521196c23b65 100644
--- a/test/SemaCXX/abstract.cpp
+++ b/test/SemaCXX/abstract.cpp
@@ -268,16 +268,16 @@ namespace pr9247 {
}
namespace pr12658 {
- class C {
- public:
- C(int v){}
- virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'C'}}
- };
-
- void foo( C& c ) {}
-
- void bar( void ) {
- foo(C(99)); // expected-error {{allocating an object of abstract class type 'pr12658::C'}}
+ class C {
+ public:
+ C(int v){}
+ virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'C'}}
+ };
+
+ void foo( C& c ) {}
+
+ void bar( void ) {
+ foo(C(99)); // expected-error {{allocating an object of abstract class type 'pr12658::C'}}
}
}
diff --git a/test/SemaCXX/access.cpp b/test/SemaCXX/access.cpp
index 5ccd418c1b767..5fa1509c53021 100644
--- a/test/SemaCXX/access.cpp
+++ b/test/SemaCXX/access.cpp
@@ -136,3 +136,25 @@ namespace PR7434 {
};
}
}
+
+namespace LocalExternVar {
+ class test {
+ private:
+ struct private_struct { // expected-note 2{{here}}
+ int x;
+ };
+ int use_private();
+ };
+
+ int test::use_private() {
+ extern int array[sizeof(test::private_struct)]; // ok
+ return array[0];
+ }
+
+ int f() {
+ extern int array[sizeof(test::private_struct)]; // expected-error {{private}}
+ return array[0];
+ }
+
+ int array[sizeof(test::private_struct)]; // expected-error {{private}}
+}
diff --git a/test/SemaCXX/addr-of-overloaded-function-casting.cpp b/test/SemaCXX/addr-of-overloaded-function-casting.cpp
index 784c8a0007445..edf4c138a8402 100644
--- a/test/SemaCXX/addr-of-overloaded-function-casting.cpp
+++ b/test/SemaCXX/addr-of-overloaded-function-casting.cpp
@@ -1,8 +1,8 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
void g();
-void f(); // expected-note 9{{candidate function}}
-void f(int); // expected-note 9{{candidate function}}
+void f(); // expected-note 11{{candidate function}}
+void f(int); // expected-note 11{{candidate function}}
template <class T>
void t(T); // expected-note 3{{candidate function}} \
@@ -58,4 +58,13 @@ int main()
{ bool b = static_cast<int (&)(char)>(t); } // expected-error{{does not match required}}
{ bool b = static_cast<void (&)(char)>(f); } // expected-error{{does not match}}
+
+ {
+ // The error should be reported when casting overloaded function to the
+ // compatible function type (not to be confused with function pointer or
+ // function reference type.)
+ typedef void (FnType)(int);
+ FnType a = static_cast<FnType>(f); // expected-error{{address of overloaded function}}
+ FnType b = (FnType)(f); // expected-error{{address of overloaded function}}
+ }
}
diff --git a/test/SemaCXX/addr-of-overloaded-function.cpp b/test/SemaCXX/addr-of-overloaded-function.cpp
index 230a1eb994e19..358fe8d5b08e5 100644
--- a/test/SemaCXX/addr-of-overloaded-function.cpp
+++ b/test/SemaCXX/addr-of-overloaded-function.cpp
@@ -84,7 +84,7 @@ struct C {
void h() {
// Do not suggest '()' since an int argument is required
- q1<int>; // expected-error-re{{reference to non-static member function must be called$}}
+ q1<int>; // expected-error-re{{reference to non-static member function must be called{{$}}}}
// Suggest '()' since there's a default value for the only argument & the
// type argument is already provided
q2<int>; // expected-error{{reference to non-static member function must be called; did you mean to call it with no arguments?}}
@@ -92,7 +92,7 @@ struct C {
// already provided
q3<int>; // expected-error{{reference to non-static member function must be called; did you mean to call it with no arguments?}}
// Do not suggest '()' since another type argument is required
- q4<int>; // expected-error-re{{reference to non-static member function must be called$}}
+ q4<int>; // expected-error-re{{reference to non-static member function must be called{{$}}}}
// Suggest '()' since the type parameter has a default value
q5; // expected-error{{reference to non-static member function must be called; did you mean to call it with no arguments?}}
}
@@ -220,20 +220,20 @@ namespace test1 {
void QualifierTest() {
void (Qualifiers::*X)();
- X = &Qualifiers::C; // expected-error {{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() const': different qualifiers (none vs const)}}
- X = &Qualifiers::V; // expected-error{{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() volatile': different qualifiers (none vs volatile)}}
- X = &Qualifiers::R; // expected-error{{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() restrict': different qualifiers (none vs restrict)}}
- X = &Qualifiers::CV; // expected-error{{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() const volatile': different qualifiers (none vs const and volatile)}}
- X = &Qualifiers::CR; // expected-error{{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() const restrict': different qualifiers (none vs const and restrict)}}
- X = &Qualifiers::VR; // expected-error{{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() volatile restrict': different qualifiers (none vs volatile and restrict)}}
- X = &Qualifiers::CVR; // expected-error{{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() const volatile restrict': different qualifiers (none vs const, volatile, and restrict)}}
+ X = &Qualifiers::C; // expected-error-re {{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const': different qualifiers (none vs const)}}
+ X = &Qualifiers::V; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile': different qualifiers (none vs volatile)}}
+ X = &Qualifiers::R; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} restrict': different qualifiers (none vs restrict)}}
+ X = &Qualifiers::CV; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile': different qualifiers (none vs const and volatile)}}
+ X = &Qualifiers::CR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const restrict': different qualifiers (none vs const and restrict)}}
+ X = &Qualifiers::VR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile restrict': different qualifiers (none vs volatile and restrict)}}
+ X = &Qualifiers::CVR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile restrict': different qualifiers (none vs const, volatile, and restrict)}}
}
struct Dummy {
void N() {};
};
- void (Qualifiers::*X)() = &Dummy::N; // expected-error{{cannot initialize a variable of type 'void (test1::Qualifiers::*)()' with an rvalue of type 'void (test1::Dummy::*)()': different classes ('test1::Qualifiers' vs 'test1::Dummy')}}
+ void (Qualifiers::*X)() = &Dummy::N; // expected-error-re{{cannot initialize a variable of type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' with an rvalue of type 'void (test1::Dummy::*)(){{( __attribute__\(\(thiscall\)\))?}}': different classes ('test1::Qualifiers' vs 'test1::Dummy')}}
}
template <typename T> class PR16561 {
diff --git a/test/SemaCXX/aggregate-initialization.cpp b/test/SemaCXX/aggregate-initialization.cpp
index 885bf703dc108..4e4177463f885 100644
--- a/test/SemaCXX/aggregate-initialization.cpp
+++ b/test/SemaCXX/aggregate-initialization.cpp
@@ -49,7 +49,7 @@ struct A {
A(int);
~A();
- A(const A&) = delete; // expected-note 2 {{function has been explicitly marked deleted here}}
+ A(const A&) = delete; // expected-note 2 {{'A' has been explicitly marked deleted here}}
};
struct B {
diff --git a/test/SemaCXX/alias-template.cpp b/test/SemaCXX/alias-template.cpp
index db9c82afd5985..89efc501d82ce 100644
--- a/test/SemaCXX/alias-template.cpp
+++ b/test/SemaCXX/alias-template.cpp
@@ -102,10 +102,10 @@ class CtorDtorName {
};
namespace TagName {
- template<typename Z> using S = struct { int n; }; // expected-error {{can not be defined}}
- template<typename Z> using T = class { int n; }; // expected-error {{can not be defined}}
- template<typename Z> using U = enum { a, b, c }; // expected-error {{can not be defined}}
- template<typename Z> using V = struct V { int n; }; // expected-error {{'TagName::V' can not be defined in a type alias template}}
+ template<typename Z> using S = struct { int n; }; // expected-error {{cannot be defined}}
+ template<typename Z> using T = class { int n; }; // expected-error {{cannot be defined}}
+ template<typename Z> using U = enum { a, b, c }; // expected-error {{cannot be defined}}
+ template<typename Z> using V = struct V { int n; }; // expected-error {{'TagName::V' cannot be defined in a type alias template}}
}
namespace StdExample {
@@ -136,7 +136,7 @@ namespace Access {
namespace VoidArg {
template<typename Z> using V = void;
V<int> f(int); // ok
- V<char> g(V<double>); // expected-error {{empty parameter list defined with a type alias of 'void' not allowed}}
+ V<char> g(V<double>); // ok (DR577)
}
namespace Curried {
diff --git a/test/SemaCXX/alignof.cpp b/test/SemaCXX/alignof.cpp
index f0b89eef656dc..011f459abdf2d 100644
--- a/test/SemaCXX/alignof.cpp
+++ b/test/SemaCXX/alignof.cpp
@@ -62,3 +62,18 @@ const int test8 = __alignof__(S5::x);
long long int test14[2];
static_assert(alignof(test14) == 8, "foo"); // expected-warning {{'alignof' applied to an expression is a GNU extension}}
+
+// PR19992
+static_assert(alignof(int[]) == alignof(int), ""); // ok
+
+namespace alignof_array_expr {
+ alignas(32) extern int n[];
+ static_assert(alignof(n) == 32, ""); // expected-warning {{GNU extension}}
+
+ template<int> struct S {
+ static int a[];
+ };
+ template<int N> int S<N>::a[N];
+ // ok, does not complete type of S<-1>::a
+ static_assert(alignof(S<-1>::a) == alignof(int), ""); // expected-warning {{GNU extension}}
+}
diff --git a/test/SemaCXX/anonymous-struct.cpp b/test/SemaCXX/anonymous-struct.cpp
index 8a61041463bae..1b5dc13cea015 100644
--- a/test/SemaCXX/anonymous-struct.cpp
+++ b/test/SemaCXX/anonymous-struct.cpp
@@ -14,3 +14,10 @@ struct E {
static struct {
};
};
+
+template <class T> void foo(T);
+typedef struct { // expected-note {{use a tag name here to establish linkage prior to definition}} expected-note {{declared here}}
+ void test() {
+ foo(this); // expected-warning {{template argument uses unnamed type}}
+ }
+} A; // expected-error {{unsupported: typedef changes linkage of anonymous type, but linkage was already computed}}
diff --git a/test/SemaCXX/anonymous-union-cxx11.cpp b/test/SemaCXX/anonymous-union-cxx11.cpp
index 9f987a9681cdd..b0dd1a874deb1 100644
--- a/test/SemaCXX/anonymous-union-cxx11.cpp
+++ b/test/SemaCXX/anonymous-union-cxx11.cpp
@@ -12,3 +12,12 @@ namespace PR12866 {
(void)sizeof(bar::member);
}
}
+
+namespace PR20021 {
+class C {
+ union {
+ static_assert(true, "");
+ int i;
+ };
+};
+}
diff --git a/test/SemaCXX/ast-print.cpp b/test/SemaCXX/ast-print.cpp
index a1975b4ac2644..4851571283f4a 100644
--- a/test/SemaCXX/ast-print.cpp
+++ b/test/SemaCXX/ast-print.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -ast-print %s -std=gnu++11 | FileCheck %s
// CHECK: r;
// CHECK-NEXT: (r->method());
@@ -164,3 +164,47 @@ void test13() {
void test14() {
struct X { union { int x; } x; };
}
+
+
+// CHECK: float test15() {
+// CHECK: return __builtin_asinf(1.F);
+// CHECK: }
+// CHECK-NOT: extern "C"
+float test15() {
+ return __builtin_asinf(1.0F);
+}
+
+namespace PR18776 {
+struct A {
+ operator void *();
+ explicit operator bool();
+ A operator&(A);
+};
+
+// CHECK: struct A
+// CHECK-NEXT: {{^[ ]*operator}} void *();
+// CHECK-NEXT: {{^[ ]*explicit}} operator bool();
+
+void bar(void *);
+
+void foo() {
+ A a, b;
+ bar(a & b);
+// CHECK: bar(a & b);
+ if (a & b)
+// CHECK: if (a & b)
+ return;
+}
+};
+
+namespace {
+void test(int i) {
+ switch (i) {
+ case 1:
+ // CHECK: {{\[\[clang::fallthrough\]\]}}
+ [[clang::fallthrough]];
+ case 2:
+ break;
+ }
+}
+}
diff --git a/test/SemaCXX/atomic-type.cxx b/test/SemaCXX/atomic-type.cpp
index 947bb3c5f406d..ae18eab5b4a90 100644
--- a/test/SemaCXX/atomic-type.cxx
+++ b/test/SemaCXX/atomic-type.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -verify -pedantic %s
+// RUN: %clang_cc1 -verify -pedantic %s -std=c++98
+// RUN: %clang_cc1 -verify -pedantic %s -std=c++11
template<typename T> struct atomic {
_Atomic(T) value;
@@ -48,7 +49,7 @@ typedef _Atomic int(A::*mem_ptr_to_atomic_int);
typedef _Atomic(int)&atomic_int_ref;
typedef _Atomic int &atomic_int_ref;
-typedef _Atomic atomic_int_ref atomic_int_ref; // ok, qualifiers on references ignored in this case.
+typedef _Atomic atomic_int_ref atomic_int_ref; // expected-warning {{'_Atomic' qualifier on reference type 'atomic_int_ref' (aka '_Atomic(int) &') has no effect}}
typedef int &_Atomic atomic_reference_to_int; // expected-error {{'_Atomic' qualifier may not be applied to a reference}}
typedef _Atomic(int &) atomic_reference_to_int; // expected-error {{_Atomic cannot be applied to reference type 'int &'}}
@@ -56,3 +57,29 @@ typedef _Atomic(int &) atomic_reference_to_int; // expected-error {{_Atomic cann
struct S {
_Atomic union { int n; }; // expected-warning {{anonymous union cannot be '_Atomic'}}
};
+
+namespace copy_init {
+ struct X {
+ X(int);
+ int n;
+ };
+ _Atomic(X) y = X(0);
+ _Atomic(X) z(X(0));
+ void f() { y = X(0); }
+
+ _Atomic(X) e1(0); // expected-error {{cannot initialize}}
+#if __cplusplus >= 201103L
+ _Atomic(X) e2{0}; // expected-error {{illegal initializer}}
+ _Atomic(X) a{X(0)};
+#endif
+
+ struct Y {
+ _Atomic(X) a;
+ _Atomic(int) b;
+ };
+ Y y1 = { X(0), 4 };
+ Y y2 = { 0, 4 }; // expected-error {{cannot initialize}}
+ // FIXME: It's not really clear if we should allow these. Generally, C++11
+ // allows extraneous braces around initializers.
+ Y y3 = { { X(0) }, { 4 } }; // expected-error 2{{illegal initializer type}}
+}
diff --git a/test/SemaCXX/attr-common.cpp b/test/SemaCXX/attr-common.cpp
index 58b30133f52f1..fb98639d1b2ce 100644
--- a/test/SemaCXX/attr-common.cpp
+++ b/test/SemaCXX/attr-common.cpp
@@ -1,3 +1,3 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-__attribute__((common)) int x; // expected-error {{common attribute is not supported in C++}}
+__attribute__((common)) int x; // expected-error {{'common' attribute is not supported in C++}}
diff --git a/test/SemaCXX/attr-cxx0x.cpp b/test/SemaCXX/attr-cxx0x.cpp
index e24e12e50c4e4..6ba89a62d70de 100644
--- a/test/SemaCXX/attr-cxx0x.cpp
+++ b/test/SemaCXX/attr-cxx0x.cpp
@@ -45,3 +45,8 @@ static_assert(alignof(align_class_temp_pack_expr<8, 16, 32>) == 32, "template's
static_assert(alignof(outer<int,char>::inner<double,short>) == alignof(int) * alignof(double), "template's alignment is wrong");
static_assert(alignof(int(int)) >= 1, "alignof(function) not positive"); // expected-error{{invalid application of 'alignof' to a function type}}
+
+[[__carries_dependency__]] // expected-warning{{unknown attribute '__carries_dependency__' ignored}}
+void func(void);
+
+alignas(4) auto PR19252 = 0;
diff --git a/test/SemaCXX/attr-deprecated.cpp b/test/SemaCXX/attr-deprecated.cpp
index b3223f399799f..d28eb75cca657 100644
--- a/test/SemaCXX/attr-deprecated.cpp
+++ b/test/SemaCXX/attr-deprecated.cpp
@@ -1,10 +1,10 @@
// RUN: %clang_cc1 %s -verify -fexceptions
class A {
- void f() __attribute__((deprecated)); // expected-note 2 {{declared here}}
+ void f() __attribute__((deprecated)); // expected-note 2 {{'f' has been explicitly marked deprecated here}}
void g(A* a);
void h(A* a) __attribute__((deprecated));
- int b __attribute__((deprecated)); // expected-note 2 {{declared here}}
+ int b __attribute__((deprecated)); // expected-note 2 {{'b' has been explicitly marked deprecated here}}
};
void A::g(A* a)
@@ -26,7 +26,7 @@ void A::h(A* a)
}
struct B {
- virtual void f() __attribute__((deprecated)); // expected-note 4 {{declared here}}
+ virtual void f() __attribute__((deprecated)); // expected-note 4 {{'f' has been explicitly marked deprecated here}}
void g();
};
@@ -68,20 +68,20 @@ void f(D* d) {
// Overloaded namespace members.
namespace test1 {
- void foo(int) __attribute__((deprecated)); // expected-note {{declared here}}
+ void foo(int) __attribute__((deprecated)); // expected-note {{'foo' has been explicitly marked deprecated here}}
void test1() { foo(10); } // expected-warning {{deprecated}}
- void foo(short) __attribute__((deprecated)); // expected-note {{declared here}}
+ void foo(short) __attribute__((deprecated)); // expected-note {{'foo' has been explicitly marked deprecated here}}
void test2(short s) { foo(s); } // expected-warning {{deprecated}}
void foo(long);
void test3(long l) { foo(l); }
struct A {
- friend void foo(A*) __attribute__((deprecated)); // expected-note {{declared here}}
+ friend void foo(A*) __attribute__((deprecated)); // expected-note {{'foo' has been explicitly marked deprecated here}}
};
void test4(A *a) { foo(a); } // expected-warning {{deprecated}}
namespace ns {
struct Foo {};
- void foo(const Foo &f) __attribute__((deprecated)); // expected-note {{declared here}}
+ void foo(const Foo &f) __attribute__((deprecated)); // expected-note {{'foo' has been explicitly marked deprecated here}}
}
void test5() {
foo(ns::Foo()); // expected-warning {{deprecated}}
@@ -91,9 +91,9 @@ namespace test1 {
// Overloaded class members.
namespace test2 {
struct A {
- void foo(int) __attribute__((deprecated)); // expected-note 2 {{declared here}}
+ void foo(int) __attribute__((deprecated)); // expected-note 2 {{'foo' has been explicitly marked deprecated here}}
void foo(long);
- static void bar(int) __attribute__((deprecated)); // expected-note 3 {{declared here}}
+ static void bar(int) __attribute__((deprecated)); // expected-note 3 {{'bar' has been explicitly marked deprecated here}}
static void bar(long);
void test2(int i, long l);
@@ -120,12 +120,12 @@ namespace test2 {
namespace test3 {
struct A {
void operator*(const A &);
- void operator*(int) __attribute__((deprecated)); // expected-note {{declared here}}
+ void operator*(int) __attribute__((deprecated)); // expected-note {{'operator*' has been explicitly marked deprecated here}}
void operator-(const A &) const;
};
void operator+(const A &, const A &);
- void operator+(const A &, int) __attribute__((deprecated)); // expected-note {{declared here}}
- void operator-(const A &, int) __attribute__((deprecated)); // expected-note {{declared here}}
+ void operator+(const A &, int) __attribute__((deprecated)); // expected-note {{'operator+' has been explicitly marked deprecated here}}
+ void operator-(const A &, int) __attribute__((deprecated)); // expected-note {{'operator-' has been explicitly marked deprecated here}}
void test() {
A a, b;
@@ -143,9 +143,9 @@ namespace test4 {
struct A {
typedef void (*intfn)(int);
typedef void (*unintfn)(unsigned);
- operator intfn() __attribute__((deprecated)); // expected-note {{declared here}}
+ operator intfn() __attribute__((deprecated)); // expected-note {{'operator void (*)(int)' has been explicitly marked deprecated here}}
operator unintfn();
- void operator ()(A &) __attribute__((deprecated)); // expected-note {{declared here}}
+ void operator ()(A &) __attribute__((deprecated)); // expected-note {{'operator()' has been explicitly marked deprecated here}}
void operator ()(const A &);
};
@@ -163,7 +163,7 @@ namespace test4 {
namespace test5 {
struct A {
- operator int() __attribute__((deprecated)); // expected-note 3 {{declared here}}
+ operator int() __attribute__((deprecated)); // expected-note 3 {{'operator int' has been explicitly marked deprecated here}}
operator long();
};
void test1(A a) {
@@ -193,8 +193,8 @@ namespace test5 {
// rdar://problem/8518751
namespace test6 {
- enum __attribute__((deprecated)) A { // expected-note {{declared here}}
- a0 // expected-note {{declared here}}
+ enum __attribute__((deprecated)) A { // expected-note {{'A' has been explicitly marked deprecated here}}
+ a0 // expected-note {{'a0' has been explicitly marked deprecated here}}
};
void testA() {
A x; // expected-warning {{'A' is deprecated}}
@@ -202,7 +202,7 @@ namespace test6 {
}
enum B {
- b0 __attribute__((deprecated)), // expected-note {{declared here}}
+ b0 __attribute__((deprecated)), // expected-note {{'b0' has been explicitly marked deprecated here}}
b1
};
void testB() {
@@ -212,8 +212,8 @@ namespace test6 {
}
template <class T> struct C {
- enum __attribute__((deprecated)) Enum { // expected-note {{declared here}}
- c0 // expected-note {{declared here}}
+ enum __attribute__((deprecated)) Enum { // expected-note {{'Enum' has been explicitly marked deprecated here}}
+ c0 // expected-note {{'c0' has been explicitly marked deprecated here}}
};
};
void testC() {
@@ -224,7 +224,7 @@ namespace test6 {
template <class T> struct D {
enum Enum {
d0,
- d1 __attribute__((deprecated)), // expected-note {{declared here}}
+ d1 __attribute__((deprecated)), // expected-note {{'d1' has been explicitly marked deprecated here}}
};
};
void testD() {
@@ -236,8 +236,8 @@ namespace test6 {
namespace test7 {
struct X {
- void* operator new(typeof(sizeof(void*))) __attribute__((deprecated)); // expected-note{{'operator new' declared here}}
- void operator delete(void *) __attribute__((deprecated)); // expected-note{{'operator delete' declared here}}
+ void* operator new(typeof(sizeof(void*))) __attribute__((deprecated)); // expected-note{{'operator new' has been explicitly marked deprecated here}}
+ void operator delete(void *) __attribute__((deprecated)); // expected-note{{'operator delete' has been explicitly marked deprecated here}}
};
void test() {
@@ -247,6 +247,6 @@ namespace test7 {
// rdar://problem/15044218
typedef struct TDS {
-} TDS __attribute__((deprecated)); // expected-note {{'TDS' declared here}}
+} TDS __attribute__((deprecated)); // expected-note {{'TDS' has been explicitly marked deprecated here}}
TDS tds; // expected-warning {{'TDS' is deprecated}}
struct TDS tds2; // no warning, attribute only applies to the typedef.
diff --git a/test/SemaCXX/attr-flatten.cpp b/test/SemaCXX/attr-flatten.cpp
new file mode 100644
index 0000000000000..afcba72b6429e
--- /dev/null
+++ b/test/SemaCXX/attr-flatten.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+int i __attribute__((flatten)); // expected-error {{'flatten' attribute only applies to functions}}
+
+void f1() __attribute__((flatten));
+void f2() __attribute__((flatten(1))); // expected-error {{'flatten' attribute takes no arguments}}
+
+template <typename T>
+void tf1() __attribute__((flatten));
+
+int f3(int __attribute__((flatten)), int); // expected-error{{'flatten' attribute only applies to functions}}
+
+struct A {
+ int f __attribute__((flatten)); // expected-error{{'flatten' attribute only applies to functions}}
+ void mf1() __attribute__((flatten));
+ static void mf2() __attribute__((flatten));
+};
+
+int ci [[gnu::flatten]]; // expected-error {{'flatten' attribute only applies to functions}}
+
+[[gnu::flatten]] void cf1();
+[[gnu::flatten(1)]] void cf2(); // expected-error {{'flatten' attribute takes no arguments}}
+
+template <typename T>
+[[gnu::flatten]]
+void ctf1();
+
+int cf3(int c[[gnu::flatten]], int); // expected-error{{'flatten' attribute only applies to functions}}
+
+struct CA {
+ int f [[gnu::flatten]]; // expected-error{{'flatten' attribute only applies to functions}}
+ [[gnu::flatten]] void mf1();
+ [[gnu::flatten]] static void mf2();
+};
diff --git a/test/SemaCXX/attr-no-sanitize-address.cpp b/test/SemaCXX/attr-no-sanitize-address.cpp
index f1803496fa55c..9ca28630552bc 100644
--- a/test/SemaCXX/attr-no-sanitize-address.cpp
+++ b/test/SemaCXX/attr-no-sanitize-address.cpp
@@ -15,23 +15,23 @@ int noanal_testfn(int y) NO_SANITIZE_ADDRESS;
int noanal_testfn(int y) {
int x NO_SANITIZE_ADDRESS = y; // \
- // expected-error {{'no_sanitize_address' attribute only applies to functions and methods}}
+ // expected-error {{'no_sanitize_address' attribute only applies to functions}}
return x;
}
int noanal_test_var NO_SANITIZE_ADDRESS; // \
- // expected-error {{'no_sanitize_address' attribute only applies to functions and methods}}
+ // expected-error {{'no_sanitize_address' attribute only applies to functions}}
class NoanalFoo {
private:
int test_field NO_SANITIZE_ADDRESS; // \
- // expected-error {{'no_sanitize_address' attribute only applies to functions and methods}}
+ // expected-error {{'no_sanitize_address' attribute only applies to functions}}
void test_method() NO_SANITIZE_ADDRESS;
};
class NO_SANITIZE_ADDRESS NoanalTestClass { // \
- // expected-error {{'no_sanitize_address' attribute only applies to functions and methods}}
+ // expected-error {{'no_sanitize_address' attribute only applies to functions}}
};
void noanal_fun_params(int lvar NO_SANITIZE_ADDRESS); // \
- // expected-error {{'no_sanitize_address' attribute only applies to functions and methods}}
+ // expected-error {{'no_sanitize_address' attribute only applies to functions}}
diff --git a/test/SemaCXX/attr-no-sanitize-memory.cpp b/test/SemaCXX/attr-no-sanitize-memory.cpp
index d6eca1b69dc17..9cbcb03d6ecf1 100644
--- a/test/SemaCXX/attr-no-sanitize-memory.cpp
+++ b/test/SemaCXX/attr-no-sanitize-memory.cpp
@@ -15,23 +15,23 @@ int noanal_testfn(int y) NO_SANITIZE_MEMORY;
int noanal_testfn(int y) {
int x NO_SANITIZE_MEMORY = y; // \
- // expected-error {{'no_sanitize_memory' attribute only applies to functions and methods}}
+ // expected-error {{'no_sanitize_memory' attribute only applies to functions}}
return x;
}
int noanal_test_var NO_SANITIZE_MEMORY; // \
- // expected-error {{'no_sanitize_memory' attribute only applies to functions and methods}}
+ // expected-error {{'no_sanitize_memory' attribute only applies to functions}}
class NoanalFoo {
private:
int test_field NO_SANITIZE_MEMORY; // \
- // expected-error {{'no_sanitize_memory' attribute only applies to functions and methods}}
+ // expected-error {{'no_sanitize_memory' attribute only applies to functions}}
void test_method() NO_SANITIZE_MEMORY;
};
class NO_SANITIZE_MEMORY NoanalTestClass { // \
- // expected-error {{'no_sanitize_memory' attribute only applies to functions and methods}}
+ // expected-error {{'no_sanitize_memory' attribute only applies to functions}}
};
void noanal_fun_params(int lvar NO_SANITIZE_MEMORY); // \
- // expected-error {{'no_sanitize_memory' attribute only applies to functions and methods}}
+ // expected-error {{'no_sanitize_memory' attribute only applies to functions}}
diff --git a/test/SemaCXX/attr-no-sanitize-thread.cpp b/test/SemaCXX/attr-no-sanitize-thread.cpp
index d6372bceff8a3..6cb9c715bf6cc 100644
--- a/test/SemaCXX/attr-no-sanitize-thread.cpp
+++ b/test/SemaCXX/attr-no-sanitize-thread.cpp
@@ -15,23 +15,23 @@ int noanal_testfn(int y) NO_SANITIZE_THREAD;
int noanal_testfn(int y) {
int x NO_SANITIZE_THREAD = y; // \
- // expected-error {{'no_sanitize_thread' attribute only applies to functions and methods}}
+ // expected-error {{'no_sanitize_thread' attribute only applies to functions}}
return x;
}
int noanal_test_var NO_SANITIZE_THREAD; // \
- // expected-error {{'no_sanitize_thread' attribute only applies to functions and methods}}
+ // expected-error {{'no_sanitize_thread' attribute only applies to functions}}
class NoanalFoo {
private:
int test_field NO_SANITIZE_THREAD; // \
- // expected-error {{'no_sanitize_thread' attribute only applies to functions and methods}}
+ // expected-error {{'no_sanitize_thread' attribute only applies to functions}}
void test_method() NO_SANITIZE_THREAD;
};
class NO_SANITIZE_THREAD NoanalTestClass { // \
- // expected-error {{'no_sanitize_thread' attribute only applies to functions and methods}}
+ // expected-error {{'no_sanitize_thread' attribute only applies to functions}}
};
void noanal_fun_params(int lvar NO_SANITIZE_THREAD); // \
- // expected-error {{'no_sanitize_thread' attribute only applies to functions and methods}}
+ // expected-error {{'no_sanitize_thread' attribute only applies to functions}}
diff --git a/test/SemaCXX/attr-no-split-stack.cpp b/test/SemaCXX/attr-no-split-stack.cpp
new file mode 100644
index 0000000000000..3575e9983f41c
--- /dev/null
+++ b/test/SemaCXX/attr-no-split-stack.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+int i __attribute__((no_split_stack)); // expected-error {{'no_split_stack' attribute only applies to functions}}
+
+void f1() __attribute__((no_split_stack));
+void f2() __attribute__((no_split_stack(1))); // expected-error {{'no_split_stack' attribute takes no arguments}}
+
+template <typename T>
+void tf1() __attribute__((no_split_stack));
+
+int f3(int __attribute__((no_split_stack)), int); // expected-error{{'no_split_stack' attribute only applies to functions}}
+
+struct A {
+ int f __attribute__((no_split_stack)); // expected-error{{'no_split_stack' attribute only applies to functions}}
+ void mf1() __attribute__((no_split_stack));
+ static void mf2() __attribute__((no_split_stack));
+};
+
+int ci [[gnu::no_split_stack]]; // expected-error {{'no_split_stack' attribute only applies to functions}}
+
+[[gnu::no_split_stack]] void cf1();
+[[gnu::no_split_stack(1)]] void cf2(); // expected-error {{'no_split_stack' attribute takes no arguments}}
+
+template <typename T>
+[[gnu::no_split_stack]]
+void ctf1();
+
+int cf3(int c[[gnu::no_split_stack]], int); // expected-error{{'no_split_stack' attribute only applies to functions}}
+
+struct CA {
+ int f [[gnu::no_split_stack]]; // expected-error{{'no_split_stack' attribute only applies to functions}}
+ [[gnu::no_split_stack]] void mf1();
+ [[gnu::no_split_stack]] static void mf2();
+};
diff --git a/test/SemaCXX/attr-optnone.cpp b/test/SemaCXX/attr-optnone.cpp
new file mode 100644
index 0000000000000..eaa50004047c4
--- /dev/null
+++ b/test/SemaCXX/attr-optnone.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -verify %s
+
+int foo() __attribute__((optnone));
+int bar() __attribute__((optnone)) __attribute__((noinline));
+
+int baz() __attribute__((always_inline)) __attribute__((optnone)); // expected-error{{'always_inline' and 'optnone' attributes are not compatible}}
+int quz() __attribute__((optnone)) __attribute__((always_inline)); // expected-error{{'optnone' and 'always_inline' attributes are not compatible}}
+
+__forceinline __attribute__((optnone)) int bax(); // expected-error{{'__forceinline' and 'optnone' attributes are not compatible}}
+__attribute__((optnone)) __forceinline int qux(); // expected-error{{'optnone' and '__forceinline' attributes are not compatible}}
+
+int globalVar __attribute__((optnone)); // expected-warning{{'optnone' attribute only applies to functions}}
+
+int fubar(int __attribute__((optnone)), int); // expected-warning{{'optnone' attribute only applies to functions}}
+
+struct A {
+ int aField __attribute__((optnone)); // expected-warning{{'optnone' attribute only applies to functions}}
+};
+
+struct B {
+ void foo() __attribute__((optnone));
+ static void bar() __attribute__((optnone));
+};
+
+// Verify that we can specify the [[clang::optnone]] syntax as well.
+
+[[clang::optnone]]
+int foo2();
+[[clang::optnone]]
+int bar2() __attribute__((noinline));
+
+[[clang::optnone]]
+int baz2() __attribute__((always_inline)); // expected-error{{'always_inline' and 'optnone' attributes are not compatible}}
+
+[[clang::optnone]] int globalVar2; //expected-warning{{'optnone' attribute only applies to functions}}
+
+struct A2 {
+ [[clang::optnone]] int aField; // expected-warning{{'optnone' attribute only applies to functions}}
+};
+
+struct B2 {
+ [[clang::optnone]]
+ void foo();
+ [[clang::optnone]]
+ static void bar();
+};
+
diff --git a/test/SemaCXX/attr-selectany.cpp b/test/SemaCXX/attr-selectany.cpp
index 0f9776dbf5db0..c27a9159215ff 100644
--- a/test/SemaCXX/attr-selectany.cpp
+++ b/test/SemaCXX/attr-selectany.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify -std=c++11 %s
// MSVC produces similar diagnostics.
__declspec(selectany) void foo() { } // expected-error{{'selectany' can only be applied to data items with external linkage}}
@@ -31,3 +31,6 @@ class X {
};
__declspec(selectany) X x(1);
+
+namespace { class Internal {}; }
+__declspec(selectany) auto x8 = Internal(); // expected-error {{'selectany' can only be applied to data items with external linkage}}
diff --git a/test/SemaCXX/attr-unavailable.cpp b/test/SemaCXX/attr-unavailable.cpp
index 2d82668a205a3..51dc8fe3789ef 100644
--- a/test/SemaCXX/attr-unavailable.cpp
+++ b/test/SemaCXX/attr-unavailable.cpp
@@ -3,7 +3,7 @@
int &foo(int); // expected-note {{candidate}}
double &foo(double); // expected-note {{candidate}}
void foo(...) __attribute__((__unavailable__)); // expected-note {{candidate function}} \
-// expected-note{{function has been explicitly marked unavailable here}}
+// expected-note{{'foo' has been explicitly marked unavailable here}}
void bar(...) __attribute__((__unavailable__)); // expected-note 2{{explicitly marked unavailable}}
@@ -37,3 +37,22 @@ void unavail(short* sp) {
foo(sp);
foo();
}
+
+// Show that delayed processing of 'unavailable' is the same
+// delayed process for 'deprecated'.
+// <rdar://problem/12241361> and <rdar://problem/15584219>
+enum DeprecatedEnum { DE_A, DE_B } __attribute__((deprecated)); // expected-note {{'DeprecatedEnum' has been explicitly marked deprecated here}}
+__attribute__((deprecated)) typedef enum DeprecatedEnum DeprecatedEnum;
+typedef enum DeprecatedEnum AnotherDeprecatedEnum; // expected-warning {{'DeprecatedEnum' is deprecated}}
+
+__attribute__((deprecated))
+DeprecatedEnum testDeprecated(DeprecatedEnum X) { return X; }
+
+
+enum UnavailableEnum { UE_A, UE_B } __attribute__((unavailable)); // expected-note {{'UnavailableEnum' has been explicitly marked unavailable here}}
+__attribute__((unavailable)) typedef enum UnavailableEnum UnavailableEnum;
+typedef enum UnavailableEnum AnotherUnavailableEnum; // expected-error {{'UnavailableEnum' is unavailable}}
+
+
+__attribute__((unavailable))
+UnavailableEnum testUnavailable(UnavailableEnum X) { return X; }
diff --git a/test/SemaCXX/attr-used.cpp b/test/SemaCXX/attr-used.cpp
index 9bae3edc7f8b3..65df861f83216 100644
--- a/test/SemaCXX/attr-used.cpp
+++ b/test/SemaCXX/attr-used.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-extern char test1[] __attribute__((used)); // expected-warning {{used attribute ignored}}
-extern const char test2[] __attribute__((used)); // expected-warning {{used attribute ignored}}
+extern char test1[] __attribute__((used)); // expected-warning {{'used' attribute ignored}}
+extern const char test2[] __attribute__((used)); // expected-warning {{'used' attribute ignored}}
extern const char test3[] __attribute__((used)) = "";
diff --git a/test/SemaCXX/attr-weak.cpp b/test/SemaCXX/attr-weak.cpp
index 8939a28d75e1a..8ba3a954282d2 100644
--- a/test/SemaCXX/attr-weak.cpp
+++ b/test/SemaCXX/attr-weak.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
static int test0 __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
static void test1() __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
-namespace test2 __attribute__((weak)) { // expected-warning {{'weak' attribute only applies to variables and functions}}
+namespace test2 __attribute__((weak)) { // expected-warning {{'weak' attribute only applies to variables, functions and classes}}
}
namespace {
@@ -31,6 +31,10 @@ template <class T> struct Test7 {
};
template <class T>
int Test7<T>::var;
-namespace { class Internal; }
+namespace { class Internal {}; }
template struct Test7<Internal>;
template struct Test7<int>;
+
+class __attribute__((weak)) Test8 {}; // OK
+
+__attribute__((weak)) auto Test9 = Internal(); // expected-error {{weak declaration cannot have internal linkage}}
diff --git a/test/SemaCXX/attr-weakref.cpp b/test/SemaCXX/attr-weakref.cpp
index 0c3f1d20e7f79..46ca5ab206820 100644
--- a/test/SemaCXX/attr-weakref.cpp
+++ b/test/SemaCXX/attr-weakref.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
// GCC will accept anything as the argument of weakref. Should we
// check for an existing decl?
@@ -34,3 +34,5 @@ static int a10();
int a10() __attribute__((weakref ("foo")));
static int v __attribute__((weakref(a1), alias("foo"))); // expected-error {{'weakref' attribute requires a string}}
+
+__attribute__((weakref ("foo"))) auto a11 = 1; // expected-error {{weakref declaration must have internal linkage}}
diff --git a/test/SemaCXX/bool-compare.cpp b/test/SemaCXX/bool-compare.cpp
new file mode 100644
index 0000000000000..fe47633bb23b6
--- /dev/null
+++ b/test/SemaCXX/bool-compare.cpp
@@ -0,0 +1,207 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+
+void f(int x, int y, int z) {
+
+ bool a,b;
+
+ if(b > true) {} // expected-warning {{comparison of true with expression of type 'bool' is always false}}
+ if(b < true) {} // no warning
+ if(b >= true) {} // no warning
+ if(b <= true) {} // expected-warning {{comparison of true with expression of type 'bool' is always true}}
+ if(b == true) {} // no warning
+ if(b != true) {} // no warning
+
+ if(b > false) {} // no warning
+ if(b < false) {} // expected-warning {{comparison of false with expression of type 'bool' is always false}}
+ if(b >= false) {} // expected-warning {{comparison of false with expression of type 'bool' is always true}}
+ if(b <= false) {} // no warning
+ if(b == false) {} // no warning
+ if(b != false) {} // no warning
+
+ if(b > 1U){} // expected-warning {{comparison of constant 1 with expression of type 'bool' is always false}}
+
+ if (a > b) {} // no warning
+ if (a < b) {} // no warning
+ if (a >= b) {} // no warning
+ if (a <= b) {} // no warning
+ if (a == b) {} // no warning
+ if (a != b) {} // no warning
+
+ if (a > 0) {} // no warning
+ if (a > 1) {} // expected-warning {{comparison of constant 1 with expression of type 'bool' is always false}}
+ if (a > 2) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always false}}
+
+ if (a >= 0) {} // expected-warning {{comparison of constant 0 with expression of type 'bool' is always true}}
+ if (a >= 1) {} // no warning
+ if (a >= 2) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always false}}
+ if (a >= -1) {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
+
+ if (a <= 0) {} // no warning
+ if (a <= 1) {} // expected-warning {{comparison of constant 1 with expression of type 'bool' is always true}}
+ if (a <= 2) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always true}}
+ if (a <= -1) {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always false}}
+
+ if (!a > 0) {} // no warning
+ if (!a > 1) {} // expected-warning {{comparison of constant 1 with expression of type 'bool' is always false}}
+ if (!a > 2) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always false}}
+ if (!a > y) {} // no warning
+ if (!a > b) {} // no warning
+ if (!a > -1) {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
+
+ if (!a < 0) {} // expected-warning {{comparison of constant 0 with expression of type 'bool' is always false}}
+ if (!a < 1) {} // no warning
+ if (!a < 2) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always true}}
+ if (!a < y) {} // no warning
+ if (!a < b) {} // no warning
+ if (!a < -1) {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always false}}
+
+ if (!a >= 0) {} // expected-warning {{comparison of constant 0 with expression of type 'bool' is always true}}
+ if (!a >= 1) {} // no warning
+ if (!a >= 2) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always false}}
+ if (!a >= y) {} // no warning
+ if (!a >= b) {} // no warning
+ if (!a >= -1) {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
+
+ if (!a <= 0) {} // no warning
+ if (!a <= 1) {} // expected-warning {{comparison of constant 1 with expression of type 'bool' is always true}}
+ if (!a <= 2) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always true}}
+ if (!a <= y) {} // no warning
+ if (!a <= b) {} // no warning
+ if (!a <= -1) {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always false}}
+
+ if ((a||b) > 0) {} // no warning
+ if ((a||b) > 1) {} // expected-warning {{comparison of constant 1 with expression of type 'bool' is always false}}
+ if ((a||b) > 4) {} // expected-warning {{comparison of constant 4 with expression of type 'bool' is always false}}
+ if ((a||b) > -1) {}// expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
+
+ if ((a&&b) > 0) {} // no warning
+ if ((a&&b) > 1) {} // expected-warning {{comparison of constant 1 with expression of type 'bool' is always false}}
+ if ((a&&b) > 4) {} // expected-warning {{comparison of constant 4 with expression of type 'bool' is always false}}
+
+ if ((a<y) > 0) {} // no warning
+ if ((a<y) > 1) {} // expected-warning {{comparison of constant 1 with expression of type 'bool' is always false}}
+ if ((a<y) > 4) {} // expected-warning {{comparison of constant 4 with expression of type 'bool' is always false}}
+ if ((a<y) > z) {} // no warning
+ if ((a<y) > -1) {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
+
+ if ((a<y) == 0) {} // no warning
+ if ((a<y) == 1) {} // no warning
+ if ((a<y) == 2) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always false}}
+ if ((a<y) == z) {} // no warning
+ if ((a<y) == -1) {}// expected-warning {{comparison of constant -1 with expression of type 'bool' is always false}}
+
+ if ((a<y) != 0) {} // no warning
+ if ((a<y) != 1) {} // no warning
+ if ((a<y) != 2) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always true}}
+ if ((a<y) != z) {} // no warning
+ if ((a<y) != -1) {}// expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
+
+ if ((a<y) == z) {} // no warning
+ if (a>y<z) {} // no warning
+ if ((a<y) > z) {} // no warning
+ if((a<y)>(z<y)) {} // no warning
+ if((a<y)==(z<y)){} // no warning
+ if((a<y)!=(z<y)){} // no warning
+ if((z==x)<(y==z)){} // no warning
+ if((a<y)!=((z==x)<(y==z))){} // no warning
+
+
+ if (0 > !a) {} // expected-warning {{comparison of constant 0 with expression of type 'bool' is always false}}
+ if (1 > !a) {} // no warning
+ if (2 > !a) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always true}}
+ if (y > !a) {} // no warning
+ if (-1 > !a) {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always false}}
+
+ if (0 < !a) {} // no warning
+ if (1 < !a) {} // expected-warning {{comparison of constant 1 with expression of type 'bool' is always false}}
+ if (2 < !a) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always false}}
+ if (y < !a) {} // no warning
+ if (-1 < !a) {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
+
+
+ if (0 >= !a) {} // no warning
+ if (1 >= !a) {} // expected-warning {{comparison of constant 1 with expression of type 'bool' is always true}}
+ if (2 >= !a) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always true}}
+ if (y >= !a) {} // no warning
+ if (-1 >= !a) {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always false}}
+
+ if (0 <= !a) {} // expected-warning {{comparison of constant 0 with expression of type 'bool' is always true}}
+ if (1 <= !a) {} // no warning
+ if (2 <= !a) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always false}}
+ if (y <= !a) {} //
+ if (-1 <= !a) {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
+
+ if (0 > (a||b)) {} // expected-warning {{comparison of constant 0 with expression of type 'bool' is always false}}
+ if (1 > (a||b)) {} // no warning
+ if (4 > (a||b)) {} // expected-warning {{comparison of constant 4 with expression of type 'bool' is always true}}
+
+ if (0 > (a&&b)) {} // expected-warning {{comparison of constant 0 with expression of type 'bool' is always false}}
+ if (1 > (a&&b)) {} // no warning
+ if (4 > (a&&b)) {} // expected-warning {{comparison of constant 4 with expression of type 'bool' is always true}}
+
+ if (0 > (a<y)) {} // expected-warning {{comparison of constant 0 with expression of type 'bool' is always false}}
+ if (1 > (a<y)) {} // no warning
+ if (4 > (a<y)) {} // expected-warning {{comparison of constant 4 with expression of type 'bool' is always true}}
+ if (z > (a<y)) {} //
+ if (-1 > (a<y)) {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always false}}
+
+ if (0 == (a<y)) {} // no warning
+ if (1 == (a<y)) {} // no warning
+ if (2 == (a<y)) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always false}}
+ if (z == (a<y)) {} // no warning
+ if (-1 == (a<y)){} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always false}}
+
+ if (0 !=(a<y)) {} // no warning
+ if (1 !=(a<y)) {} // no warning
+ if (2 !=(a<y)) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always true}}
+ if (z !=(a<y)) {} // no warning
+ if (-1 !=(a<y)) {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
+
+ if (z ==(a<y)) {} // no warning
+ if (z<a>y) {} // no warning
+ if (z > (a<y)) {} // no warning
+ if((z<y)>(a<y)) {} // no warning
+ if((z<y)==(a<y)){} // no warning
+ if((z<y)!=(a<y)){} // no warning
+ if((y==z)<(z==x)){} // no warning
+ if(((z==x)<(y==z))!=(a<y)){} // no warning
+
+ if(((z==x)<(-1==z))!=(a<y)){} // no warning
+ if(((z==x)<(z==-1))!=(a<y)){} // no warning
+ if(((z==x)<-1)!=(a<y)){} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always false}}
+ if(((z==x)< 2)!=(a<y)){} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always true}}
+ if(((z==x)<(z>2))!=(a<y)){} // no warning
+
+}
+
+
+template<typename T, typename U, typename V> struct X6 {
+ U f(T t, U u, V v) {
+ // IfStmt
+ if (t > 0)
+ return u;
+ else {
+ if (t < 0)
+ return v; // expected-error{{cannot initialize return object of type}}
+ }
+ bool r;
+ // FIXME: We should warn here, DiagRuntimeBehavior does currently not detect this.
+ if(r<0){}
+
+ if (T x = t) {
+ t = x;
+ }
+ return v; // expected-error{{cannot initialize return object of type}}
+ }
+};
+
+struct ConvertibleToInt {
+ operator int() const;
+};
+
+template struct X6<ConvertibleToInt, float, char>;
+template struct X6<bool, int, int*>; // expected-note{{instantiation}}
+
+
+
diff --git a/test/SemaCXX/c99-variable-length-array.cpp b/test/SemaCXX/c99-variable-length-array.cpp
index bb620c71fa070..237f56458dab3 100644
--- a/test/SemaCXX/c99-variable-length-array.cpp
+++ b/test/SemaCXX/c99-variable-length-array.cpp
@@ -140,3 +140,24 @@ namespace PR11744 {
}
int test = f<int>(0); // expected-note {{instantiation of}}
}
+
+namespace pr18633 {
+ struct A1 {
+ static const int sz;
+ static const int sz2;
+ };
+ const int A1::sz2 = 11;
+ template<typename T>
+ void func () {
+ int arr[A1::sz]; // expected-warning{{variable length arrays are a C99 feature}}
+ }
+ template<typename T>
+ void func2 () {
+ int arr[A1::sz2];
+ }
+ const int A1::sz = 12;
+ void func2() {
+ func<int>();
+ func2<int>();
+ }
+}
diff --git a/test/SemaCXX/calling-conv-compat.cpp b/test/SemaCXX/calling-conv-compat.cpp
index 2d52386add16c..cebac9fad6cdd 100644
--- a/test/SemaCXX/calling-conv-compat.cpp
+++ b/test/SemaCXX/calling-conv-compat.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -fms-extensions -cxx-abi microsoft -verify -triple i686-pc-win32 %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -fms-extensions -verify -triple i686-pc-win32 %s
// Pointers to free functions
void free_func_default();
@@ -351,24 +351,25 @@ typedef void (__cdecl fun_cdecl)();
typedef void (__stdcall fun_stdcall)();
typedef void (__fastcall fun_fastcall)();
-// FIXME: Adjust cdecl to thiscall when forming a member pointer.
-//fun_default A::*td1 = &A::method_thiscall;
-fun_cdecl A::*td2 = &A::method_cdecl;
+fun_default A::*td1 = &A::method_thiscall;
+fun_cdecl A::*td2 = &A::method_thiscall;
fun_stdcall A::*td3 = &A::method_stdcall;
fun_fastcall A::*td4 = &A::method_fastcall;
// Round trip the function type through a template, and verify that only cdecl
// gets adjusted.
-template<typename Fn> struct X {
- typedef Fn A::*p;
-};
+template<typename Fn> struct X { typedef Fn A::*p; };
-// FIXME: Adjust cdecl to thiscall when forming a member pointer.
-//X<void ()>::p tmpl1 = &A::method_thiscall;
-//X<void __cdecl ()>::p tmpl2 = &A::method_thiscall;
+X<void ()>::p tmpl1 = &A::method_thiscall;
+X<void __cdecl ()>::p tmpl2 = &A::method_thiscall;
X<void __stdcall ()>::p tmpl3 = &A::method_stdcall;
X<void __fastcall ()>::p tmpl4 = &A::method_fastcall;
+X<fun_default >::p tmpl5 = &A::method_thiscall;
+X<fun_cdecl >::p tmpl6 = &A::method_thiscall;
+X<fun_stdcall >::p tmpl7 = &A::method_stdcall;
+X<fun_fastcall>::p tmpl8 = &A::method_fastcall;
+
} // end namespace MemberPointers
// Test that lambdas that capture nothing convert to cdecl function pointers.
diff --git a/test/SemaCXX/compare.cpp b/test/SemaCXX/compare.cpp
index 8214f7899ecfc..ef0a524f92f11 100644
--- a/test/SemaCXX/compare.cpp
+++ b/test/SemaCXX/compare.cpp
@@ -225,7 +225,7 @@ void test3() {
}
// Test comparison of short to unsigned. If tautological compare does not
-// trigger, then the signed comparision warning will.
+// trigger, then the signed comparison warning will.
void test4(short s) {
// A is max short plus 1. All zero and positive shorts are smaller than it.
// All negative shorts are cast towards the max unsigned range. Relation
diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp
index 5abee4a3c4f85..538de5847de81 100644
--- a/test/SemaCXX/conditional-expr.cpp
+++ b/test/SemaCXX/conditional-expr.cpp
@@ -75,6 +75,7 @@ void test()
int i1 = ToBool() ? 0 : 1;
// p2 (one or both void, and throwing)
+ Fields flds;
i1 ? throw 0 : throw 1;
i1 ? test() : throw 1;
i1 ? throw 0 : test();
@@ -85,8 +86,16 @@ void test()
i1 = i1 ? 0 : (throw 0);
i1 ? 0 : test(); // expected-error {{right operand to ? is void, but left operand is of type 'int'}}
i1 ? test() : 0; // expected-error {{left operand to ? is void, but right operand is of type 'int'}}
- (i1 ? throw 0 : i1) = 0; // expected-error {{expression is not assignable}}
- (i1 ? i1 : throw 0) = 0; // expected-error {{expression is not assignable}}
+ (i1 ? throw 0 : i1) = 0;
+ (i1 ? i1 : throw 0) = 0;
+ (i1 ? (throw 0) : i1) = 0;
+ (i1 ? i1 : (throw 0)) = 0;
+ (i1 ? (void)(throw 0) : i1) = 0; // expected-error {{left operand to ? is void, but right operand is of type 'int'}}
+ (i1 ? i1 : (void)(throw 0)) = 0; // expected-error {{right operand to ? is void, but left operand is of type 'int'}}
+ int &throwRef1 = (i1 ? flds.i1 : throw 0);
+ int &throwRef2 = (i1 ? throw 0 : flds.i1);
+ int &throwRef3 = (i1 ? flds.b1 : throw 0); // expected-error {{non-const reference cannot bind to bit-field}}
+ int &throwRef4 = (i1 ? throw 0 : flds.b1); // expected-error {{non-const reference cannot bind to bit-field}}
// p3 (one or both class type, convert to each other)
// b1 (lvalues)
@@ -151,7 +160,6 @@ void test()
&(i1 ? i1 : i2); // expected-error {{cannot take the address of an rvalue}}
// p4 (lvalue, same type)
- Fields flds;
int &ir1 = i1 ? flds.i1 : flds.i2;
(i1 ? flds.b1 : flds.i2) = 0;
(i1 ? flds.i1 : flds.b2) = 0;
@@ -219,8 +227,8 @@ void test()
// *must* create a separate temporary copy of class objects. This can only
// be properly tested at runtime, though.
- const Abstract &a = true ? static_cast<const Abstract&>(Derived1()) : Derived2(); // expected-error {{allocating an object of abstract class type 'const Abstract'}}
- true ? static_cast<const Abstract&>(Derived1()) : throw 3; // expected-error {{allocating an object of abstract class type 'const Abstract'}}
+ const Abstract &abstract1 = true ? static_cast<const Abstract&>(Derived1()) : Derived2(); // expected-error {{allocating an object of abstract class type 'const Abstract'}}
+ const Abstract &abstract2 = true ? static_cast<const Abstract&>(Derived1()) : throw 3; // ok
}
namespace PR6595 {
@@ -367,3 +375,12 @@ namespace DR587 {
const volatile int &cvir2 = b ? cvi : vi;
const volatile int &cvir3 = b ? ci : vi; // expected-error{{volatile lvalue reference to type 'const volatile int' cannot bind to a temporary of type 'int'}}
}
+
+namespace PR17052 {
+ struct X {
+ int i_;
+ bool b_;
+
+ int &test() { return b_ ? i_ : throw 1; }
+ };
+}
diff --git a/test/SemaCXX/const-cast.cpp b/test/SemaCXX/const-cast.cpp
index 1fe350d1977a8..cb9937c50d50c 100644
--- a/test/SemaCXX/const-cast.cpp
+++ b/test/SemaCXX/const-cast.cpp
@@ -60,7 +60,7 @@ short *bad_const_cast_test(char const *volatile *const volatile *var)
// Function pointers.
f fp2 = const_cast<f>(fp1); // expected-error {{const_cast to 'f' (aka 'int (*)(int)'), which is not a reference, pointer-to-object, or pointer-to-data-member}}
void (A::*mfn)() = 0;
- (void)const_cast<void (A::*)()>(mfn); // expected-error {{const_cast to 'void (A::*)()', which is not a reference, pointer-to-object, or pointer-to-data-member}}
+ (void)const_cast<void (A::*)()>(mfn); // expected-error-re {{const_cast to 'void (A::*)(){{( __attribute__\(\(thiscall\)\))?}}', which is not a reference, pointer-to-object, or pointer-to-data-member}}
(void)const_cast<int&&>(0); // expected-error {{const_cast from rvalue to reference type 'int &&'}} expected-warning {{C++11}}
return **var3;
}
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp
index d73ee4507f7b9..09d93fa73af1f 100644
--- a/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i686-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -fsyntax-only -fcxx-exceptions -verify -std=c++11 -pedantic %s -Wno-comment
+// RUN: %clang_cc1 -triple i686-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -fsyntax-only -fcxx-exceptions -verify -std=c++11 -pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion
namespace StaticAssertFoldTest {
@@ -823,6 +823,19 @@ static_assert(X() == 0, "");
}
+struct This {
+ constexpr int f() const { return 0; }
+ static constexpr int g() { return 0; }
+ void h() {
+ constexpr int x = f(); // expected-error {{must be initialized by a constant}}
+ // expected-note@-1 {{implicit use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function}}
+ constexpr int y = this->f(); // expected-error {{must be initialized by a constant}}
+ // expected-note-re@-1 {{{{^}}use of 'this' pointer}}
+ constexpr int z = g();
+ static_assert(z == 0, "");
+ }
+};
+
}
namespace Temporaries {
@@ -860,6 +873,12 @@ static_assert(f(T(5)) == 5, "");
constexpr bool b(int n) { return &n; }
static_assert(b(0), "");
+struct NonLiteral {
+ NonLiteral();
+ int f();
+};
+constexpr int k = NonLiteral().f(); // expected-error {{constant expression}} expected-note {{non-literal type 'Temporaries::NonLiteral'}}
+
}
namespace Union {
diff --git a/test/SemaCXX/constant-expression.cpp b/test/SemaCXX/constant-expression.cpp
index 942bf414742b2..e01acdd46f935 100644
--- a/test/SemaCXX/constant-expression.cpp
+++ b/test/SemaCXX/constant-expression.cpp
@@ -124,3 +124,20 @@ namespace test3 {
struct Y { bool b; X x; }; // expected-error {{field has incomplete type 'test3::X'}}
int f() { return Y().b; }
}
+
+// PR18283
+namespace test4 {
+ template <int> struct A {};
+ int const i = { 42 };
+ // i can be used as non-type template-parameter as "const int x = { 42 };" is
+ // equivalent to "const int x = 42;" as per C++03 8.5/p13.
+ typedef A<i> Ai; // ok
+}
+
+// rdar://16064952
+namespace rdar16064952 {
+ template < typename T > void fn1() {
+ T b;
+ unsigned w = ({int a = b.val[sizeof(0)]; 0; }); // expected-warning {{use of GNU statement expression extension}}
+ }
+}
diff --git a/test/SemaCXX/constexpr-value-init.cpp b/test/SemaCXX/constexpr-value-init.cpp
index e5b7db50eb65f..9ad11290190f3 100644
--- a/test/SemaCXX/constexpr-value-init.cpp
+++ b/test/SemaCXX/constexpr-value-init.cpp
@@ -9,7 +9,7 @@ struct B {
A a;
};
-constexpr A a; // ok, zero initialization preceeds static initialization
+constexpr A a; // ok, zero initialization precedes static initialization
void f() {
constexpr A a; // expected-error {{constant expression}} expected-note {{in call to 'A()'}}
}
diff --git a/test/SemaCXX/constructor-initializer.cpp b/test/SemaCXX/constructor-initializer.cpp
index 17576328c11be..81dc19ea6dfc0 100644
--- a/test/SemaCXX/constructor-initializer.cpp
+++ b/test/SemaCXX/constructor-initializer.cpp
@@ -94,7 +94,7 @@ struct Current : Derived {
Derived::Base1(), // expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}}
Derived::V(),
::NonExisting(), // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
- INT::NonExisting() {} // expected-error {{expected a class or namespace}} \
+ INT::NonExisting() {} // expected-error {{'INT' (aka 'int') is not a class, namespace, or scoped enumeration}} \
// expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
};
@@ -232,15 +232,14 @@ namespace PR7402 {
// <rdar://problem/8308215>: don't crash.
// Lots of questionable recovery here; errors can change.
namespace test3 {
- class A : public std::exception {}; // expected-error {{undeclared identifier}} expected-error {{expected class name}} expected-note 4 {{candidate}}
+ class A : public std::exception {}; // expected-error {{undeclared identifier}} expected-error {{expected class name}} expected-note 2 {{candidate}}
class B : public A {
public:
B(const String& s, int e=0) // expected-error {{unknown type name}}
: A(e), m_String(s) , m_ErrorStr(__null) {} // expected-error {{no matching constructor}} expected-error {{does not name}}
B(const B& e)
: A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error {{does not name}} \
- // expected-error {{no member named 'm_String' in 'test3::B'}} \
- // expected-error {{no matching}}
+ // expected-error {{no member named 'm_String' in 'test3::B'}}
}
};
}
diff --git a/test/SemaCXX/constructor.cpp b/test/SemaCXX/constructor.cpp
index f3b910d2f5a3b..fa930bdb95dcd 100644
--- a/test/SemaCXX/constructor.cpp
+++ b/test/SemaCXX/constructor.cpp
@@ -17,6 +17,8 @@ class Foo {
int Foo(int, int); // expected-error{{constructor cannot have a return type}} \
// expected-error{{member 'Foo' has the same name as its class}}
+
+ volatile Foo(float); // expected-error{{constructor cannot have a return type}}
};
Foo::Foo(const Foo&) { }
diff --git a/test/SemaCXX/conversion-function.cpp b/test/SemaCXX/conversion-function.cpp
index 7eaed54934b3e..40ac33b8eb0df 100644
--- a/test/SemaCXX/conversion-function.cpp
+++ b/test/SemaCXX/conversion-function.cpp
@@ -26,6 +26,9 @@ class Y {
public:
void operator bool(int, ...) const; // expected-error{{conversion function cannot have a return type}} \
// expected-error{{conversion function cannot have any parameters}}
+
+ operator bool(int a = 4, int b = 6) const; // expected-error{{conversion function cannot have any parameters}}
+
operator float(...) const; // expected-error{{conversion function cannot be variadic}}
@@ -405,3 +408,14 @@ namespace PR12712 {
A f(const C c) { return c; }
}
+
+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}}
+ } a;
+ A::S s = a;
+ 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/crashes.cpp b/test/SemaCXX/crashes.cpp
index 0b15bb0386c21..1570d12eeb2fb 100644
--- a/test/SemaCXX/crashes.cpp
+++ b/test/SemaCXX/crashes.cpp
@@ -218,3 +218,16 @@ namespace pr12791 {
template class basic_stringbuf<char>;
}
+namespace pr16989 {
+ class C {
+ template <class T>
+ C tpl_mem(T *) { return } // expected-error{{expected expression}}
+ void mem(int *p) {
+ tpl_mem(p);
+ }
+ };
+ class C2 {
+ void f();
+ };
+ void C2::f() {}
+}
diff --git a/test/SemaCXX/cstyle-cast.cpp b/test/SemaCXX/cstyle-cast.cpp
index 468c8ecb23c42..afac6a137ec4a 100644
--- a/test/SemaCXX/cstyle-cast.cpp
+++ b/test/SemaCXX/cstyle-cast.cpp
@@ -227,6 +227,6 @@ void memptrs()
void (structure::*psf)() = 0;
(void)(int (structure::*)())(psf);
- (void)(void (structure::*)())(psi); // expected-error {{C-style cast from 'const int structure::*' to 'void (structure::*)()' is not allowed}}
- (void)(int structure::*)(psf); // expected-error {{C-style cast from 'void (structure::*)()' to 'int structure::*' is not allowed}}
+ (void)(void (structure::*)())(psi); // expected-error-re {{C-style cast from 'const int structure::*' to 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' is not allowed}}
+ (void)(int structure::*)(psf); // expected-error-re {{C-style cast from 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' to 'int structure::*' is not allowed}}
}
diff --git a/test/SemaCXX/cxx-altivec.cpp b/test/SemaCXX/cxx-altivec.cpp
new file mode 100644
index 0000000000000..baacbac7d0363
--- /dev/null
+++ b/test/SemaCXX/cxx-altivec.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -triple=powerpc-apple-darwin8 -faltivec -fsyntax-only -verify %s
+
+struct Vector {
+ __vector float xyzw;
+} __attribute__((vecreturn)) __attribute__((vecreturn)); // expected-error {{'vecreturn' attribute cannot be repeated}}
diff --git a/test/SemaCXX/cxx0x-compat.cpp b/test/SemaCXX/cxx0x-compat.cpp
index ffbd20fda373d..a58a7f875cdb3 100644
--- a/test/SemaCXX/cxx0x-compat.cpp
+++ b/test/SemaCXX/cxx0x-compat.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++98 -Wc++11-compat -verify %s
-// RUN: %clang_cc1 -fsyntax-only -std=c++1y -Wc++11-compat -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++1z -Wc++11-compat -verify %s
#if __cplusplus < 201103L
@@ -44,5 +44,6 @@ char c = 'x'_x; // expected-warning {{will be treated as a user-defined literal
#else
auto init_capture = [a(0)] {}; // expected-warning {{initialized lambda captures are incompatible with C++ standards before C++1y}}
+static_assert(true); // expected-warning {{incompatible with C++ standards before C++1z}}
#endif
diff --git a/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/test/SemaCXX/cxx0x-cursory-default-delete.cpp
index b1078dc404b17..07a7842266408 100644
--- a/test/SemaCXX/cxx0x-cursory-default-delete.cpp
+++ b/test/SemaCXX/cxx0x-cursory-default-delete.cpp
@@ -80,3 +80,7 @@ struct except_spec_d_match : except_spec_a, except_spec_b {
// (but not normal definitions)
struct S { S(); };
S::S() __attribute((pure)) = default;
+
+using size_t = decltype(sizeof(0));
+void *operator new(size_t) = delete; // expected-error {{deleted definition must be first declaration}} expected-note {{implicit}}
+void operator delete(void *) noexcept = delete; // expected-error {{deleted definition must be first declaration}} expected-note {{implicit}}
diff --git a/test/SemaCXX/cxx0x-delegating-ctors.cpp b/test/SemaCXX/cxx0x-delegating-ctors.cpp
index a34ee4fcb024f..2e1abf53ae99b 100644
--- a/test/SemaCXX/cxx0x-delegating-ctors.cpp
+++ b/test/SemaCXX/cxx0x-delegating-ctors.cpp
@@ -43,7 +43,7 @@ foo::foo (void*) : foo(4.0f) {
}
struct deleted_dtor {
- ~deleted_dtor() = delete; // expected-note{{function has been explicitly marked deleted here}}
+ ~deleted_dtor() = delete; // expected-note{{'~deleted_dtor' has been explicitly marked deleted here}}
deleted_dtor();
deleted_dtor(int) : deleted_dtor() // expected-error{{attempt to use a deleted function}}
{}
diff --git a/test/SemaCXX/cxx0x-deleted-default-ctor.cpp b/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
index 0cebc10ade403..b9af67948bfc9 100644
--- a/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
+++ b/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
@@ -59,7 +59,7 @@ struct good_const {
good_const gc;
struct no_default {
- no_default() = delete; // expected-note 3{{deleted here}}
+ no_default() = delete; // expected-note 4{{deleted here}}
};
struct no_dtor {
~no_dtor() = delete; // expected-note 2{{deleted here}}
@@ -114,7 +114,7 @@ struct defaulted_delete {
defaulted_delete dd; // expected-error {{call to implicitly-deleted default constructor}}
struct late_delete {
- no_default nd;
+ no_default nd; // expected-note {{because field 'nd' has a deleted default constructor}}
late_delete();
};
late_delete::late_delete() = default; // expected-error {{would delete it}}
diff --git a/test/SemaCXX/cxx0x-initializer-constructor.cpp b/test/SemaCXX/cxx0x-initializer-constructor.cpp
index dc179f81bd353..3ea53095d4ea6 100644
--- a/test/SemaCXX/cxx0x-initializer-constructor.cpp
+++ b/test/SemaCXX/cxx0x-initializer-constructor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -fexceptions -verify %s
struct one { char c[1]; };
struct two { char c[2]; };
@@ -75,8 +75,8 @@ namespace objects {
{ F<0> f = {}; }
// Narrowing conversions don't affect viability. The next two choose
// the initializer_list constructor.
- { F<3> f{1, 1.0}; } // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}}
- { F<3> f = {1, 1.0}; } // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}}
+ { F<3> f{1, 1.0}; } // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}}
+ { F<3> f = {1, 1.0}; } // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}}
{ F<3> f{1, 2, 3, 4, 5, 6, 7, 8}; }
{ F<3> f = {1, 2, 3, 4, 5, 6, 7, 8}; }
{ F<3> f{1, 2, 3, 4, 5, 6, 7, 8}; }
@@ -304,7 +304,6 @@ namespace init_list_default {
B b {}; // calls default constructor
}
-
// PR13470, <rdar://problem/11974632>
namespace PR13470 {
struct W {
@@ -365,3 +364,42 @@ namespace PR13470 {
yi.h(); // ok, all diagnostics produced in template definition
}
}
+
+namespace PR19729 {
+ struct A {
+ A(int);
+ A(const A&) = delete;
+ };
+ struct B {
+ void *operator new(std::size_t, A);
+ };
+ B *p = new ({123}) B;
+}
+
+namespace PR11410 {
+ struct A {
+ A() = delete; // expected-note 2{{deleted here}}
+ A(int);
+ };
+
+ A a[3] = {
+ {1}, {2}
+ }; // expected-error {{call to deleted constructor}} \
+ expected-note {{in implicit initialization of array element 2 with omitted initializer}}
+
+ struct B {
+ A a; // expected-note {{in implicit initialization of field 'a'}}
+ } b = {
+ }; // expected-error {{call to deleted constructor}}
+
+ struct C {
+ C(int = 0); // expected-note 2{{candidate}}
+ C(float = 0); // expected-note 2{{candidate}}
+ };
+ C c[3] = {
+ 0, 1
+ }; // expected-error {{ambiguous}} expected-note {{in implicit initialization of array element 2}}
+ C c2[3] = {
+ [0] = 1, [2] = 3
+ }; // expected-error {{ambiguous}} expected-note {{in implicit initialization of array element 1}}
+}
diff --git a/test/SemaCXX/cxx0x-initializer-scalars.cpp b/test/SemaCXX/cxx0x-initializer-scalars.cpp
index 627855e96e8cb..1475dcf911c90 100644
--- a/test/SemaCXX/cxx0x-initializer-scalars.cpp
+++ b/test/SemaCXX/cxx0x-initializer-scalars.cpp
@@ -45,8 +45,8 @@ namespace integral {
{ const int a{1, 2}; } // expected-error {{excess elements}}
{ const int a = {1, 2}; } // expected-error {{excess elements}}
// FIXME: Redundant warnings.
- { const short a{100000}; } // expected-error {{cannot be narrowed}} expected-note {{inserting an explicit cast}} expected-warning {{changes value}}
- { const short a = {100000}; } // expected-error {{cannot be narrowed}} expected-note {{inserting an explicit cast}} expected-warning {{changes value}}
+ { const short a{100000}; } // expected-error {{cannot be narrowed}} expected-note {{insert an explicit cast}} expected-warning {{changes value}}
+ { const short a = {100000}; } // expected-error {{cannot be narrowed}} expected-note {{insert an explicit cast}} expected-warning {{changes value}}
{ if (const int a{1}) static_assert(a == 1, ""); }
{ if (const int a = {1}) static_assert(a == 1, ""); }
}
diff --git a/test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp b/test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp
new file mode 100644
index 0000000000000..774745777c17d
--- /dev/null
+++ b/test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wsystem-headers %s
+
+// libstdc++4.6 in debug mode has explicit default constructors.
+// stlport has this for all containers.
+#ifdef BE_THE_HEADER
+#pragma clang system_header
+namespace std {
+namespace __debug {
+template <class T>
+class vector {
+public:
+ explicit vector() {} // expected-warning{{should not be explicit}}
+};
+}
+}
+#else
+
+#define BE_THE_HEADER
+#include __FILE__
+
+struct { int a, b; std::__debug::vector<int> c; } e[] = { {1, 1} }; // expected-note{{used in initialization here}}
+
+#endif
diff --git a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
index 9d89cce67b384..70f7c642a5458 100644
--- a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -230,3 +230,32 @@ namespace PR18013 {
int f();
std::initializer_list<long (*)()> x = {f}; // expected-error {{cannot initialize an array element of type 'long (*const)()' with an lvalue of type 'int ()': different return type ('long' vs 'int')}}
}
+
+namespace DR1070 {
+ struct S {
+ S(std::initializer_list<int>);
+ };
+ S s[3] = { {1, 2, 3}, {4, 5} }; // ok
+ S *p = new S[3] { {1, 2, 3}, {4, 5} }; // ok
+}
+
+namespace ListInitInstantiate {
+ struct A {
+ A(std::initializer_list<A>);
+ A(std::initializer_list<int>);
+ };
+ struct B : A {
+ B(int);
+ };
+ template<typename T> struct X {
+ X();
+ A a;
+ };
+ template<typename T> X<T>::X() : a{B{0}, B{1}} {}
+
+ X<int> x;
+
+ int f(const A&);
+ template<typename T> void g() { int k = f({0}); }
+ template void g<int>();
+}
diff --git a/test/SemaCXX/cxx0x-type-convert-construct.cpp b/test/SemaCXX/cxx0x-type-convert-construct.cpp
index 6a7fe45281f5a..25a43d7053ccd 100644
--- a/test/SemaCXX/cxx0x-type-convert-construct.cpp
+++ b/test/SemaCXX/cxx0x-type-convert-construct.cpp
@@ -9,9 +9,9 @@ void f() {
Ustr = U"a UTF-32 string"; // expected-error {{assigning to 'char32_t *' from incompatible type 'const char32_t [16]'}}
char *Rstr;
- Rstr = R"foo(a raw string)foo"; // expected-warning{{conversion from string literal to 'char *' is deprecated}}
+ Rstr = R"foo(a raw string)foo"; // expected-warning{{ISO C++11 does not allow conversion from string literal to 'char *'}}
wchar_t *LRstr;
- LRstr = LR"foo(a wide raw string)foo"; // expected-warning{{conversion from string literal to 'wchar_t *' is deprecated}}
+ LRstr = LR"foo(a wide raw string)foo"; // expected-warning{{ISO C++11 does not allow conversion from string literal to 'wchar_t *'}}
char *u8Rstr;
u8Rstr = u8R"foo(a UTF-8 raw string)foo"; // expected-error {{assigning to 'char *' from incompatible type 'const char [19]'}}
char16_t *uRstr;
diff --git a/test/SemaCXX/cxx11-attr-print.cpp b/test/SemaCXX/cxx11-attr-print.cpp
index 01325d3c8bf32..999eaed618026 100644
--- a/test/SemaCXX/cxx11-attr-print.cpp
+++ b/test/SemaCXX/cxx11-attr-print.cpp
@@ -42,9 +42,6 @@ int f3 [[gnu::warn_unused_result]] ();
// CHECK: {{\[}}[noreturn]];
void f4 [[noreturn]] ();
-// CHECK: {{\[}}[std::noreturn]];
-void f5 [[std::noreturn]] ();
-
// CHECK: __attribute__((gnu_inline));
inline void f6() __attribute__((gnu_inline));
diff --git a/test/SemaCXX/cxx11-gnu-attrs.cpp b/test/SemaCXX/cxx11-gnu-attrs.cpp
index 22d61a1978fb2..9f182249a3e6e 100644
--- a/test/SemaCXX/cxx11-gnu-attrs.cpp
+++ b/test/SemaCXX/cxx11-gnu-attrs.cpp
@@ -19,8 +19,6 @@ void aliasa [[gnu::alias("_Z6alias1v")]] ();
void aligned_fn [[gnu::aligned(32)]] ();
struct [[gnu::aligned(8)]] aligned_struct {};
-[[gnu::malloc, gnu::alloc_size(1,2)]] void *alloc_size(int a, int b);
-
void always_inline [[gnu::always_inline]] ();
__thread int tls_model [[gnu::tls_model("local-exec")]];
diff --git a/test/SemaCXX/cxx11-inheriting-ctors.cpp b/test/SemaCXX/cxx11-inheriting-ctors.cpp
index 67d55213a0847..04aa117b29dd2 100644
--- a/test/SemaCXX/cxx11-inheriting-ctors.cpp
+++ b/test/SemaCXX/cxx11-inheriting-ctors.cpp
@@ -26,3 +26,11 @@ namespace PR15757 {
return 0;
}
}
+
+namespace WrongIdent {
+ struct A {};
+ struct B : A {};
+ struct C : B {
+ using B::A;
+ };
+}
diff --git a/test/SemaCXX/cxx11-unused.cpp b/test/SemaCXX/cxx11-unused.cpp
new file mode 100644
index 0000000000000..1e25bd5157247
--- /dev/null
+++ b/test/SemaCXX/cxx11-unused.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s -Wunused-parameter
+
+// PR19303 : Make sure we don't get a unused expression warning for deleted and
+// defaulted functions
+
+// expected-no-diagnostics
+
+class A {
+public:
+ int x;
+ A() = default;
+ ~A() = default;
+ A(const A &other) = delete;
+
+ template <typename T>
+ void SetX(T x) {
+ this->x = x;
+ };
+
+ void SetX1(int x);
+};
+
+template <>
+void A::SetX(A x) = delete;
+
+class B {
+public:
+ B() = default;
+ ~B() = default;
+ B(const B &other);
+};
+
+B::B(const B &other) = default;
diff --git a/test/SemaCXX/cxx11-user-defined-literals.cpp b/test/SemaCXX/cxx11-user-defined-literals.cpp
index f8bbcd960fd32..cb7796418ee31 100644
--- a/test/SemaCXX/cxx11-user-defined-literals.cpp
+++ b/test/SemaCXX/cxx11-user-defined-literals.cpp
@@ -141,3 +141,27 @@ namespace PR14950 {
int operator"" _b(); // expected-error {{no function template matches function template specialization}}
int main() { return 0_b; } // expected-error {{no matching literal operator for call to 'operator "" _b'}}
}
+
+namespace bad_names {
+ template<char...> int operator""_x();
+
+ template<typename T> void f() {
+ class T:: // expected-error {{anonymous class}} expected-warning {{does not declare anything}}
+ operator // expected-error {{expected identifier}}
+ ""_q<'a'>;
+
+ T::template operator""_q<'a'>(); // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} expected-error +{{}}
+ T::template operator""_q<'a'>::X; // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} expected-error +{{}}
+ T::operator""_q<'a'>(); // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} expected-error +{{}}
+ typename T::template operator""_q<'a'> a; // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} expected-error +{{}}
+ typename T::operator""_q(""); // expected-error +{{}} expected-note {{to match}}
+ T::operator""_q(""); // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}}
+
+ bad_names::operator""_x<'a', 'b', 'c'>();
+ };
+
+ struct S {};
+ void g() {
+ S::operator""_q(); // expected-error {{non-namespace scope 'S::' cannot have a literal operator member}}
+ }
+}
diff --git a/test/SemaCXX/cxx1y-deduced-return-type.cpp b/test/SemaCXX/cxx1y-deduced-return-type.cpp
index d3308b3fd50bf..60864165954ad 100644
--- a/test/SemaCXX/cxx1y-deduced-return-type.cpp
+++ b/test/SemaCXX/cxx1y-deduced-return-type.cpp
@@ -261,6 +261,13 @@ namespace DefaultedMethods {
namespace Constexpr {
constexpr auto f1(int n) { return n; }
+ template<typename T> struct X { constexpr auto f() {} }; // PR18746
+ template<typename T> struct Y { constexpr T f() {} }; // expected-note {{control reached end of constexpr function}}
+ void f() {
+ X<int>().f();
+ Y<void>().f();
+ constexpr int q = Y<int>().f(); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to '&Y<int>()->f()'}}
+ }
struct NonLiteral { ~NonLiteral(); } nl; // expected-note {{user-provided destructor}}
constexpr auto f2(int n) { return nl; } // expected-error {{return type 'Constexpr::NonLiteral' is not a literal type}}
}
diff --git a/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp b/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp
index 8bd4f4242c1df..b08d58abd2a9c 100644
--- a/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp
+++ b/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp
@@ -1358,6 +1358,21 @@ template<class R> struct X {
int run_char = X<int>{}.foo('a');
int run_int = X<double>{}.foo(4);
}
-
#endif // MS_EXTENSIONS
+namespace nsdmi_capturing_this {
+struct X {
+ int m = 10;
+ int n = [this](auto) { return m; }(20);
+};
+
+template<class T>
+struct XT {
+ T m = 10;
+ T n = [this](auto) { return m; }(20);
+};
+
+XT<int> xt{};
+
+
+}
diff --git a/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp b/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp
new file mode 100644
index 0000000000000..b0b86e387721f
--- /dev/null
+++ b/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp
@@ -0,0 +1,100 @@
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks %s
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING
+
+namespace explicit_argument_variadics {
+
+
+template<class ... Ts> void print(Ts ... ) { }
+
+struct X { };
+struct Y { };
+struct Z { };
+
+int test() {
+ {
+ auto L = [](auto ... as) { };
+ L.operator()<bool>(true);
+ }
+ {
+ auto L = [](auto a) { };
+ L.operator()<bool>(false);
+ }
+ {
+ auto L = [](auto a, auto b) { };
+ L.operator()<bool>(false, 'a');
+ }
+ {
+ auto L = [](auto a, auto b) { };
+ L.operator()<bool, char>(false, 'a');
+ }
+ {
+ auto L = [](auto a, auto b, auto ... cs) { };
+ L.operator()<bool, char>(false, 'a');
+ L.operator()<bool, char, const char*>(false, 'a', "jim");
+ }
+
+ {
+ auto L = [](auto ... As) {
+ };
+ L.operator()<bool, double>(false, 3.14, "abc");
+ }
+ {
+ auto L = [](auto A, auto B, auto ... As) {
+ };
+ L.operator()<bool>(false, 3.14, "abc");
+ L.operator()<bool, char>(false, 3.14, "abc"); //expected-warning{{implicit conversion}}
+ L.operator()<X, Y, bool, Z>(X{}, Y{}, 3.14, Z{}, X{}); //expected-warning{{implicit conversion}}
+ }
+ {
+ auto L = [](auto ... As) {
+ print("\nL::As = ", As ...);
+ return [](decltype(As) ... as, auto ... Bs) {
+ print("\nL::Inner::as = ", as ...);
+ print("\nL::Inner::Bs = ", Bs ...);
+ return 4;
+ };
+ };
+ auto M = L.operator()<bool, double>(false, 3.14, "abc");
+ M(false, 6.26, "jim", true);
+ M.operator()<bool>(true, 6.26, "jim", false, 3.14);
+ }
+ {
+ auto L = [](auto A, auto ... As) {
+ print("\nL::As = ", As ...);
+ return [](decltype(As) ... as, decltype(A) a, auto ... Bs) {
+ print("\nL::Inner::as = ", as ...);
+ print("\nL::Inner::Bs = ", Bs ...);
+ return 4;
+ };
+ };
+ auto M = L.operator()<bool, double>(false, 3.14, "abc");
+ M(6.26, "jim", true);
+ M.operator()<X>(6.26, "jim", false, X{}, Y{}, Z{});
+ }
+
+ return 0;
+}
+ int run = test();
+} // end ns explicit_argument_extension
+
+
+
+#ifdef PR18499_FIXED
+namespace variadic_expansion {
+ void f(int &, char &);
+
+ template <typename ... T> void g(T &... t) {
+ f([&a(t)]()->decltype(auto) {
+ return a;
+ }() ...);
+ f([&a(f([&b(t)]()->decltype(auto) { return b; }()...), t)]()->decltype(auto) {
+ return a;
+ }()...);
+ }
+
+ void h(int i, char c) { g(i, c); }
+}
+#endif
+
diff --git a/test/SemaCXX/cxx1y-generic-lambdas.cpp b/test/SemaCXX/cxx1y-generic-lambdas.cpp
index 20e06f48a1ce3..dc8574825dd98 100644
--- a/test/SemaCXX/cxx1y-generic-lambdas.cpp
+++ b/test/SemaCXX/cxx1y-generic-lambdas.cpp
@@ -3,6 +3,17 @@
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING
+template<class F, class ...Rest> struct first_impl { typedef F type; };
+template<class ...Args> using first = typename first_impl<Args...>::type;
+
+namespace simple_explicit_capture {
+ void test() {
+ int i;
+ auto L = [i](auto a) { return i + a; };
+ L(3.14);
+ }
+}
+
namespace explicit_call {
int test() {
auto L = [](auto a) { return a; };
@@ -489,8 +500,6 @@ int run = fooT('a') + fooT(3.14);
template<class ... Ts> void print(Ts ... ts) { }
-template<class F, class ... Rest> using first = F;
-
template<class ... Ts> auto fooV(Ts ... ts) {
auto L = [](auto ... a) {
auto M = [](decltype(a) ... b) {
@@ -560,7 +569,6 @@ int (*np2)(const char*, int, const char*, double, const char*, int) = O; // expe
namespace variadic_tests_1 {
template<class ... Ts> void print(Ts ... ts) { }
-template<class F, class ... Rest> using FirstType = F;
template<class F, class ... Rest> F& FirstArg(F& f, Rest...) { return f; }
template<class ... Ts> int fooV(Ts ... ts) {
@@ -574,7 +582,7 @@ template<class ... Ts> int fooV(Ts ... ts) {
};
N('a');
N(N);
- N(FirstType<Ts...>{});
+ N(first<Ts...>{});
};
M(a...);
print("a = ", a..., "\n");
@@ -599,7 +607,7 @@ template<class ... Ts> int fooV(Ts ... ts) {
};
N('a');
N(N);
- N(FirstType<Ts...>{});
+ N(first<Ts...>{});
};
M(a...);
return M;
@@ -619,7 +627,7 @@ template<class ... Ts> int fooV(Ts ... ts) {
};
N('a');
N(N);
- N(FirstType<Ts...>{});
+ N(first<Ts...>{});
return N;
};
M(a...);
@@ -763,7 +771,6 @@ int run = test();
namespace fptr_with_decltype_return_type {
-template<class F, class ... Ts> using FirstType = F;
template<class F, class ... Rest> F& FirstArg(F& f, Rest& ... r) { return f; };
template<class ... Ts> auto vfun(Ts&& ... ts) {
print(ts...);
@@ -774,7 +781,7 @@ int test()
{
auto L = [](auto ... As) {
return [](auto b) ->decltype(b) {
- vfun([](decltype(As) a) -> decltype(a) { return a; } ...)(FirstType<decltype(As)...>{});
+ vfun([](decltype(As) a) -> decltype(a) { return a; } ...)(first<decltype(As)...>{});
return decltype(b){};
};
};
@@ -905,4 +912,4 @@ int run2 = x2.fooG3();
-} //end ns inclass_lambdas_within_nested_classes \ No newline at end of file
+} //end ns inclass_lambdas_within_nested_classes
diff --git a/test/SemaCXX/cxx1y-init-captures.cpp b/test/SemaCXX/cxx1y-init-captures.cpp
index 2cb4d31ffc4bd..64fe50a70e784 100644
--- a/test/SemaCXX/cxx1y-init-captures.cpp
+++ b/test/SemaCXX/cxx1y-init-captures.cpp
@@ -36,7 +36,7 @@ namespace variadic_expansion {
namespace odr_use_within_init_capture {
int test() {
-
+
{ // no captures
const int x = 10;
auto L = [z = x + 2](int a) {
diff --git a/test/SemaCXX/cxx1y-variable-templates_in_class.cpp b/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
index 94d0f16f06ede..1e5e834b6d2a0 100644
--- a/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
+++ b/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -39,11 +39,11 @@ namespace out_of_line {
template<typename T> CONST T B1::right<T,int> = T(5);
class B2 {
- template<typename T, typename T0> static CONST T right = T(100); // expected-note {{previous definition is here}}
- template<typename T> static CONST T right<T,int> = T(5); // expected-note {{previous definition is here}}
+ template<typename T, typename T0> static CONST T right = T(100); // expected-note {{previous initialization is here}}
+ template<typename T> static CONST T right<T,int> = T(5); // expected-note {{previous initialization is here}}
};
- template<typename T, typename T0> CONST T B2::right = T(100); // expected-error {{redefinition of 'right'}}
- template<typename T> CONST T B2::right<T,int> = T(5); // expected-error {{redefinition of 'right'}}
+ template<typename T, typename T0> CONST T B2::right = T(100); // expected-error {{static data member 'right' already has an initializer}}
+ template<typename T> CONST T B2::right<T,int> = T(5); // expected-error {{static data member 'right' already has an initializer}}
class B3 {
template<typename T, typename T0> static CONST T right = T(100);
@@ -291,6 +291,30 @@ namespace in_class_template {
template<typename T> template<typename...U> T A<T>::y<tuple<U...> >[] = { U()... };
static_assert(sizeof(A<int>::y<tuple<char, char, char> >) == 12, "");
}
+
+ namespace bad_reference {
+ struct S {
+ template<typename T> static int A; // expected-note 4{{here}}
+ };
+
+ template<typename T> void f() {
+ typename T::template A<int> a; // expected-error {{template name refers to non-type template 'S::A'}}
+ }
+ template<typename T> void g() {
+ T::template A<int>::B = 0; // expected-error {{template name refers to non-type template 'S::A'}}
+ }
+ template<typename T> void h() {
+ class T::template A<int> c; // expected-error {{template name refers to non-type template 'S::A'}}
+ }
+
+ template<typename T>
+ struct X : T::template A<int> {}; // expected-error {{template name refers to non-type template 'S::A'}}
+
+ template void f<S>(); // expected-note {{in instantiation of}}
+ template void g<S>(); // expected-note {{in instantiation of}}
+ template void h<S>(); // expected-note {{in instantiation of}}
+ template struct X<S>; // expected-note {{in instantiation of}}
+ }
}
namespace in_nested_classes {
diff --git a/test/SemaCXX/cxx1y-variable-templates_top_level.cpp b/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
index b6e8762f5d59d..4e62941e68188 100644
--- a/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
+++ b/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
@@ -81,7 +81,7 @@ namespace odr_tmpl {
template<typename T> T v; // expected-note {{previous definition is here}}
template<typename T> int v; // expected-error {{redefinition of 'v'}}
- template<typename T> int v1; // expected-note {{previous template declaration is here}}
+ template<typename T> extern int v1; // expected-note {{previous template declaration is here}}
template<int I> int v1; // expected-error {{template parameter has a different kind in template redeclaration}}
}
namespace pvt_use {
@@ -90,11 +90,8 @@ namespace odr_tmpl {
}
namespace pvt_diff_params {
- // FIXME: (?) Redefinitions should simply be not allowed, whether the
- // template parameters match or not. However, this current behaviour also
- // matches that of class templates...
- template<typename T, typename> T v; // expected-note 2{{previous template declaration is here}}
- template<typename T> T v; // expected-error {{too few template parameters in template redeclaration}}
+ template<typename T, typename> T v; // expected-note {{previous template declaration is here}}
+ template<typename T> T v; // expected-error {{too few template parameters in template redeclaration}} expected-note {{previous template declaration is here}}
template<typename T, typename, typename> T v; // expected-error {{too many template parameters in template redeclaration}}
}
@@ -327,7 +324,7 @@ namespace narrowing {
template<typename T> T v = {1234}; // expected-warning {{implicit conversion from 'int' to 'char' changes value from 1234 to}}
#ifndef PRECXX11
// expected-error@-2 {{constant expression evaluates to 1234 which cannot be narrowed to type 'char'}}\
- // expected-note@-2 {{override this message by inserting an explicit cast}}
+ // expected-note@-2 {{insert an explicit cast to silence this issue}}
#endif
int k = v<char>; // expected-note {{in instantiation of variable template specialization 'narrowing::v<char>' requested here}}
}
@@ -391,7 +388,7 @@ namespace nested {
namespace n1 {
template<typename T>
- T pi1a = T(3.1415926535897932385);
+ T pi1a = T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}}
#ifndef PRECXX11
// expected-note@-2 {{explicit instantiation refers here}}
#endif
@@ -413,7 +410,7 @@ namespace nested {
#endif
float f1 = pi1a<float>;
- template<> double pi1a<double> = 5.2; // expected-error {{no variable template matches specialization}}
+ template<> double pi1a<double> = 5.2; // expected-error {{variable template specialization of 'pi1a' must originally be declared in namespace 'n1'}}
double d1 = pi1a<double>;
}
@@ -432,3 +429,32 @@ namespace nested {
}
}
+namespace nested_name {
+ template<typename T> int a; // expected-note {{variable template 'a' declared here}}
+ a<int>::b c; // expected-error {{qualified name refers into a specialization of variable template 'a'}}
+
+ class a<int> {}; // expected-error {{identifier followed by '<' indicates a class template specialization but 'a' refers to a variable template}}
+ enum a<int> {}; // expected-error {{expected identifier or '{'}} expected-warning {{does not declare anything}}
+}
+
+namespace PR18530 {
+ template<typename T> int a;
+ int a<int>; // expected-error {{requires 'template<>'}}
+}
+
+namespace PR19152 {
+#ifndef PRECXX11
+ template<typename T> const auto x = 1;
+ static_assert(x<int> == 1, "");
+#endif
+}
+
+namespace PR19169 {
+ template <typename T> int* f();
+ template <typename T> void f();
+ template<> int f<double>; // expected-error {{no variable template matches specialization; did you mean to use 'f' as function template instead?}}
+
+ template <typename T> void g();
+ template<> int g<double>; // expected-error {{no variable template matches specialization; did you mean to use 'g' as function template instead?}}
+}
+
diff --git a/test/SemaCXX/cxx98-compat.cpp b/test/SemaCXX/cxx98-compat.cpp
index 9690638ce0256..96af95425aecc 100644
--- a/test/SemaCXX/cxx98-compat.cpp
+++ b/test/SemaCXX/cxx98-compat.cpp
@@ -23,7 +23,7 @@ template<int ...I> // expected-warning {{variadic templates are incompatible wi
class Variadic3 {};
alignas(8) int with_alignas; // expected-warning {{'alignas' is incompatible with C++98}}
-int with_attribute [[ ]]; // expected-warning {{attributes are incompatible with C++98}}
+int with_attribute [[ ]]; // expected-warning {{C++11 attribute syntax is incompatible with C++98}}
void Literals() {
(void)u8"str"; // expected-warning {{unicode literals are incompatible with C++98}}
@@ -219,18 +219,11 @@ int n = {}; // expected-warning {{scalar initialized from empty initializer list
class PrivateMember {
struct ImPrivate {};
};
-template<typename T> typename T::ImPrivate SFINAEAccessControl(T t) { // expected-warning {{substitution failure due to access control is incompatible with C++98}} expected-note {{while substituting deduced template arguments into function template 'SFINAEAccessControl' [with T = PrivateMember]}}
+template<typename T> typename T::ImPrivate SFINAEAccessControl(T t) { // expected-warning {{substitution failure due to access control is incompatible with C++98}}
return typename T::ImPrivate();
}
int SFINAEAccessControl(...) { return 0; }
-int CheckSFINAEAccessControl = SFINAEAccessControl(PrivateMember());
-
-template<typename T>
-struct FriendRedefinition {
- friend void Friend() {} // expected-warning {{friend function 'Friend' would be implicitly redefined in C++98}} expected-note {{previous}}
-};
-FriendRedefinition<int> FriendRedef1;
-FriendRedefinition<char> FriendRedef2; // expected-note {{requested here}}
+int CheckSFINAEAccessControl = SFINAEAccessControl(PrivateMember()); // expected-note {{while substituting deduced template arguments into function template 'SFINAEAccessControl' [with T = PrivateMember]}}
namespace CopyCtorIssues {
struct Private {
@@ -386,38 +379,22 @@ template<typename T> T var = T(10);
// expected-warning@-4 {{variable templates are a C++1y extension}}
#endif
+// No diagnostic for specializations of variable templates; we will have
+// diagnosed the primary template.
template<typename T> T* var<T*> = new T();
-#ifdef CXX1YCOMPAT
-// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}}
-#else
-// expected-warning@-4 {{variable templates are a C++1y extension}}
-#endif
-
template<> int var<int> = 10;
-#ifdef CXX1YCOMPAT
-// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}}
-#else
-// expected-warning@-4 {{variable templates are a C++1y extension}}
-#endif
-
template int var<int>;
float fvar = var<float>;
-class A {
+class A {
template<typename T> static T var = T(10);
#ifdef CXX1YCOMPAT
// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}}
#else
// expected-warning@-4 {{variable templates are a C++1y extension}}
#endif
-
- template<typename T> static T* var<T*> = new T();
-#ifdef CXX1YCOMPAT
-// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}}
-#else
-// expected-warning@-4 {{variable templates are a C++1y extension}}
-#endif
+ template<typename T> static T* var<T*> = new T();
};
struct B { template<typename T> static T v; };
@@ -435,19 +412,7 @@ template<typename T> T B::v = T();
#endif
template<typename T> T* B::v<T*> = new T();
-#ifdef CXX1YCOMPAT
-// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}}
-#else
-// expected-warning@-4 {{variable templates are a C++1y extension}}
-#endif
-
template<> int B::v<int> = 10;
-#ifdef CXX1YCOMPAT
-// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}}
-#else
-// expected-warning@-4 {{variable templates are a C++1y extension}}
-#endif
-
template int B::v<int>;
float fsvar = B::v<float>;
diff --git a/test/SemaCXX/dcl_init_aggr.cpp b/test/SemaCXX/dcl_init_aggr.cpp
index 8c5e654fca2ef..432c116466111 100644
--- a/test/SemaCXX/dcl_init_aggr.cpp
+++ b/test/SemaCXX/dcl_init_aggr.cpp
@@ -46,7 +46,7 @@ struct NoDefaultConstructor { // expected-note 3 {{candidate constructor (the im
};
struct TooFewError { // expected-error{{implicit default constructor for}}
int a;
- NoDefaultConstructor nodef; // expected-note{{member is declared here}}
+ NoDefaultConstructor nodef; // expected-note{{member is declared here}} expected-note 2{{in implicit initialization of field 'nodef'}}
};
TooFewError too_few_okay = { 1, 1 };
TooFewError too_few_error = { 1 }; // expected-error{{no matching constructor}}
@@ -54,7 +54,7 @@ TooFewError too_few_error = { 1 }; // expected-error{{no matching constructor}}
TooFewError too_few_okay2[2] = { 1, 1 }; // expected-note{{implicit default constructor for 'TooFewError' first required here}}
TooFewError too_few_error2[2] = { 1 }; // expected-error{{no matching constructor}}
-NoDefaultConstructor too_few_error3[3] = { }; // expected-error {{no matching constructor}}
+NoDefaultConstructor too_few_error3[3] = { }; // expected-error {{no matching constructor}} expected-note {{implicit initialization of array element 0}}
// C++ [dcl.init.aggr]p8
struct Empty { };
diff --git a/test/SemaCXX/decl-expr-ambiguity.cpp b/test/SemaCXX/decl-expr-ambiguity.cpp
index 8164b2bc91e72..6abfb2f328747 100644
--- a/test/SemaCXX/decl-expr-ambiguity.cpp
+++ b/test/SemaCXX/decl-expr-ambiguity.cpp
@@ -33,7 +33,7 @@ void f() {
extern T f3();
__typeof(*T()) f4(); // expected-warning {{empty parentheses interpreted as a function declaration}} expected-note {{replace parentheses with an initializer}}
typedef void *V;
- __typeof(*V()) f5();
+ __typeof(*V()) f5(); // expected-error {{ISO C++ does not allow indirection on operand of type 'V' (aka 'void *')}}
T multi1,
multi2(); // expected-warning {{empty parentheses interpreted as a function declaration}} expected-note {{replace parentheses with an initializer}}
T(d)[5]; // expected-error {{redefinition of 'd'}}
diff --git a/test/SemaCXX/decl-microsoft-call-conv.cpp b/test/SemaCXX/decl-microsoft-call-conv.cpp
index 9f1463245ba29..eb6c8507eddcb 100644
--- a/test/SemaCXX/decl-microsoft-call-conv.cpp
+++ b/test/SemaCXX/decl-microsoft-call-conv.cpp
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -triple i686-pc-win32 -cxx-abi microsoft -fms-extensions -verify %s
+// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -verify %s
+// RUN: %clang_cc1 -triple i686-pc-mingw32 -verify %s
+// RUN: %clang_cc1 -triple i686-pc-mingw32 -fms-extensions -verify %s
typedef void void_fun_t();
typedef void __cdecl cdecl_fun_t();
@@ -191,3 +193,41 @@ namespace test5 {
};
extern template void valarray<int>::bar();
}
+
+namespace test6 {
+ struct foo {
+ int bar();
+ };
+ typedef int bar_t();
+ void zed(bar_t foo::*) {
+ }
+ void baz() {
+ zed(&foo::bar);
+ }
+}
+
+namespace test7 {
+ template <typename T>
+ struct S {
+ void f(T t) {
+ t = 42;
+ }
+ };
+ template<> void S<void*>::f(void*);
+ void g(S<void*> s, void* p) {
+ s.f(p);
+ }
+}
+
+namespace test8 {
+ template <typename T>
+ struct S {
+ void f(T t) { // expected-note {{previous declaration is here}}
+ t = 42; // expected-error {{assigning to 'void *' from incompatible type 'int'}}
+ }
+ };
+ template<> void __cdecl S<void*>::f(void*); // expected-error {{function declared 'cdecl' here was previously declared without calling convention}}
+ void g(S<void*> s, void* p) {
+ s.f(p); // expected-note {{in instantiation of member function 'test8::S<void *>::f' requested here}}
+ }
+}
diff --git a/test/SemaCXX/declspec-thread.cpp b/test/SemaCXX/declspec-thread.cpp
new file mode 100644
index 0000000000000..0ace9a65a4c57
--- /dev/null
+++ b/test/SemaCXX/declspec-thread.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -std=c++11 -fms-extensions -verify %s
+
+__thread __declspec(thread) int a; // expected-error {{already has a thread-local storage specifier}}
+__declspec(thread) __thread int b; // expected-error {{already has a thread-local storage specifier}}
+__declspec(thread) int c(); // expected-warning {{only applies to variables}}
+__declspec(thread) int d;
+int foo();
+__declspec(thread) int e = foo(); // expected-error {{must be a constant expression}} expected-note {{thread_local}}
+
+struct HasCtor { HasCtor(); int x; };
+__declspec(thread) HasCtor f; // expected-error {{must be a constant expression}} expected-note {{thread_local}}
+
+struct HasDtor { ~HasDtor(); int x; };
+__declspec(thread) HasDtor g; // expected-error {{non-trivial destruction}} expected-note {{thread_local}}
+
+struct HasDefaultedDefaultCtor {
+ HasDefaultedDefaultCtor() = default;
+ int x;
+};
+__declspec(thread) HasDefaultedDefaultCtor h;
+
+struct HasConstexprCtor {
+ constexpr HasConstexprCtor(int x) : x(x) {}
+ int x;
+};
+__declspec(thread) HasConstexprCtor i(42);
+
+int foo() {
+ __declspec(thread) int a; // expected-error {{must have global storage}}
+ static __declspec(thread) int b;
+}
+
+extern __declspec(thread) int fwd_thread_var;
+__declspec(thread) int fwd_thread_var = 5;
+
+extern int fwd_thread_var_mismatch; // expected-note {{previous declaration}}
+__declspec(thread) int fwd_thread_var_mismatch = 5; // expected-error-re {{thread-local {{.*}} follows non-thread-local}}
+
+extern __declspec(thread) int thread_mismatch_2; // expected-note {{previous declaration}}
+int thread_mismatch_2 = 5; // expected-error-re {{non-thread-local {{.*}} follows thread-local}}
+
+typedef __declspec(thread) int tls_int_t; // expected-warning {{only applies to variables}}
diff --git a/test/SemaCXX/decltype.cpp b/test/SemaCXX/decltype.cpp
index d6e85d285dd14..f1900b2b830f0 100644
--- a/test/SemaCXX/decltype.cpp
+++ b/test/SemaCXX/decltype.cpp
@@ -16,6 +16,27 @@ void test_f2() {
float &fr = f2(AC().a);
}
+template <class T>
+struct Future {
+ explicit Future(T v);
+
+ template <class F>
+ auto call(F&& fn) -> decltype(fn(T())) {
+ return fn(T());
+ }
+
+ template <class B, class F>
+ auto then(F&& fn) -> decltype(call(fn))
+ {
+ return fn(T());
+ }
+};
+
+void rdar16527205() {
+ Future<int> f1(42);
+ f1.call([](int){ return Future<float>(0); });
+}
+
namespace pr10154 {
class A{
A(decltype(nullptr) param);
@@ -45,6 +66,16 @@ namespace PR16529 {
U &r = S<int>::f();
}
+namespace PR18876 {
+ struct A { ~A() = delete; }; // expected-note +{{here}}
+ A f();
+ decltype(f()) *a; // ok, function call
+ decltype(A()) *b; // expected-error {{attempt to use a deleted function}}
+ decltype(0, f()) *c; // ok, function call on RHS of comma
+ decltype(0, A()) *d; // expected-error {{attempt to use a deleted function}}
+ decltype(f(), 0) *e; // expected-error {{attempt to use a deleted function}}
+}
+
template<typename>
class conditional {
};
diff --git a/test/SemaCXX/default1.cpp b/test/SemaCXX/default1.cpp
index b661776b6ef58..23466fac62aaa 100644
--- a/test/SemaCXX/default1.cpp
+++ b/test/SemaCXX/default1.cpp
@@ -62,3 +62,6 @@ int i2() {
j(2, 3); // expected-error{{too many arguments to function call, expected at most single argument 'f', have 2}}
}
}
+
+int pr20055_f(int x = 0, int y = UNDEFINED); // expected-error{{use of undeclared identifier}}
+int pr20055_v = pr20055_f(0);
diff --git a/test/SemaCXX/deleted-function.cpp b/test/SemaCXX/deleted-function.cpp
index e78e7edc71998..d7ef9b263d881 100644
--- a/test/SemaCXX/deleted-function.cpp
+++ b/test/SemaCXX/deleted-function.cpp
@@ -15,9 +15,9 @@ void ov(int) {} // expected-note {{candidate function}}
void ov(double) = delete; // expected-note {{candidate function has been explicitly deleted}}
struct WithDel {
- WithDel() = delete; // expected-note {{function has been explicitly marked deleted here}}
- void fn() = delete; // expected-note {{function has been explicitly marked deleted here}}
- operator int() = delete; // expected-note {{function has been explicitly marked deleted here}}
+ WithDel() = delete; // expected-note {{'WithDel' has been explicitly marked deleted here}}
+ void fn() = delete; // expected-note {{'fn' has been explicitly marked deleted here}}
+ operator int() = delete; // expected-note {{'operator int' has been explicitly marked deleted here}}
void operator +(int) = delete;
int i = delete; // expected-error {{only functions can have deleted definitions}}
diff --git a/test/SemaCXX/deleted-operator.cpp b/test/SemaCXX/deleted-operator.cpp
index 9f53e71d456c3..df67978a36d6c 100644
--- a/test/SemaCXX/deleted-operator.cpp
+++ b/test/SemaCXX/deleted-operator.cpp
@@ -13,6 +13,7 @@ int PR10757f() {
}
struct DelOpDel {
- virtual ~DelOpDel() {} // expected-error {{deleted function}}
- void operator delete(void*) = delete; // expected-note {{deleted here}}
+ // FIXME: In MS ABI, we error twice below.
+ virtual ~DelOpDel() {} // expected-error 1-2 {{attempt to use a deleted function}}
+ void operator delete(void*) = delete; // expected-note 1-2 {{deleted here}}
};
diff --git a/test/SemaCXX/deprecated.cpp b/test/SemaCXX/deprecated.cpp
index 0335a80ffc5d5..2fe6d59861ac5 100644
--- a/test/SemaCXX/deprecated.cpp
+++ b/test/SemaCXX/deprecated.cpp
@@ -24,12 +24,15 @@ void stuff() {
register int m asm("rbx"); // no-warning
int k = to_int(n); // no-warning
-
bool b;
++b; // expected-warning {{incrementing expression of type bool is deprecated}}
- // FIXME: This is ill-formed in C++11.
- char *p = "foo"; // expected-warning {{conversion from string literal to 'char *' is deprecated}}
+ char *p = "foo";
+#if __cplusplus < 201103L
+ // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}
+#else
+ // expected-warning@-4 {{ISO C++11 does not allow conversion from string literal to 'char *'}}
+#endif
}
struct S { int n; };
diff --git a/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp
index e511be0116621..5305ff5f7ca65 100644
--- a/test/SemaCXX/destructor.cpp
+++ b/test/SemaCXX/destructor.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s
+// RUN: %clang_cc1 -std=c++11 -triple %ms_abi_triple -DMSABI -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s
class A {
public:
~A();
@@ -83,6 +84,12 @@ namespace PR6421 {
}
namespace PR6709 {
+#ifdef MSABI
+ // This bug, "Clang instantiates destructor for function argument" is intended
+ // behaviour in the Microsoft ABI because the callee needs to destruct the arguments.
+ // expected-error@+3 {{indirection requires pointer operand ('int' invalid)}}
+ // expected-note@+3 {{in instantiation of member function 'PR6709::X<int>::~X' requested here}}
+#endif
template<class T> class X { T v; ~X() { ++*v; } };
void a(X<int> x) {}
}
@@ -100,10 +107,16 @@ namespace test6 {
T::deleteIt(p); // expected-error {{type 'int' cannot be used prior to '::'}}
}
+#ifdef MSABI
+ // expected-note@+2 {{in instantiation of member function 'test6::A<int>::operator delete' requested here}}
+#endif
virtual ~A() {}
};
- class B : A<int> { B(); }; // expected-note {{in instantiation of member function 'test6::A<int>::operator delete' requested here}}
+#ifndef MSABI
+ // expected-note@+2 {{in instantiation of member function 'test6::A<int>::operator delete' requested here}}
+#endif
+ class B : A<int> { B(); };
B::B() {}
}
@@ -182,7 +195,7 @@ struct B { // expected-warning {{has virtual functions but non-virtual destructo
struct D: B {}; // expected-warning {{has virtual functions but non-virtual destructor}}
-struct F final: B {}; // expected-warning {{has virtual functions but non-virtual destructor}}
+struct F final : B {};
struct VB {
virtual void foo();
@@ -367,3 +380,9 @@ namespace PR7900 {
namespace PR16892 {
auto p = &A::~A; // expected-error{{taking the address of a destructor}}
}
+
+namespace PR20238 {
+struct S {
+ volatile ~S() { } // expected-error{{destructor cannot have a return type}}
+};
+}
diff --git a/test/SemaCXX/dllexport.cpp b/test/SemaCXX/dllexport.cpp
new file mode 100644
index 0000000000000..50d163a7f20f8
--- /dev/null
+++ b/test/SemaCXX/dllexport.cpp
@@ -0,0 +1,1010 @@
+// RUN: %clang_cc1 -triple i686-win32 -fsyntax-only -verify -std=c++11 -DMS %s
+// RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -verify -std=c++1y -DMS %s
+// RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -verify -std=c++1y %s
+// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c++11 %s
+
+// Helper structs to make templates more expressive.
+struct ImplicitInst_Exported {};
+struct ExplicitDecl_Exported {};
+struct ExplicitInst_Exported {};
+struct ExplicitSpec_Exported {};
+struct ExplicitSpec_Def_Exported {};
+struct ExplicitSpec_InlineDef_Exported {};
+struct ExplicitSpec_NotExported {};
+namespace { struct Internal {}; }
+struct External { int v; };
+
+
+// Invalid usage.
+__declspec(dllexport) typedef int typedef1; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+typedef __declspec(dllexport) int typedef2; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+typedef int __declspec(dllexport) typedef3; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+typedef __declspec(dllexport) void (*FunTy)(); // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+enum __declspec(dllexport) Enum {}; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+#if __has_feature(cxx_strong_enums)
+ enum class __declspec(dllexport) EnumClass {}; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+#endif
+
+
+
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Export declaration.
+__declspec(dllexport) extern int ExternGlobalDecl;
+
+// dllexport implies a definition.
+__declspec(dllexport) int GlobalDef;
+
+// Export definition.
+__declspec(dllexport) int GlobalInit1 = 1;
+int __declspec(dllexport) GlobalInit2 = 1;
+
+// Declare, then export definition.
+__declspec(dllexport) extern int GlobalDeclInit;
+int GlobalDeclInit = 1;
+
+// Redeclarations
+__declspec(dllexport) extern int GlobalRedecl1;
+__declspec(dllexport) int GlobalRedecl1;
+
+__declspec(dllexport) extern int GlobalRedecl2;
+ int GlobalRedecl2;
+
+ extern int GlobalRedecl3; // expected-note{{previous declaration is here}}
+__declspec(dllexport) extern int GlobalRedecl3; // expected-error{{redeclaration of 'GlobalRedecl3' cannot add 'dllexport' attribute}}
+
+// External linkage is required.
+__declspec(dllexport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllexport'}}
+__declspec(dllexport) Internal InternalTypeGlobal; // expected-error{{'InternalTypeGlobal' must have external linkage when declared 'dllexport'}}
+namespace { __declspec(dllexport) int InternalGlobal; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllexport'}}
+namespace ns { __declspec(dllexport) int ExternalGlobal; }
+
+__declspec(dllexport) auto InternalAutoTypeGlobal = Internal(); // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllexport'}}
+__declspec(dllexport) auto ExternalAutoTypeGlobal = External();
+
+// Export in local scope.
+void functionScope() {
+ __declspec(dllexport) int LocalVarDecl; // expected-error{{'LocalVarDecl' must have external linkage when declared 'dllexport'}}
+ __declspec(dllexport) int LocalVarDef = 1; // expected-error{{'LocalVarDef' must have external linkage when declared 'dllexport'}}
+ __declspec(dllexport) extern int ExternLocalVarDecl;
+ __declspec(dllexport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllexport'}}
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Variable templates
+//===----------------------------------------------------------------------===//
+#if __has_feature(cxx_variable_templates)
+
+// Export declaration.
+template<typename T> __declspec(dllexport) extern int ExternVarTmplDecl;
+
+// dllexport implies a definition.
+template<typename T> __declspec(dllexport) int VarTmplDef;
+
+// Export definition.
+template<typename T> __declspec(dllexport) int VarTmplInit1 = 1;
+template<typename T> int __declspec(dllexport) VarTmplInit2 = 1;
+
+// Declare, then export definition.
+template<typename T> __declspec(dllexport) extern int VarTmplDeclInit;
+template<typename T> int VarTmplDeclInit = 1;
+
+// Redeclarations
+template<typename T> __declspec(dllexport) extern int VarTmplRedecl1;
+template<typename T> __declspec(dllexport) int VarTmplRedecl1 = 1;
+
+template<typename T> __declspec(dllexport) extern int VarTmplRedecl2;
+template<typename T> int VarTmplRedecl2 = 1;
+
+template<typename T> extern int VarTmplRedecl3; // expected-note{{previous declaration is here}}
+template<typename T> __declspec(dllexport) extern int VarTmplRedecl3; // expected-error{{redeclaration of 'VarTmplRedecl3' cannot add 'dllexport' attribute}}
+
+// External linkage is required.
+template<typename T> __declspec(dllexport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllexport'}}
+template<typename T> __declspec(dllexport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllexport'}}
+namespace { template<typename T> __declspec(dllexport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllexport'}}
+namespace ns { template<typename T> __declspec(dllexport) int ExternalVarTmpl = 1; }
+
+template<typename T> __declspec(dllexport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllexport'}}
+template<typename T> __declspec(dllexport) auto ExternalAutoTypeVarTmpl = External();
+template External ExternalAutoTypeVarTmpl<ExplicitInst_Exported>;
+
+
+template<typename T> int VarTmpl = 1;
+template<typename T> __declspec(dllexport) int ExportedVarTmpl = 1;
+
+// Export implicit instantiation of an exported variable template.
+int useVarTmpl() { return ExportedVarTmpl<ImplicitInst_Exported>; }
+
+// Export explicit instantiation declaration of an exported variable template.
+extern template int ExportedVarTmpl<ExplicitDecl_Exported>;
+ template int ExportedVarTmpl<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of an exported variable template.
+template __declspec(dllexport) int ExportedVarTmpl<ExplicitInst_Exported>;
+
+// Export specialization of an exported variable template.
+template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Exported>;
+template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Def_Exported> = 1;
+
+// Not exporting specialization of an exported variable template without
+// explicit dllexport.
+template<> int ExportedVarTmpl<ExplicitSpec_NotExported>;
+
+
+// Export explicit instantiation declaration of a non-exported variable template.
+extern template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
+ template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of a non-exported variable template.
+template __declspec(dllexport) int VarTmpl<ExplicitInst_Exported>;
+
+// Export specialization of a non-exported variable template.
+template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Exported>;
+template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Def_Exported> = 1;
+
+#endif // __has_feature(cxx_variable_templates)
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Export function declaration. Check different placements.
+__attribute__((dllexport)) void decl1A(); // Sanity check with __attribute__
+__declspec(dllexport) void decl1B();
+
+void __attribute__((dllexport)) decl2A();
+void __declspec(dllexport) decl2B();
+
+// Export function definition.
+__declspec(dllexport) void def() {}
+
+// extern "C"
+extern "C" __declspec(dllexport) void externC() {}
+
+// Export inline function.
+__declspec(dllexport) inline void inlineFunc1() {}
+inline void __attribute__((dllexport)) inlineFunc2() {}
+
+__declspec(dllexport) inline void inlineDecl();
+ void inlineDecl() {}
+
+__declspec(dllexport) void inlineDef();
+ inline void inlineDef() {}
+
+// Redeclarations
+__declspec(dllexport) void redecl1();
+__declspec(dllexport) void redecl1() {}
+
+__declspec(dllexport) void redecl2();
+ void redecl2() {}
+
+ void redecl3(); // expected-note{{previous declaration is here}}
+__declspec(dllexport) void redecl3(); // expected-error{{redeclaration of 'redecl3' cannot add 'dllexport' attribute}}
+
+ void redecl4(); // expected-note{{previous declaration is here}}
+__declspec(dllexport) inline void redecl4() {} // expected-error{{redeclaration of 'redecl4' cannot add 'dllexport' attribute}}
+
+// Friend functions
+struct FuncFriend {
+ friend __declspec(dllexport) void friend1();
+ friend __declspec(dllexport) void friend2();
+ friend void friend3(); // expected-note{{previous declaration is here}}
+ friend void friend4(); // expected-note{{previous declaration is here}}
+};
+__declspec(dllexport) void friend1() {}
+ void friend2() {}
+__declspec(dllexport) void friend3() {} // expected-error{{redeclaration of 'friend3' cannot add 'dllexport' attribute}}
+__declspec(dllexport) inline void friend4() {} // expected-error{{redeclaration of 'friend4' cannot add 'dllexport' attribute}}
+
+// Implicit declarations can be redeclared with dllexport.
+__declspec(dllexport) void* operator new(__SIZE_TYPE__ n);
+
+// External linkage is required.
+__declspec(dllexport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllexport'}}
+__declspec(dllexport) Internal internalRetFunc(); // expected-error{{'internalRetFunc' must have external linkage when declared 'dllexport'}}
+namespace { __declspec(dllexport) void internalFunc() {} } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllexport'}}
+namespace ns { __declspec(dllexport) void externalFunc() {} }
+
+// Export deleted function.
+__declspec(dllexport) void deletedFunc() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+__declspec(dllexport) inline void deletedInlineFunc() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Function templates
+//===----------------------------------------------------------------------===//
+
+// Export function template declaration. Check different placements.
+template<typename T> __declspec(dllexport) void funcTmplDecl1();
+template<typename T> void __declspec(dllexport) funcTmplDecl2();
+
+// Export function template definition.
+template<typename T> __declspec(dllexport) void funcTmplDef() {}
+
+// Export inline function template.
+template<typename T> __declspec(dllexport) inline void inlineFuncTmpl1() {}
+template<typename T> inline void __attribute__((dllexport)) inlineFuncTmpl2() {}
+
+template<typename T> __declspec(dllexport) inline void inlineFuncTmplDecl();
+template<typename T> void inlineFuncTmplDecl() {}
+
+template<typename T> __declspec(dllexport) void inlineFuncTmplDef();
+template<typename T> inline void inlineFuncTmplDef() {}
+
+// Redeclarations
+template<typename T> __declspec(dllexport) void funcTmplRedecl1();
+template<typename T> __declspec(dllexport) void funcTmplRedecl1() {}
+
+template<typename T> __declspec(dllexport) void funcTmplRedecl2();
+template<typename T> void funcTmplRedecl2() {}
+
+template<typename T> void funcTmplRedecl3(); // expected-note{{previous declaration is here}}
+template<typename T> __declspec(dllexport) void funcTmplRedecl3(); // expected-error{{redeclaration of 'funcTmplRedecl3' cannot add 'dllexport' attribute}}
+
+template<typename T> void funcTmplRedecl4(); // expected-note{{previous declaration is here}}
+template<typename T> __declspec(dllexport) inline void funcTmplRedecl4() {} // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllexport' attribute}}
+
+// Function template friends
+struct FuncTmplFriend {
+ template<typename T> friend __declspec(dllexport) void funcTmplFriend1();
+ template<typename T> friend __declspec(dllexport) void funcTmplFriend2();
+ template<typename T> friend void funcTmplFriend3(); // expected-note{{previous declaration is here}}
+ template<typename T> friend void funcTmplFriend4(); // expected-note{{previous declaration is here}}
+};
+template<typename T> __declspec(dllexport) void funcTmplFriend1() {}
+template<typename T> void funcTmplFriend2() {}
+template<typename T> __declspec(dllexport) void funcTmplFriend3() {} // expected-error{{redeclaration of 'funcTmplFriend3' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) inline void funcTmplFriend4() {} // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllexport' attribute}}
+
+// External linkage is required.
+template<typename T> __declspec(dllexport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllexport'}}
+template<typename T> __declspec(dllexport) Internal internalRetFuncTmpl(); // expected-error{{'internalRetFuncTmpl' must have external linkage when declared 'dllexport'}}
+namespace { template<typename T> __declspec(dllexport) void internalFuncTmpl(); } // expected-error{{'(anonymous namespace)::internalFuncTmpl' must have external linkage when declared 'dllexport'}}
+namespace ns { template<typename T> __declspec(dllexport) void externalFuncTmpl(); }
+
+
+template<typename T> void funcTmpl() {}
+template<typename T> __declspec(dllexport) void exportedFuncTmplDecl();
+template<typename T> __declspec(dllexport) void exportedFuncTmpl() {}
+
+// Export implicit instantiation of an exported function template.
+void useFunTmplDecl() { exportedFuncTmplDecl<ImplicitInst_Exported>(); }
+void useFunTmplDef() { exportedFuncTmpl<ImplicitInst_Exported>(); }
+
+// Export explicit instantiation declaration of an exported function template.
+extern template void exportedFuncTmpl<ExplicitDecl_Exported>();
+ template void exportedFuncTmpl<ExplicitDecl_Exported>();
+
+// Export explicit instantiation definition of an exported function template.
+template void exportedFuncTmpl<ExplicitInst_Exported>();
+
+// Export specialization of an exported function template.
+template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Exported>();
+template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void exportedFuncTmpl<ExplicitSpec_InlineDef_Exported>() {}
+
+// Not exporting specialization of an exported function template without
+// explicit dllexport.
+template<> void exportedFuncTmpl<ExplicitSpec_NotExported>() {}
+
+
+// Export explicit instantiation declaration of a non-exported function template.
+extern template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
+ template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
+
+// Export explicit instantiation definition of a non-exported function template.
+template __declspec(dllexport) void funcTmpl<ExplicitInst_Exported>();
+
+// Export specialization of a non-exported function template.
+template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Exported>();
+template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void funcTmpl<ExplicitSpec_InlineDef_Exported>() {}
+
+
+
+//===----------------------------------------------------------------------===//
+// Classes
+//===----------------------------------------------------------------------===//
+
+class __declspec(dllexport) ClassDecl;
+
+class __declspec(dllexport) ClassDef {};
+
+#ifdef MS
+// expected-warning@+3{{'dllexport' attribute ignored}}
+#endif
+template <typename T> struct PartiallySpecializedClassTemplate {};
+template <typename T> struct __declspec(dllexport) PartiallySpecializedClassTemplate<T*> { void f() {} };
+
+template <typename T> struct ExpliciallySpecializedClassTemplate {};
+template <> struct __declspec(dllexport) ExpliciallySpecializedClassTemplate<int> { void f() {} };
+
+
+//===----------------------------------------------------------------------===//
+// Classes with template base classes
+//===----------------------------------------------------------------------===//
+
+template <typename T> class ClassTemplate {};
+template <typename T> class __declspec(dllexport) ExportedClassTemplate {};
+template <typename T> class __declspec(dllimport) ImportedClassTemplate {};
+
+template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
+#ifdef MS
+// expected-note@+2{{class template 'ExplicitlySpecializedTemplate<int>' was explicitly specialized here}}
+#endif
+template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
+
+template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
+#ifdef MS
+// expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate<int>' was instantiated here}}
+#endif
+template struct ExplicitlyInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };
+template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
+template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
+
+// ClassTemplate<int> gets exported.
+class __declspec(dllexport) DerivedFromTemplate : public ClassTemplate<int> {};
+
+// ClassTemplate<int> is already exported.
+class __declspec(dllexport) DerivedFromTemplate2 : public ClassTemplate<int> {};
+
+// ExportedTemplate is explicitly exported.
+class __declspec(dllexport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
+
+// ImportedTemplate is explicitly imported.
+class __declspec(dllexport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
+
+#ifdef MS
+// expected-note@+4{{class template 'ClassTemplate<double>' was instantiated here}}
+// expected-warning@+4{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}}
+// expected-note@+3{{attribute is here}}
+#endif
+class DerivedFromTemplateD : public ClassTemplate<double> {};
+class __declspec(dllexport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
+
+#ifdef MS
+// expected-note@+4{{class template 'ClassTemplate<bool>' was instantiated here}}
+// expected-warning@+4{{propagating dll attribute to already instantiated base class template with different dll attribute is not supported}}
+// expected-note@+3{{attribute is here}}
+#endif
+class __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {};
+class __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
+
+#ifdef MS
+// expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is not supported}}
+// expected-note@+2{{attribute is here}}
+#endif
+struct __declspec(dllexport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
+
+// Base class alredy specialized with export attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
+
+// Base class already specialized with import attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
+
+#ifdef MS
+// expected-warning@+3{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}}
+// expected-note@+2{{attribute is here}}
+#endif
+struct __declspec(dllexport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
+
+// Base class already instantiated with export attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
+
+// Base class already instantiated with import attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
+
+
+//===----------------------------------------------------------------------===//
+// Precedence
+//===----------------------------------------------------------------------===//
+
+// dllexport takes precedence over dllimport if both are specified.
+__attribute__((dllimport, dllexport)) extern int PrecedenceExternGlobal1A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllimport) __declspec(dllexport) extern int PrecedenceExternGlobal1B; // expected-warning{{'dllimport' attribute ignored}}
+
+__attribute__((dllexport, dllimport)) extern int PrecedenceExternGlobal2A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport) __declspec(dllimport) extern int PrecedenceExternGlobal2B; // expected-warning{{'dllimport' attribute ignored}}
+
+__attribute__((dllimport, dllexport)) int PrecedenceGlobal1A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // expected-warning{{'dllimport' attribute ignored}}
+
+__attribute__((dllexport, dllimport)) int PrecedenceGlobal2A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // expected-warning{{'dllimport' attribute ignored}}
+
+__declspec(dllexport) extern int PrecedenceExternGlobalRedecl1;
+__declspec(dllimport) extern int PrecedenceExternGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}}
+
+__declspec(dllimport) extern int PrecedenceExternGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport) extern int PrecedenceExternGlobalRedecl2;
+
+__declspec(dllexport) extern int PrecedenceGlobalRedecl1;
+__declspec(dllimport) int PrecedenceGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}}
+
+__declspec(dllimport) extern int PrecedenceGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport) int PrecedenceGlobalRedecl2;
+
+void __attribute__((dllimport, dllexport)) precedence1A() {} // expected-warning{{'dllimport' attribute ignored}}
+void __declspec(dllimport) __declspec(dllexport) precedence1B() {} // expected-warning{{'dllimport' attribute ignored}}
+
+void __attribute__((dllexport, dllimport)) precedence2A() {} // expected-warning{{'dllimport' attribute ignored}}
+void __declspec(dllexport) __declspec(dllimport) precedence2B() {} // expected-warning{{'dllimport' attribute ignored}}
+
+void __declspec(dllimport) precedenceRedecl1(); // expected-warning{{'dllimport' attribute ignored}}
+void __declspec(dllexport) precedenceRedecl1() {}
+
+void __declspec(dllexport) precedenceRedecl2();
+void __declspec(dllimport) precedenceRedecl2() {} // expected-warning{{'dllimport' attribute ignored}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Class members
+//===----------------------------------------------------------------------===//
+
+// Export individual members of a class.
+struct ExportMembers {
+ struct Nested {
+ __declspec(dllexport) void normalDef();
+ };
+
+ __declspec(dllexport) void normalDecl();
+ __declspec(dllexport) void normalDef();
+ __declspec(dllexport) void normalInclass() {}
+ __declspec(dllexport) void normalInlineDef();
+ __declspec(dllexport) inline void normalInlineDecl();
+ __declspec(dllexport) virtual void virtualDecl();
+ __declspec(dllexport) virtual void virtualDef();
+ __declspec(dllexport) virtual void virtualInclass() {}
+ __declspec(dllexport) virtual void virtualInlineDef();
+ __declspec(dllexport) virtual inline void virtualInlineDecl();
+ __declspec(dllexport) static void staticDecl();
+ __declspec(dllexport) static void staticDef();
+ __declspec(dllexport) static void staticInclass() {}
+ __declspec(dllexport) static void staticInlineDef();
+ __declspec(dllexport) static inline void staticInlineDecl();
+
+protected:
+ __declspec(dllexport) void protectedDef();
+private:
+ __declspec(dllexport) void privateDef();
+public:
+
+ __declspec(dllexport) int Field; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+ __declspec(dllexport) static int StaticField;
+ __declspec(dllexport) static int StaticFieldDef;
+ __declspec(dllexport) static const int StaticConstField;
+ __declspec(dllexport) static const int StaticConstFieldDef;
+ __declspec(dllexport) static const int StaticConstFieldEqualInit = 1;
+ __declspec(dllexport) static const int StaticConstFieldBraceInit{1};
+ __declspec(dllexport) constexpr static int ConstexprField = 1;
+ __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
+};
+
+ void ExportMembers::Nested::normalDef() {}
+ void ExportMembers::normalDef() {}
+inline void ExportMembers::normalInlineDef() {}
+ void ExportMembers::normalInlineDecl() {}
+ void ExportMembers::virtualDef() {}
+inline void ExportMembers::virtualInlineDef() {}
+ void ExportMembers::virtualInlineDecl() {}
+ void ExportMembers::staticDef() {}
+inline void ExportMembers::staticInlineDef() {}
+ void ExportMembers::staticInlineDecl() {}
+ void ExportMembers::protectedDef() {}
+ void ExportMembers::privateDef() {}
+
+ int ExportMembers::StaticFieldDef;
+const int ExportMembers::StaticConstFieldDef = 1;
+constexpr int ExportMembers::ConstexprFieldDef;
+
+
+// Export on member definitions.
+struct ExportMemberDefs {
+ __declspec(dllexport) void normalDef();
+ __declspec(dllexport) void normalInlineDef();
+ __declspec(dllexport) inline void normalInlineDecl();
+ __declspec(dllexport) virtual void virtualDef();
+ __declspec(dllexport) virtual void virtualInlineDef();
+ __declspec(dllexport) virtual inline void virtualInlineDecl();
+ __declspec(dllexport) static void staticDef();
+ __declspec(dllexport) static void staticInlineDef();
+ __declspec(dllexport) static inline void staticInlineDecl();
+
+ __declspec(dllexport) static int StaticField;
+ __declspec(dllexport) static const int StaticConstField;
+ __declspec(dllexport) constexpr static int ConstexprField = 1;
+};
+
+__declspec(dllexport) void ExportMemberDefs::normalDef() {}
+__declspec(dllexport) inline void ExportMemberDefs::normalInlineDef() {}
+__declspec(dllexport) void ExportMemberDefs::normalInlineDecl() {}
+__declspec(dllexport) void ExportMemberDefs::virtualDef() {}
+__declspec(dllexport) inline void ExportMemberDefs::virtualInlineDef() {}
+__declspec(dllexport) void ExportMemberDefs::virtualInlineDecl() {}
+__declspec(dllexport) void ExportMemberDefs::staticDef() {}
+__declspec(dllexport) inline void ExportMemberDefs::staticInlineDef() {}
+__declspec(dllexport) void ExportMemberDefs::staticInlineDecl() {}
+
+__declspec(dllexport) int ExportMemberDefs::StaticField;
+__declspec(dllexport) const int ExportMemberDefs::StaticConstField = 1;
+__declspec(dllexport) constexpr int ExportMemberDefs::ConstexprField;
+
+
+// Export special member functions.
+struct ExportSpecials {
+ __declspec(dllexport) ExportSpecials() {}
+ __declspec(dllexport) ~ExportSpecials();
+ __declspec(dllexport) inline ExportSpecials(const ExportSpecials&);
+ __declspec(dllexport) ExportSpecials& operator=(const ExportSpecials&);
+ __declspec(dllexport) ExportSpecials(ExportSpecials&&);
+ __declspec(dllexport) ExportSpecials& operator=(ExportSpecials&&);
+};
+
+ExportSpecials::~ExportSpecials() {}
+ExportSpecials::ExportSpecials(const ExportSpecials&) {}
+inline ExportSpecials& ExportSpecials::operator=(const ExportSpecials&) { return *this; }
+ExportSpecials::ExportSpecials(ExportSpecials&&) {}
+ExportSpecials& ExportSpecials::operator=(ExportSpecials&&) { return *this; }
+
+
+// Export allocation functions.
+extern "C" void* malloc(__SIZE_TYPE__ size);
+extern "C" void free(void* p);
+struct ExportAlloc {
+ __declspec(dllexport) void* operator new(__SIZE_TYPE__);
+ __declspec(dllexport) void* operator new[](__SIZE_TYPE__);
+ __declspec(dllexport) void operator delete(void*);
+ __declspec(dllexport) void operator delete[](void*);
+};
+void* ExportAlloc::operator new(__SIZE_TYPE__ n) { return malloc(n); }
+void* ExportAlloc::operator new[](__SIZE_TYPE__ n) { return malloc(n); }
+void ExportAlloc::operator delete(void* p) { free(p); }
+void ExportAlloc::operator delete[](void* p) { free(p); }
+
+
+// Export deleted member functions.
+struct ExportDeleted {
+ __declspec(dllexport) ExportDeleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+ __declspec(dllexport) ~ExportDeleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+ __declspec(dllexport) ExportDeleted(const ExportDeleted&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+ __declspec(dllexport) ExportDeleted& operator=(const ExportDeleted&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+ __declspec(dllexport) ExportDeleted(ExportDeleted&&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+ __declspec(dllexport) ExportDeleted& operator=(ExportDeleted&&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+ __declspec(dllexport) void deleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+};
+
+
+// Export defaulted member functions.
+struct ExportDefaulted {
+ __declspec(dllexport) ExportDefaulted() = default;
+ __declspec(dllexport) ~ExportDefaulted() = default;
+ __declspec(dllexport) ExportDefaulted(const ExportDefaulted&) = default;
+ __declspec(dllexport) ExportDefaulted& operator=(const ExportDefaulted&) = default;
+ __declspec(dllexport) ExportDefaulted(ExportDefaulted&&) = default;
+ __declspec(dllexport) ExportDefaulted& operator=(ExportDefaulted&&) = default;
+};
+
+
+// Export defaulted member function definitions.
+struct ExportDefaultedDefs {
+ __declspec(dllexport) ExportDefaultedDefs();
+ __declspec(dllexport) ~ExportDefaultedDefs();
+
+ __declspec(dllexport) inline ExportDefaultedDefs(const ExportDefaultedDefs&);
+ __declspec(dllexport) ExportDefaultedDefs& operator=(const ExportDefaultedDefs&);
+
+ __declspec(dllexport) ExportDefaultedDefs(ExportDefaultedDefs&&);
+ __declspec(dllexport) ExportDefaultedDefs& operator=(ExportDefaultedDefs&&);
+};
+
+// Export definitions.
+__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs() = default;
+ExportDefaultedDefs::~ExportDefaultedDefs() = default;
+
+// Export inline declaration and definition.
+__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(const ExportDefaultedDefs&) = default;
+inline ExportDefaultedDefs& ExportDefaultedDefs::operator=(const ExportDefaultedDefs&) = default;
+
+__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(ExportDefaultedDefs&&) = default;
+ExportDefaultedDefs& ExportDefaultedDefs::operator=(ExportDefaultedDefs&&) = default;
+
+
+// Redeclarations cannot add dllexport.
+struct MemberRedecl {
+ void normalDef(); // expected-note{{previous declaration is here}}
+ void normalInlineDef(); // expected-note{{previous declaration is here}}
+ inline void normalInlineDecl(); // expected-note{{previous declaration is here}}
+ virtual void virtualDef(); // expected-note{{previous declaration is here}}
+ virtual void virtualInlineDef(); // expected-note{{previous declaration is here}}
+ virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}}
+ static void staticDef(); // expected-note{{previous declaration is here}}
+ static void staticInlineDef(); // expected-note{{previous declaration is here}}
+ static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
+
+ static int StaticField; // expected-note{{previous declaration is here}}
+ static const int StaticConstField; // expected-note{{previous declaration is here}}
+ constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
+};
+
+__declspec(dllexport) void MemberRedecl::normalDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllexport' attribute}}
+__declspec(dllexport) inline void MemberRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDef' cannot add 'dllexport' attribute}}
+__declspec(dllexport) void MemberRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDecl' cannot add 'dllexport' attribute}}
+__declspec(dllexport) void MemberRedecl::virtualDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualDef' cannot add 'dllexport' attribute}}
+__declspec(dllexport) inline void MemberRedecl::virtualInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDef' cannot add 'dllexport' attribute}}
+__declspec(dllexport) void MemberRedecl::virtualInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDecl' cannot add 'dllexport' attribute}}
+__declspec(dllexport) void MemberRedecl::staticDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticDef' cannot add 'dllexport' attribute}}
+__declspec(dllexport) inline void MemberRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllexport' attribute}}
+__declspec(dllexport) void MemberRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllexport' attribute}}
+
+__declspec(dllexport) int MemberRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllexport' attribute}}
+__declspec(dllexport) const int MemberRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllexport' attribute}}
+__declspec(dllexport) constexpr int MemberRedecl::ConstexprField; // expected-error{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllexport' attribute}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Class member templates
+//===----------------------------------------------------------------------===//
+
+struct ExportMemberTmpl {
+ template<typename T> __declspec(dllexport) void normalDecl();
+ template<typename T> __declspec(dllexport) void normalDef();
+ template<typename T> __declspec(dllexport) void normalInclass() {}
+ template<typename T> __declspec(dllexport) void normalInlineDef();
+ template<typename T> __declspec(dllexport) inline void normalInlineDecl();
+ template<typename T> __declspec(dllexport) static void staticDecl();
+ template<typename T> __declspec(dllexport) static void staticDef();
+ template<typename T> __declspec(dllexport) static void staticInclass() {}
+ template<typename T> __declspec(dllexport) static void staticInlineDef();
+ template<typename T> __declspec(dllexport) static inline void staticInlineDecl();
+
+#if __has_feature(cxx_variable_templates)
+ template<typename T> __declspec(dllexport) static int StaticField;
+ template<typename T> __declspec(dllexport) static int StaticFieldDef;
+ template<typename T> __declspec(dllexport) static const int StaticConstField;
+ template<typename T> __declspec(dllexport) static const int StaticConstFieldDef;
+ template<typename T> __declspec(dllexport) static const int StaticConstFieldEqualInit = 1;
+ template<typename T> __declspec(dllexport) static const int StaticConstFieldBraceInit{1};
+ template<typename T> __declspec(dllexport) constexpr static int ConstexprField = 1;
+ template<typename T> __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
+#endif // __has_feature(cxx_variable_templates)
+};
+
+template<typename T> void ExportMemberTmpl::normalDef() {}
+template<typename T> inline void ExportMemberTmpl::normalInlineDef() {}
+template<typename T> void ExportMemberTmpl::normalInlineDecl() {}
+template<typename T> void ExportMemberTmpl::staticDef() {}
+template<typename T> inline void ExportMemberTmpl::staticInlineDef() {}
+template<typename T> void ExportMemberTmpl::staticInlineDecl() {}
+
+#if __has_feature(cxx_variable_templates)
+template<typename T> int ExportMemberTmpl::StaticFieldDef;
+template<typename T> const int ExportMemberTmpl::StaticConstFieldDef = 1;
+template<typename T> constexpr int ExportMemberTmpl::ConstexprFieldDef;
+#endif // __has_feature(cxx_variable_templates)
+
+
+// Redeclarations cannot add dllexport.
+struct MemTmplRedecl {
+ template<typename T> void normalDef(); // expected-note{{previous declaration is here}}
+ template<typename T> void normalInlineDef(); // expected-note{{previous declaration is here}}
+ template<typename T> inline void normalInlineDecl(); // expected-note{{previous declaration is here}}
+ template<typename T> static void staticDef(); // expected-note{{previous declaration is here}}
+ template<typename T> static void staticInlineDef(); // expected-note{{previous declaration is here}}
+ template<typename T> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
+
+#if __has_feature(cxx_variable_templates)
+ template<typename T> static int StaticField; // expected-note{{previous declaration is here}}
+ template<typename T> static const int StaticConstField; // expected-note{{previous declaration is here}}
+ template<typename T> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
+#endif // __has_feature(cxx_variable_templates)
+};
+
+template<typename T> __declspec(dllexport) void MemTmplRedecl::normalDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalDef' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) inline void MemTmplRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDef' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) void MemTmplRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDecl' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) void MemTmplRedecl::staticDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticDef' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) inline void MemTmplRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) void MemTmplRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllexport' attribute}}
+
+#if __has_feature(cxx_variable_templates)
+template<typename T> __declspec(dllexport) int MemTmplRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) const int MemTmplRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) constexpr int MemTmplRedecl::ConstexprField; // expected-error{{redeclaration of 'MemTmplRedecl::ConstexprField' cannot add 'dllexport' attribute}}
+#endif // __has_feature(cxx_variable_templates)
+
+
+
+struct MemFunTmpl {
+ template<typename T> void normalDef() {}
+ template<typename T> __declspec(dllexport) void exportedNormal() {}
+ template<typename T> static void staticDef() {}
+ template<typename T> __declspec(dllexport) static void exportedStatic() {}
+};
+
+// Export implicit instantiation of an exported member function template.
+void useMemFunTmpl() {
+ MemFunTmpl().exportedNormal<ImplicitInst_Exported>();
+ MemFunTmpl().exportedStatic<ImplicitInst_Exported>();
+}
+
+// Export explicit instantiation declaration of an exported member function
+// template.
+extern template void MemFunTmpl::exportedNormal<ExplicitDecl_Exported>();
+ template void MemFunTmpl::exportedNormal<ExplicitDecl_Exported>();
+
+extern template void MemFunTmpl::exportedStatic<ExplicitDecl_Exported>();
+ template void MemFunTmpl::exportedStatic<ExplicitDecl_Exported>();
+
+// Export explicit instantiation definition of an exported member function
+// template.
+template void MemFunTmpl::exportedNormal<ExplicitInst_Exported>();
+template void MemFunTmpl::exportedStatic<ExplicitInst_Exported>();
+
+// Export specialization of an exported member function template.
+template<> __declspec(dllexport) void MemFunTmpl::exportedNormal<ExplicitSpec_Exported>();
+template<> __declspec(dllexport) void MemFunTmpl::exportedNormal<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void MemFunTmpl::exportedNormal<ExplicitSpec_InlineDef_Exported>() {}
+
+template<> __declspec(dllexport) void MemFunTmpl::exportedStatic<ExplicitSpec_Exported>();
+template<> __declspec(dllexport) void MemFunTmpl::exportedStatic<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void MemFunTmpl::exportedStatic<ExplicitSpec_InlineDef_Exported>() {}
+
+// Not exporting specialization of an exported member function template without
+// explicit dllexport.
+template<> void MemFunTmpl::exportedNormal<ExplicitSpec_NotExported>() {}
+template<> void MemFunTmpl::exportedStatic<ExplicitSpec_NotExported>() {}
+
+
+// Export explicit instantiation declaration of a non-exported member function
+// template.
+extern template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitDecl_Exported>();
+ template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitDecl_Exported>();
+
+extern template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitDecl_Exported>();
+ template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitDecl_Exported>();
+
+// Export explicit instantiation definition of a non-exported member function
+// template.
+template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitInst_Exported>();
+template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitInst_Exported>();
+
+// Export specialization of a non-exported member function template.
+template<> __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitSpec_Exported>();
+template<> __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void MemFunTmpl::normalDef<ExplicitSpec_InlineDef_Exported>() {}
+
+template<> __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitSpec_Exported>();
+template<> __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Exported>() {}
+
+
+
+#if __has_feature(cxx_variable_templates)
+struct MemVarTmpl {
+ template<typename T> static const int StaticVar = 1;
+ template<typename T> __declspec(dllexport) static const int ExportedStaticVar = 1;
+};
+template<typename T> const int MemVarTmpl::StaticVar;
+template<typename T> const int MemVarTmpl::ExportedStaticVar;
+
+// Export implicit instantiation of an exported member variable template.
+int useMemVarTmpl() { return MemVarTmpl::ExportedStaticVar<ImplicitInst_Exported>; }
+
+// Export explicit instantiation declaration of an exported member variable
+// template.
+extern template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
+ template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of an exported member variable
+// template.
+template const int MemVarTmpl::ExportedStaticVar<ExplicitInst_Exported>;
+
+// Export specialization of an exported member variable template.
+template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_Exported>;
+template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_Def_Exported> = 1;
+
+// Not exporting specialization of an exported member variable template without
+// explicit dllexport.
+template<> const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_NotExported>;
+
+
+// Export explicit instantiation declaration of a non-exported member variable
+// template.
+extern template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
+ template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of a non-exported member variable
+// template.
+template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitInst_Exported>;
+
+// Export specialization of a non-exported member variable template.
+template<> __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitSpec_Exported>;
+template<> __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Exported> = 1;
+
+#endif // __has_feature(cxx_variable_templates)
+
+
+
+//===----------------------------------------------------------------------===//
+// Class template members
+//===----------------------------------------------------------------------===//
+
+// Export individual members of a class template.
+template<typename T>
+struct ExportClassTmplMembers {
+ __declspec(dllexport) void normalDecl();
+ __declspec(dllexport) void normalDef();
+ __declspec(dllexport) void normalInclass() {}
+ __declspec(dllexport) void normalInlineDef();
+ __declspec(dllexport) inline void normalInlineDecl();
+ __declspec(dllexport) virtual void virtualDecl();
+ __declspec(dllexport) virtual void virtualDef();
+ __declspec(dllexport) virtual void virtualInclass() {}
+ __declspec(dllexport) virtual void virtualInlineDef();
+ __declspec(dllexport) virtual inline void virtualInlineDecl();
+ __declspec(dllexport) static void staticDecl();
+ __declspec(dllexport) static void staticDef();
+ __declspec(dllexport) static void staticInclass() {}
+ __declspec(dllexport) static void staticInlineDef();
+ __declspec(dllexport) static inline void staticInlineDecl();
+
+protected:
+ __declspec(dllexport) void protectedDef();
+private:
+ __declspec(dllexport) void privateDef();
+public:
+
+ __declspec(dllexport) int Field; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+ __declspec(dllexport) static int StaticField;
+ __declspec(dllexport) static int StaticFieldDef;
+ __declspec(dllexport) static const int StaticConstField;
+ __declspec(dllexport) static const int StaticConstFieldDef;
+ __declspec(dllexport) static const int StaticConstFieldEqualInit = 1;
+ __declspec(dllexport) static const int StaticConstFieldBraceInit{1};
+ __declspec(dllexport) constexpr static int ConstexprField = 1;
+ __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
+};
+
+template<typename T> void ExportClassTmplMembers<T>::normalDef() {}
+template<typename T> inline void ExportClassTmplMembers<T>::normalInlineDef() {}
+template<typename T> void ExportClassTmplMembers<T>::normalInlineDecl() {}
+template<typename T> void ExportClassTmplMembers<T>::virtualDef() {}
+template<typename T> inline void ExportClassTmplMembers<T>::virtualInlineDef() {}
+template<typename T> void ExportClassTmplMembers<T>::virtualInlineDecl() {}
+template<typename T> void ExportClassTmplMembers<T>::staticDef() {}
+template<typename T> inline void ExportClassTmplMembers<T>::staticInlineDef() {}
+template<typename T> void ExportClassTmplMembers<T>::staticInlineDecl() {}
+template<typename T> void ExportClassTmplMembers<T>::protectedDef() {}
+template<typename T> void ExportClassTmplMembers<T>::privateDef() {}
+
+template<typename T> int ExportClassTmplMembers<T>::StaticFieldDef;
+template<typename T> const int ExportClassTmplMembers<T>::StaticConstFieldDef = 1;
+template<typename T> constexpr int ExportClassTmplMembers<T>::ConstexprFieldDef;
+
+template struct ExportClassTmplMembers<ImplicitInst_Exported>;
+
+
+// Redeclarations cannot add dllexport.
+template<typename T>
+struct CTMR /*ClassTmplMemberRedecl*/ {
+ void normalDef(); // expected-note{{previous declaration is here}}
+ void normalInlineDef(); // expected-note{{previous declaration is here}}
+ inline void normalInlineDecl(); // expected-note{{previous declaration is here}}
+ virtual void virtualDef(); // expected-note{{previous declaration is here}}
+ virtual void virtualInlineDef(); // expected-note{{previous declaration is here}}
+ virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}}
+ static void staticDef(); // expected-note{{previous declaration is here}}
+ static void staticInlineDef(); // expected-note{{previous declaration is here}}
+ static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
+
+ static int StaticField; // expected-note{{previous declaration is here}}
+ static const int StaticConstField; // expected-note{{previous declaration is here}}
+ constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
+};
+
+template<typename T> __declspec(dllexport) void CTMR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) inline void CTMR<T>::normalInlineDef() {} // expected-error{{redeclaration of 'CTMR::normalInlineDef' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) void CTMR<T>::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMR::normalInlineDecl' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) void CTMR<T>::virtualDef() {} // expected-error{{redeclaration of 'CTMR::virtualDef' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) inline void CTMR<T>::virtualInlineDef() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDef' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) void CTMR<T>::virtualInlineDecl() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDecl' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) void CTMR<T>::staticDef() {} // expected-error{{redeclaration of 'CTMR::staticDef' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) inline void CTMR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) void CTMR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllexport' attribute}}
+
+template<typename T> __declspec(dllexport) int CTMR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) const int CTMR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) constexpr int CTMR<T>::ConstexprField; // expected-error{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllexport' attribute}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Class template member templates
+//===----------------------------------------------------------------------===//
+
+template<typename T>
+struct ExportClsTmplMemTmpl {
+ template<typename U> __declspec(dllexport) void normalDecl();
+ template<typename U> __declspec(dllexport) void normalDef();
+ template<typename U> __declspec(dllexport) void normalInclass() {}
+ template<typename U> __declspec(dllexport) void normalInlineDef();
+ template<typename U> __declspec(dllexport) inline void normalInlineDecl();
+ template<typename U> __declspec(dllexport) static void staticDecl();
+ template<typename U> __declspec(dllexport) static void staticDef();
+ template<typename U> __declspec(dllexport) static void staticInclass() {}
+ template<typename U> __declspec(dllexport) static void staticInlineDef();
+ template<typename U> __declspec(dllexport) static inline void staticInlineDecl();
+
+#if __has_feature(cxx_variable_templates)
+ template<typename U> __declspec(dllexport) static int StaticField;
+ template<typename U> __declspec(dllexport) static int StaticFieldDef;
+ template<typename U> __declspec(dllexport) static const int StaticConstField;
+ template<typename U> __declspec(dllexport) static const int StaticConstFieldDef;
+ template<typename U> __declspec(dllexport) static const int StaticConstFieldEqualInit = 1;
+ template<typename U> __declspec(dllexport) static const int StaticConstFieldBraceInit{1};
+ template<typename U> __declspec(dllexport) constexpr static int ConstexprField = 1;
+ template<typename U> __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
+#endif // __has_feature(cxx_variable_templates)
+};
+
+template<typename T> template<typename U> void ExportClsTmplMemTmpl<T>::normalDef() {}
+template<typename T> template<typename U> inline void ExportClsTmplMemTmpl<T>::normalInlineDef() {}
+template<typename T> template<typename U> void ExportClsTmplMemTmpl<T>::normalInlineDecl() {}
+template<typename T> template<typename U> void ExportClsTmplMemTmpl<T>::staticDef() {}
+template<typename T> template<typename U> inline void ExportClsTmplMemTmpl<T>::staticInlineDef() {}
+template<typename T> template<typename U> void ExportClsTmplMemTmpl<T>::staticInlineDecl() {}
+
+#if __has_feature(cxx_variable_templates)
+template<typename T> template<typename U> int ExportClsTmplMemTmpl<T>::StaticFieldDef;
+template<typename T> template<typename U> const int ExportClsTmplMemTmpl<T>::StaticConstFieldDef = 1;
+template<typename T> template<typename U> constexpr int ExportClsTmplMemTmpl<T>::ConstexprFieldDef;
+#endif // __has_feature(cxx_variable_templates)
+
+
+// Redeclarations cannot add dllexport.
+template<typename T>
+struct CTMTR /*ClassTmplMemberTmplRedecl*/ {
+ template<typename U> void normalDef(); // expected-note{{previous declaration is here}}
+ template<typename U> void normalInlineDef(); // expected-note{{previous declaration is here}}
+ template<typename U> inline void normalInlineDecl(); // expected-note{{previous declaration is here}}
+ template<typename U> static void staticDef(); // expected-note{{previous declaration is here}}
+ template<typename U> static void staticInlineDef(); // expected-note{{previous declaration is here}}
+ template<typename U> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
+
+#if __has_feature(cxx_variable_templates)
+ template<typename U> static int StaticField; // expected-note{{previous declaration is here}}
+ template<typename U> static const int StaticConstField; // expected-note{{previous declaration is here}}
+ template<typename U> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
+#endif // __has_feature(cxx_variable_templates)
+};
+
+template<typename T> template<typename U> __declspec(dllexport) void CTMTR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllexport' attribute}}
+template<typename T> template<typename U> __declspec(dllexport) inline void CTMTR<T>::normalInlineDef() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDef' cannot add 'dllexport' attribute}}
+template<typename T> template<typename U> __declspec(dllexport) void CTMTR<T>::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDecl' cannot add 'dllexport' attribute}}
+template<typename T> template<typename U> __declspec(dllexport) void CTMTR<T>::staticDef() {} // expected-error{{redeclaration of 'CTMTR::staticDef' cannot add 'dllexport' attribute}}
+template<typename T> template<typename U> __declspec(dllexport) inline void CTMTR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllexport' attribute}}
+template<typename T> template<typename U> __declspec(dllexport) void CTMTR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllexport' attribute}}
+
+#if __has_feature(cxx_variable_templates)
+template<typename T> template<typename U> __declspec(dllexport) int CTMTR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllexport' attribute}}
+template<typename T> template<typename U> __declspec(dllexport) const int CTMTR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllexport' attribute}}
+template<typename T> template<typename U> __declspec(dllexport) constexpr int CTMTR<T>::ConstexprField; // expected-error{{redeclaration of 'CTMTR::ConstexprField' cannot add 'dllexport' attribute}}
+#endif // __has_feature(cxx_variable_templates)
+
+// FIXME: Precedence rules seem to be different for classes.
diff --git a/test/SemaCXX/dllimport.cpp b/test/SemaCXX/dllimport.cpp
new file mode 100644
index 0000000000000..8e826f7ae6bfc
--- /dev/null
+++ b/test/SemaCXX/dllimport.cpp
@@ -0,0 +1,1085 @@
+// RUN: %clang_cc1 -triple i686-win32 -fsyntax-only -verify -std=c++11 -DMS %s
+// RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -verify -std=c++1y -DMS %s
+// RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -verify -std=c++1y %s
+// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c++11 %s
+
+// Helper structs to make templates more expressive.
+struct ImplicitInst_Imported {};
+struct ExplicitDecl_Imported {};
+struct ExplicitInst_Imported {};
+struct ExplicitSpec_Imported {};
+struct ExplicitSpec_Def_Imported {};
+struct ExplicitSpec_InlineDef_Imported {};
+struct ExplicitSpec_NotImported {};
+namespace { struct Internal {}; }
+
+
+// Invalid usage.
+__declspec(dllimport) typedef int typedef1; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+typedef __declspec(dllimport) int typedef2; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+typedef int __declspec(dllimport) typedef3; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+typedef __declspec(dllimport) void (*FunTy)(); // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+enum __declspec(dllimport) Enum {}; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+#if __has_feature(cxx_strong_enums)
+ enum class __declspec(dllimport) EnumClass {}; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+#endif
+
+
+
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Import declaration.
+__declspec(dllimport) extern int ExternGlobalDecl;
+
+// dllimport implies a declaration.
+__declspec(dllimport) int GlobalDecl;
+int **__attribute__((dllimport))* GlobalDeclChunkAttr;
+int GlobalDeclAttr __attribute__((dllimport));
+
+// Not allowed on definitions.
+__declspec(dllimport) extern int ExternGlobalInit = 1; // expected-error{{definition of dllimport data}}
+__declspec(dllimport) int GlobalInit1 = 1; // expected-error{{definition of dllimport data}}
+int __declspec(dllimport) GlobalInit2 = 1; // expected-error{{definition of dllimport data}}
+
+// Declare, then reject definition.
+__declspec(dllimport) extern int ExternGlobalDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+int ExternGlobalDeclInit = 1; // expected-warning{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+__declspec(dllimport) int GlobalDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+int GlobalDeclInit = 1; // expected-warning{{'GlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+int *__attribute__((dllimport)) GlobalDeclChunkAttrInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+int *GlobalDeclChunkAttrInit = 0; // expected-warning{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+int GlobalDeclAttrInit __attribute__((dllimport)); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+int GlobalDeclAttrInit = 1; // expected-warning{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+// Redeclarations
+__declspec(dllimport) extern int GlobalRedecl1;
+__declspec(dllimport) extern int GlobalRedecl1;
+
+__declspec(dllimport) int GlobalRedecl2a;
+__declspec(dllimport) int GlobalRedecl2a;
+
+int *__attribute__((dllimport)) GlobalRedecl2b;
+int *__attribute__((dllimport)) GlobalRedecl2b;
+
+int GlobalRedecl2c __attribute__((dllimport));
+int GlobalRedecl2c __attribute__((dllimport));
+
+// NB: MSVC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
+// and drop the dllimport with a warning.
+__declspec(dllimport) extern int GlobalRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ extern int GlobalRedecl3; // expected-warning{{'GlobalRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+ extern int GlobalRedecl4; // expected-note{{previous declaration is here}}
+__declspec(dllimport) extern int GlobalRedecl4; // expected-error{{redeclaration of 'GlobalRedecl4' cannot add 'dllimport' attribute}}
+
+// External linkage is required.
+__declspec(dllimport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllimport'}}
+__declspec(dllimport) Internal InternalTypeGlobal; // expected-error{{'InternalTypeGlobal' must have external linkage when declared 'dllimport'}}
+namespace { __declspec(dllimport) int InternalGlobal; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllimport'}}
+namespace ns { __declspec(dllimport) int ExternalGlobal; }
+
+__declspec(dllimport) auto InternalAutoTypeGlobal = Internal(); // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllimport'}}
+ // expected-error@-1{{definition of dllimport data}}
+
+// Import in local scope.
+__declspec(dllimport) float LocalRedecl1; // expected-note{{previous definition is here}}
+__declspec(dllimport) float LocalRedecl2; // expected-note{{previous definition is here}}
+__declspec(dllimport) float LocalRedecl3; // expected-note{{previous definition is here}}
+void functionScope() {
+ __declspec(dllimport) int LocalRedecl1; // expected-error{{redefinition of 'LocalRedecl1' with a different type: 'int' vs 'float'}}
+ int *__attribute__((dllimport)) LocalRedecl2; // expected-error{{redefinition of 'LocalRedecl2' with a different type: 'int *' vs 'float'}}
+ int LocalRedecl3 __attribute__((dllimport)); // expected-error{{redefinition of 'LocalRedecl3' with a different type: 'int' vs 'float'}}
+
+ __declspec(dllimport) int LocalVarDecl;
+ __declspec(dllimport) int LocalVarDef = 1; // expected-error{{definition of dllimport data}}
+ __declspec(dllimport) extern int ExternLocalVarDecl;
+ __declspec(dllimport) extern int ExternLocalVarDef = 1; // expected-error{{definition of dllimport data}}
+ __declspec(dllimport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllimport'}}
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Variable templates
+//===----------------------------------------------------------------------===//
+#if __has_feature(cxx_variable_templates)
+
+// Import declaration.
+template<typename T> __declspec(dllimport) extern int ExternVarTmplDecl;
+
+// dllimport implies a declaration.
+template<typename T> __declspec(dllimport) int VarTmplDecl;
+
+// Not allowed on definitions.
+template<typename T> __declspec(dllimport) extern int ExternVarTmplInit = 1; // expected-error{{definition of dllimport data}}
+template<typename T> __declspec(dllimport) int VarTmplInit1 = 1; // expected-error{{definition of dllimport data}}
+template<typename T> int __declspec(dllimport) VarTmplInit2 = 1; // expected-error{{definition of dllimport data}}
+
+// Declare, then reject definition.
+template<typename T> __declspec(dllimport) extern int ExternVarTmplDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+template<typename T> int ExternVarTmplDeclInit = 1; // expected-warning{{'ExternVarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+template<typename T> __declspec(dllimport) int VarTmplDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+template<typename T> int VarTmplDeclInit = 1; // expected-warning{{'VarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+// Redeclarations
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
+
+template<typename T> __declspec(dllimport) int VarTmplRedecl2;
+template<typename T> __declspec(dllimport) int VarTmplRedecl2;
+
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+template<typename T> extern int VarTmplRedecl3; // expected-warning{{'VarTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+template<typename T> extern int VarTmplRedecl4; // expected-note{{previous declaration is here}}
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl4; // expected-error{{redeclaration of 'VarTmplRedecl4' cannot add 'dllimport' attribute}}
+
+// External linkage is required.
+template<typename T> __declspec(dllimport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllimport'}}
+template<typename T> __declspec(dllimport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllimport'}}
+namespace { template<typename T> __declspec(dllimport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllimport'}}
+namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; }
+
+template<typename T> __declspec(dllimport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{definition of dllimport data}} // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllimport'}}
+
+
+template<typename T> int VarTmpl;
+template<typename T> __declspec(dllimport) int ImportedVarTmpl;
+
+// Import implicit instantiation of an imported variable template.
+int useVarTmpl() { return ImportedVarTmpl<ImplicitInst_Imported>; }
+
+// Import explicit instantiation declaration of an imported variable template.
+extern template int ImportedVarTmpl<ExplicitDecl_Imported>;
+
+// An explicit instantiation definition of an imported variable template cannot
+// be imported because the template must be defined which is illegal.
+
+// Import specialization of an imported variable template.
+template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Imported>;
+template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Def_Imported> = 1; // expected-error{{definition of dllimport data}}
+
+// Not importing specialization of an imported variable template without
+// explicit dllimport.
+template<> int ImportedVarTmpl<ExplicitSpec_NotImported>;
+
+
+// Import explicit instantiation declaration of a non-imported variable template.
+extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>;
+
+// Import explicit instantiation definition of a non-imported variable template.
+template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>;
+
+// Import specialization of a non-imported variable template.
+template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>;
+template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Def_Imported> = 1; // expected-error{{definition of dllimport data}}
+
+#endif // __has_feature(cxx_variable_templates)
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Import function declaration. Check different placements.
+__attribute__((dllimport)) void decl1A(); // Sanity check with __attribute__
+__declspec(dllimport) void decl1B();
+
+void __attribute__((dllimport)) decl2A();
+void __declspec(dllimport) decl2B();
+
+// Not allowed on function definitions.
+__declspec(dllimport) void def() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
+
+// extern "C"
+extern "C" __declspec(dllimport) void externC();
+
+// Import inline function.
+__declspec(dllimport) inline void inlineFunc1() {}
+inline void __attribute__((dllimport)) inlineFunc2() {}
+
+__declspec(dllimport) inline void inlineDecl();
+ void inlineDecl() {}
+
+__declspec(dllimport) void inlineDef();
+ inline void inlineDef() {}
+
+// Redeclarations
+__declspec(dllimport) void redecl1();
+__declspec(dllimport) void redecl1();
+
+// NB: MSVC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
+// and drop the dllimport with a warning.
+__declspec(dllimport) void redecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ void redecl2(); // expected-warning{{'redecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+__declspec(dllimport) void redecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ void redecl3() {} // expected-warning{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+ void redecl4(); // expected-note{{previous declaration is here}}
+__declspec(dllimport) void redecl4(); // expected-error{{redeclaration of 'redecl4' cannot add 'dllimport' attribute}}
+
+ void redecl5(); // expected-note{{previous declaration is here}}
+__declspec(dllimport) inline void redecl5() {} // expected-error{{redeclaration of 'redecl5' cannot add 'dllimport' attribute}}
+
+// Friend functions
+struct FuncFriend {
+ friend __declspec(dllimport) void friend1();
+ friend __declspec(dllimport) void friend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ friend __declspec(dllimport) void friend3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ friend void friend4(); // expected-note{{previous declaration is here}}
+ friend void friend5(); // expected-note{{previous declaration is here}}
+};
+__declspec(dllimport) void friend1();
+ void friend2(); // expected-warning{{'friend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+ void friend3() {} // expected-warning{{'friend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+__declspec(dllimport) void friend4(); // expected-error{{redeclaration of 'friend4' cannot add 'dllimport' attribute}}
+__declspec(dllimport) inline void friend5() {} // expected-error{{redeclaration of 'friend5' cannot add 'dllimport' attribute}}
+
+// Implicit declarations can be redeclared with dllimport.
+__declspec(dllimport) void* operator new(__SIZE_TYPE__ n);
+
+// External linkage is required.
+__declspec(dllimport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllimport'}}
+__declspec(dllimport) Internal internalRetFunc(); // expected-error{{'internalRetFunc' must have external linkage when declared 'dllimport'}}
+namespace { __declspec(dllimport) void internalFunc(); } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllimport'}}
+namespace ns { __declspec(dllimport) void externalFunc(); }
+
+// Import deleted functions.
+// FIXME: Deleted functions are definitions so a missing inline is diagnosed
+// here which is irrelevant. But because the delete keyword is parsed later
+// there is currently no straight-forward way to avoid this diagnostic.
+__declspec(dllimport) void deletedFunc() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} expected-error{{dllimport cannot be applied to non-inline function definition}}
+__declspec(dllimport) inline void deletedInlineFunc() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Function templates
+//===----------------------------------------------------------------------===//
+
+// Import function template declaration. Check different placements.
+template<typename T> __declspec(dllimport) void funcTmplDecl1();
+template<typename T> void __declspec(dllimport) funcTmplDecl2();
+
+// Import function template definition.
+template<typename T> __declspec(dllimport) void funcTmplDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
+
+// Import inline function template.
+template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {}
+template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {}
+
+template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl();
+template<typename T> void inlineFuncTmplDecl() {}
+
+template<typename T> __declspec(dllimport) void inlineFuncTmplDef();
+template<typename T> inline void inlineFuncTmplDef() {}
+
+// Redeclarations
+template<typename T> __declspec(dllimport) void funcTmplRedecl1();
+template<typename T> __declspec(dllimport) void funcTmplRedecl1();
+
+template<typename T> __declspec(dllimport) void funcTmplRedecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+template<typename T> void funcTmplRedecl2(); // expected-warning{{'funcTmplRedecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+template<typename T> __declspec(dllimport) void funcTmplRedecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+template<typename T> void funcTmplRedecl3() {} // expected-warning{{'funcTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+template<typename T> void funcTmplRedecl4(); // expected-note{{previous declaration is here}}
+template<typename T> __declspec(dllimport) void funcTmplRedecl4(); // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllimport' attribute}}
+
+template<typename T> void funcTmplRedecl5(); // expected-note{{previous declaration is here}}
+template<typename T> __declspec(dllimport) inline void funcTmplRedecl5() {} // expected-error{{redeclaration of 'funcTmplRedecl5' cannot add 'dllimport' attribute}}
+
+// Function template friends
+struct FuncTmplFriend {
+ template<typename T> friend __declspec(dllimport) void funcTmplFriend1();
+ template<typename T> friend __declspec(dllimport) void funcTmplFriend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ template<typename T> friend __declspec(dllimport) void funcTmplFriend3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ template<typename T> friend void funcTmplFriend4(); // expected-note{{previous declaration is here}}
+ template<typename T> friend __declspec(dllimport) inline void funcTmplFriend5();
+};
+template<typename T> __declspec(dllimport) void funcTmplFriend1();
+template<typename T> void funcTmplFriend2(); // expected-warning{{'funcTmplFriend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T> void funcTmplFriend3() {} // expected-warning{{'funcTmplFriend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T> __declspec(dllimport) void funcTmplFriend4(); // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllimport' attribute}}
+template<typename T> inline void funcTmplFriend5() {}
+
+// External linkage is required.
+template<typename T> __declspec(dllimport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllimport'}}
+template<typename T> __declspec(dllimport) Internal internalRetFuncTmpl(); // expected-error{{'internalRetFuncTmpl' must have external linkage when declared 'dllimport'}}
+namespace { template<typename T> __declspec(dllimport) void internalFuncTmpl(); } // expected-error{{'(anonymous namespace)::internalFuncTmpl' must have external linkage when declared 'dllimport'}}
+namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); }
+
+
+template<typename T> void funcTmpl() {}
+template<typename T> inline void inlineFuncTmpl() {}
+template<typename T> __declspec(dllimport) void importedFuncTmplDecl();
+template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {}
+
+// Import implicit instantiation of an imported function template.
+void useFunTmplDecl() { importedFuncTmplDecl<ImplicitInst_Imported>(); }
+void useFunTmplDef() { importedFuncTmpl<ImplicitInst_Imported>(); }
+
+// Import explicit instantiation declaration of an imported function template.
+extern template void importedFuncTmpl<ExplicitDecl_Imported>();
+
+// Import explicit instantiation definition of an imported function template.
+// NB: MSVC fails this instantiation without explicit dllimport which is most
+// likely a bug because an implicit instantiation is accepted.
+template void importedFuncTmpl<ExplicitInst_Imported>();
+
+// Import specialization of an imported function template. A definition must be
+// declared inline.
+template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();
+template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
+template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {}
+
+// Not importing specialization of an imported function template without
+// explicit dllimport.
+template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {}
+
+
+// Import explicit instantiation declaration of a non-imported function template.
+extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>();
+extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>();
+
+// Import explicit instantiation definition of a non-imported function template.
+template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>();
+template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>();
+
+// Import specialization of a non-imported function template. A definition must
+// be declared inline.
+template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();
+template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
+template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
+
+
+//===----------------------------------------------------------------------===//
+// Class members
+//===----------------------------------------------------------------------===//
+
+// Import individual members of a class.
+struct ImportMembers {
+ struct Nested {
+ __declspec(dllimport) void normalDecl();
+ __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ };
+
+ __declspec(dllimport) void normalDecl();
+ __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ __declspec(dllimport) void normalInclass() {}
+ __declspec(dllimport) void normalInlineDef();
+ __declspec(dllimport) inline void normalInlineDecl();
+ __declspec(dllimport) virtual void virtualDecl();
+ __declspec(dllimport) virtual void virtualDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ __declspec(dllimport) virtual void virtualInclass() {}
+ __declspec(dllimport) virtual void virtualInlineDef();
+ __declspec(dllimport) virtual inline void virtualInlineDecl();
+ __declspec(dllimport) static void staticDecl();
+ __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ __declspec(dllimport) static void staticInclass() {}
+ __declspec(dllimport) static void staticInlineDef();
+ __declspec(dllimport) static inline void staticInlineDecl();
+
+protected:
+ __declspec(dllimport) void protectedDecl();
+private:
+ __declspec(dllimport) void privateDecl();
+public:
+
+ __declspec(dllimport) int Field; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+ __declspec(dllimport) static int StaticField;
+ __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}}
+ __declspec(dllimport) static const int StaticConstField;
+ __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}}
+ __declspec(dllimport) static const int StaticConstFieldEqualInit = 1;
+ __declspec(dllimport) static const int StaticConstFieldBraceInit{1};
+ __declspec(dllimport) constexpr static int ConstexprField = 1;
+ __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
+};
+
+ void ImportMembers::Nested::normalDef() {} // expected-warning{{'ImportMembers::Nested::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+ void ImportMembers::normalDef() {} // expected-warning{{'ImportMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+inline void ImportMembers::normalInlineDef() {}
+ void ImportMembers::normalInlineDecl() {}
+ void ImportMembers::virtualDef() {} // expected-warning{{'ImportMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+inline void ImportMembers::virtualInlineDef() {}
+ void ImportMembers::virtualInlineDecl() {}
+ void ImportMembers::staticDef() {} // expected-warning{{'ImportMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+inline void ImportMembers::staticInlineDef() {}
+ void ImportMembers::staticInlineDecl() {}
+
+ int ImportMembers::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}}
+const int ImportMembers::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}}
+constexpr int ImportMembers::ConstexprFieldDef; // expected-error{{definition of dllimport static field not allowed}}
+
+
+// Import on member definitions.
+struct ImportMemberDefs {
+ __declspec(dllimport) void normalDef();
+ __declspec(dllimport) void normalInlineDef();
+ __declspec(dllimport) inline void normalInlineDecl();
+ __declspec(dllimport) virtual void virtualDef();
+ __declspec(dllimport) virtual void virtualInlineDef();
+ __declspec(dllimport) virtual inline void virtualInlineDecl();
+ __declspec(dllimport) static void staticDef();
+ __declspec(dllimport) static void staticInlineDef();
+ __declspec(dllimport) static inline void staticInlineDecl();
+
+ __declspec(dllimport) static int StaticField;
+ __declspec(dllimport) static const int StaticConstField;
+ __declspec(dllimport) constexpr static int ConstexprField = 1;
+};
+
+__declspec(dllimport) void ImportMemberDefs::normalDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
+__declspec(dllimport) inline void ImportMemberDefs::normalInlineDef() {}
+__declspec(dllimport) void ImportMemberDefs::normalInlineDecl() {}
+__declspec(dllimport) void ImportMemberDefs::virtualDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
+__declspec(dllimport) inline void ImportMemberDefs::virtualInlineDef() {}
+__declspec(dllimport) void ImportMemberDefs::virtualInlineDecl() {}
+__declspec(dllimport) void ImportMemberDefs::staticDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
+__declspec(dllimport) inline void ImportMemberDefs::staticInlineDef() {}
+__declspec(dllimport) void ImportMemberDefs::staticInlineDecl() {}
+
+__declspec(dllimport) int ImportMemberDefs::StaticField; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
+__declspec(dllimport) const int ImportMemberDefs::StaticConstField = 1; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
+__declspec(dllimport) constexpr int ImportMemberDefs::ConstexprField; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
+
+
+// Import special member functions.
+struct ImportSpecials {
+ __declspec(dllimport) ImportSpecials();
+ __declspec(dllimport) ~ImportSpecials();
+ __declspec(dllimport) ImportSpecials(const ImportSpecials&);
+ __declspec(dllimport) ImportSpecials& operator=(const ImportSpecials&);
+ __declspec(dllimport) ImportSpecials(ImportSpecials&&);
+ __declspec(dllimport) ImportSpecials& operator=(ImportSpecials&&);
+};
+
+
+// Import deleted member functions.
+struct ImportDeleted {
+ __declspec(dllimport) ImportDeleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+ __declspec(dllimport) ~ImportDeleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+ __declspec(dllimport) ImportDeleted(const ImportDeleted&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+ __declspec(dllimport) ImportDeleted& operator=(const ImportDeleted&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+ __declspec(dllimport) ImportDeleted(ImportDeleted&&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+ __declspec(dllimport) ImportDeleted& operator=(ImportDeleted&&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+ __declspec(dllimport) void deleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+};
+
+
+// Import allocation functions.
+struct ImportAlloc {
+ __declspec(dllimport) void* operator new(__SIZE_TYPE__);
+ __declspec(dllimport) void* operator new[](__SIZE_TYPE__);
+ __declspec(dllimport) void operator delete(void*);
+ __declspec(dllimport) void operator delete[](void*);
+};
+
+
+// Import defaulted member functions.
+struct ImportDefaulted {
+ __declspec(dllimport) ImportDefaulted() = default;
+ __declspec(dllimport) ~ImportDefaulted() = default;
+ __declspec(dllimport) ImportDefaulted(const ImportDefaulted&) = default;
+ __declspec(dllimport) ImportDefaulted& operator=(const ImportDefaulted&) = default;
+ __declspec(dllimport) ImportDefaulted(ImportDefaulted&&) = default;
+ __declspec(dllimport) ImportDefaulted& operator=(ImportDefaulted&&) = default;
+};
+
+
+// Import defaulted member function definitions.
+struct ImportDefaultedDefs {
+ __declspec(dllimport) ImportDefaultedDefs();
+ __declspec(dllimport) ~ImportDefaultedDefs(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+
+ __declspec(dllimport) inline ImportDefaultedDefs(const ImportDefaultedDefs&);
+ __declspec(dllimport) ImportDefaultedDefs& operator=(const ImportDefaultedDefs&);
+
+ __declspec(dllimport) ImportDefaultedDefs(ImportDefaultedDefs&&);
+ __declspec(dllimport) ImportDefaultedDefs& operator=(ImportDefaultedDefs&&); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+};
+
+// Not allowed on definitions.
+__declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs() = default; // expected-error{{dllimport cannot be applied to non-inline function definition}}
+
+// dllimport cannot be dropped.
+ImportDefaultedDefs::~ImportDefaultedDefs() = default; // expected-warning{{'ImportDefaultedDefs::~ImportDefaultedDefs' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+// Import inline declaration and definition.
+__declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs(const ImportDefaultedDefs&) = default;
+inline ImportDefaultedDefs& ImportDefaultedDefs::operator=(const ImportDefaultedDefs&) = default;
+
+__declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs(ImportDefaultedDefs&&) = default; // expected-error{{dllimport cannot be applied to non-inline function definition}}
+ImportDefaultedDefs& ImportDefaultedDefs::operator=(ImportDefaultedDefs&&) = default; // expected-warning{{'ImportDefaultedDefs::operator=' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+
+// Redeclarations cannot add dllimport.
+struct MemberRedecl {
+ void normalDef(); // expected-note{{previous declaration is here}}
+ void normalInlineDef(); // expected-note{{previous declaration is here}}
+ inline void normalInlineDecl(); // expected-note{{previous declaration is here}}
+ virtual void virtualDef(); // expected-note{{previous declaration is here}}
+ virtual void virtualInlineDef(); // expected-note{{previous declaration is here}}
+ virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}}
+ static void staticDef(); // expected-note{{previous declaration is here}}
+ static void staticInlineDef(); // expected-note{{previous declaration is here}}
+ static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
+
+ static int StaticField; // expected-note{{previous declaration is here}}
+ static const int StaticConstField; // expected-note{{previous declaration is here}}
+ constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
+};
+
+__declspec(dllimport) void MemberRedecl::normalDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllimport' attribute}}
+ // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
+__declspec(dllimport) inline void MemberRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDef' cannot add 'dllimport' attribute}}
+__declspec(dllimport) void MemberRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDecl' cannot add 'dllimport' attribute}}
+__declspec(dllimport) void MemberRedecl::virtualDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualDef' cannot add 'dllimport' attribute}}
+ // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
+__declspec(dllimport) inline void MemberRedecl::virtualInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDef' cannot add 'dllimport' attribute}}
+__declspec(dllimport) void MemberRedecl::virtualInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDecl' cannot add 'dllimport' attribute}}
+__declspec(dllimport) void MemberRedecl::staticDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticDef' cannot add 'dllimport' attribute}}
+ // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
+__declspec(dllimport) inline void MemberRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllimport' attribute}}
+__declspec(dllimport) void MemberRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllimport' attribute}}
+
+__declspec(dllimport) int MemberRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllimport' attribute}}
+ // expected-error@-1{{definition of dllimport static field not allowed}}
+ // expected-note@-2{{attribute is here}}
+__declspec(dllimport) const int MemberRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllimport' attribute}}
+ // expected-error@-1{{definition of dllimport static field not allowed}}
+ // expected-note@-2{{attribute is here}}
+__declspec(dllimport) constexpr int MemberRedecl::ConstexprField; // expected-error{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllimport' attribute}}
+ // expected-error@-1{{definition of dllimport static field not allowed}}
+ // expected-note@-2{{attribute is here}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Class member templates
+//===----------------------------------------------------------------------===//
+
+struct ImportMemberTmpl {
+ template<typename T> __declspec(dllimport) void normalDecl();
+ template<typename T> __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ template<typename T> __declspec(dllimport) void normalInclass() {}
+ template<typename T> __declspec(dllimport) void normalInlineDef();
+ template<typename T> __declspec(dllimport) inline void normalInlineDecl();
+ template<typename T> __declspec(dllimport) static void staticDecl();
+ template<typename T> __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ template<typename T> __declspec(dllimport) static void staticInclass() {}
+ template<typename T> __declspec(dllimport) static void staticInlineDef();
+ template<typename T> __declspec(dllimport) static inline void staticInlineDecl();
+
+#if __has_feature(cxx_variable_templates)
+ template<typename T> __declspec(dllimport) static int StaticField;
+ template<typename T> __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}}
+ template<typename T> __declspec(dllimport) static const int StaticConstField;
+ template<typename T> __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}}
+ template<typename T> __declspec(dllimport) static const int StaticConstFieldEqualInit = 1;
+ template<typename T> __declspec(dllimport) static const int StaticConstFieldBraceInit{1};
+ template<typename T> __declspec(dllimport) constexpr static int ConstexprField = 1;
+ template<typename T> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
+#endif // __has_feature(cxx_variable_templates)
+};
+
+template<typename T> void ImportMemberTmpl::normalDef() {} // expected-warning{{'ImportMemberTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T> inline void ImportMemberTmpl::normalInlineDef() {}
+template<typename T> void ImportMemberTmpl::normalInlineDecl() {}
+template<typename T> void ImportMemberTmpl::staticDef() {} // expected-warning{{'ImportMemberTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T> inline void ImportMemberTmpl::staticInlineDef() {}
+template<typename T> void ImportMemberTmpl::staticInlineDecl() {}
+
+#if __has_feature(cxx_variable_templates)
+template<typename T> int ImportMemberTmpl::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}}
+template<typename T> const int ImportMemberTmpl::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}}
+template<typename T> constexpr int ImportMemberTmpl::ConstexprFieldDef; // expected-error{{definition of dllimport static field not allowed}}
+#endif // __has_feature(cxx_variable_templates)
+
+
+// Redeclarations cannot add dllimport.
+struct MemTmplRedecl {
+ template<typename T> void normalDef(); // expected-note{{previous declaration is here}}
+ template<typename T> void normalInlineDef(); // expected-note{{previous declaration is here}}
+ template<typename T> inline void normalInlineDecl(); // expected-note{{previous declaration is here}}
+ template<typename T> static void staticDef(); // expected-note{{previous declaration is here}}
+ template<typename T> static void staticInlineDef(); // expected-note{{previous declaration is here}}
+ template<typename T> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
+
+#if __has_feature(cxx_variable_templates)
+ template<typename T> static int StaticField; // expected-note{{previous declaration is here}}
+ template<typename T> static const int StaticConstField; // expected-note{{previous declaration is here}}
+ template<typename T> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
+#endif // __has_feature(cxx_variable_templates)
+};
+
+template<typename T> __declspec(dllimport) void MemTmplRedecl::normalDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalDef' cannot add 'dllimport' attribute}}
+ // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
+template<typename T> __declspec(dllimport) inline void MemTmplRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDef' cannot add 'dllimport' attribute}}
+template<typename T> __declspec(dllimport) void MemTmplRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDecl' cannot add 'dllimport' attribute}}
+template<typename T> __declspec(dllimport) void MemTmplRedecl::staticDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticDef' cannot add 'dllimport' attribute}}
+ // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
+template<typename T> __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllimport' attribute}}
+template<typename T> __declspec(dllimport) void MemTmplRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllimport' attribute}}
+
+#if __has_feature(cxx_variable_templates)
+template<typename T> __declspec(dllimport) int MemTmplRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllimport' attribute}}
+ // expected-error@-1{{definition of dllimport static field not allowed}}
+ // expected-note@-2{{attribute is here}}
+template<typename T> __declspec(dllimport) const int MemTmplRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllimport' attribute}}
+ // expected-error@-1{{definition of dllimport static field not allowed}}
+ // expected-note@-2{{attribute is here}}
+template<typename T> __declspec(dllimport) constexpr int MemTmplRedecl::ConstexprField; // expected-error{{redeclaration of 'MemTmplRedecl::ConstexprField' cannot add 'dllimport' attribute}}
+ // expected-error@-1{{definition of dllimport static field not allowed}}
+ // expected-note@-2{{attribute is here}}
+#endif // __has_feature(cxx_variable_templates)
+
+
+
+struct MemFunTmpl {
+ template<typename T> void normalDef() {}
+ template<typename T> __declspec(dllimport) void importedNormal() {}
+ template<typename T> static void staticDef() {}
+ template<typename T> __declspec(dllimport) static void importedStatic() {}
+};
+
+// Import implicit instantiation of an imported member function template.
+void useMemFunTmpl() {
+ MemFunTmpl().importedNormal<ImplicitInst_Imported>();
+ MemFunTmpl().importedStatic<ImplicitInst_Imported>();
+}
+
+// Import explicit instantiation declaration of an imported member function
+// template.
+extern template void MemFunTmpl::importedNormal<ExplicitDecl_Imported>();
+extern template void MemFunTmpl::importedStatic<ExplicitDecl_Imported>();
+
+// Import explicit instantiation definition of an imported member function
+// template.
+// NB: MSVC fails this instantiation without explicit dllimport.
+template void MemFunTmpl::importedNormal<ExplicitInst_Imported>();
+template void MemFunTmpl::importedStatic<ExplicitInst_Imported>();
+
+// Import specialization of an imported member function template.
+template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Imported>();
+template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Def_Imported>() {} // error on mingw
+template<> __declspec(dllimport) inline void MemFunTmpl::importedNormal<ExplicitSpec_InlineDef_Imported>() {}
+#ifndef MSABI
+// expected-error@-3{{dllimport cannot be applied to non-inline function definition}}
+#endif
+
+template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Imported>();
+template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Def_Imported>() {} // error on mingw
+template<> __declspec(dllimport) inline void MemFunTmpl::importedStatic<ExplicitSpec_InlineDef_Imported>() {}
+#ifndef MSABI
+// expected-error@-3{{dllimport cannot be applied to non-inline function definition}}
+#endif
+
+// Not importing specialization of an imported member function template without
+// explicit dllimport.
+template<> void MemFunTmpl::importedNormal<ExplicitSpec_NotImported>() {}
+template<> void MemFunTmpl::importedStatic<ExplicitSpec_NotImported>() {}
+
+
+// Import explicit instantiation declaration of a non-imported member function
+// template.
+extern template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitDecl_Imported>();
+extern template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitDecl_Imported>();
+
+// Import explicit instantiation definition of a non-imported member function
+// template.
+template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitInst_Imported>();
+template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitInst_Imported>();
+
+// Import specialization of a non-imported member function template.
+template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Imported>();
+template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Imported>() {} // error on mingw
+template<> __declspec(dllimport) inline void MemFunTmpl::normalDef<ExplicitSpec_InlineDef_Imported>() {}
+#ifndef MSABI
+// expected-error@-3{{dllimport cannot be applied to non-inline function definition}}
+#endif
+
+template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Imported>();
+template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Imported>() {} // error on mingw
+template<> __declspec(dllimport) inline void MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Imported>() {}
+#ifndef MSABI
+// expected-error@-3{{dllimport cannot be applied to non-inline function definition}}
+#endif
+
+
+
+#if __has_feature(cxx_variable_templates)
+struct MemVarTmpl {
+ template<typename T> static const int StaticVar = 1;
+ template<typename T> __declspec(dllimport) static const int ImportedStaticVar = 1;
+};
+
+// Import implicit instantiation of an imported member variable template.
+int useMemVarTmpl() { return MemVarTmpl::ImportedStaticVar<ImplicitInst_Imported>; }
+
+// Import explicit instantiation declaration of an imported member variable
+// template.
+extern template const int MemVarTmpl::ImportedStaticVar<ExplicitDecl_Imported>;
+
+// An explicit instantiation definition of an imported member variable template
+// cannot be imported because the template must be defined which is illegal. The
+// in-class initializer does not count.
+
+// Import specialization of an imported member variable template.
+template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Imported>;
+template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Def_Imported> = 1;
+ // expected-error@-1{{definition of dllimport static field not allowed}}
+ // expected-note@-2{{attribute is here}}
+
+// Not importing specialization of a member variable template without explicit
+// dllimport.
+template<> const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_NotImported>;
+
+
+// Import explicit instantiation declaration of a non-imported member variable
+// template.
+extern template __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitDecl_Imported>;
+
+// An explicit instantiation definition of a non-imported member variable template
+// cannot be imported because the template must be defined which is illegal. The
+// in-class initializer does not count.
+
+// Import specialization of a non-imported member variable template.
+template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Imported>;
+template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Imported> = 1;
+ // expected-error@-1{{definition of dllimport static field not allowed}}
+ // expected-note@-2{{attribute is here}}
+
+#endif // __has_feature(cxx_variable_templates)
+
+
+
+//===----------------------------------------------------------------------===//
+// Class template members
+//===----------------------------------------------------------------------===//
+
+// Import individual members of a class template.
+template<typename T>
+struct ImportClassTmplMembers {
+ __declspec(dllimport) void normalDecl();
+ __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ __declspec(dllimport) void normalInclass() {}
+ __declspec(dllimport) void normalInlineDef();
+ __declspec(dllimport) inline void normalInlineDecl();
+ __declspec(dllimport) virtual void virtualDecl();
+ __declspec(dllimport) virtual void virtualDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ __declspec(dllimport) virtual void virtualInclass() {}
+ __declspec(dllimport) virtual void virtualInlineDef();
+ __declspec(dllimport) virtual inline void virtualInlineDecl();
+ __declspec(dllimport) static void staticDecl();
+ __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ __declspec(dllimport) static void staticInclass() {}
+ __declspec(dllimport) static void staticInlineDef();
+ __declspec(dllimport) static inline void staticInlineDecl();
+
+protected:
+ __declspec(dllimport) void protectedDecl();
+private:
+ __declspec(dllimport) void privateDecl();
+public:
+
+ __declspec(dllimport) int Field; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+ __declspec(dllimport) static int StaticField;
+ __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}}
+ __declspec(dllimport) static const int StaticConstField;
+ __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}}
+ __declspec(dllimport) static const int StaticConstFieldEqualInit = 1;
+ __declspec(dllimport) static const int StaticConstFieldBraceInit{1};
+ __declspec(dllimport) constexpr static int ConstexprField = 1;
+ __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
+};
+
+// NB: MSVC is inconsistent here and disallows *InlineDef on class templates,
+// but allows it on classes. We allow both.
+template<typename T> void ImportClassTmplMembers<T>::normalDef() {} // expected-warning{{'ImportClassTmplMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T> inline void ImportClassTmplMembers<T>::normalInlineDef() {}
+template<typename T> void ImportClassTmplMembers<T>::normalInlineDecl() {}
+template<typename T> void ImportClassTmplMembers<T>::virtualDef() {} // expected-warning{{'ImportClassTmplMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T> inline void ImportClassTmplMembers<T>::virtualInlineDef() {}
+template<typename T> void ImportClassTmplMembers<T>::virtualInlineDecl() {}
+template<typename T> void ImportClassTmplMembers<T>::staticDef() {} // expected-warning{{'ImportClassTmplMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T> inline void ImportClassTmplMembers<T>::staticInlineDef() {}
+template<typename T> void ImportClassTmplMembers<T>::staticInlineDecl() {}
+
+template<typename T> int ImportClassTmplMembers<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}}
+template<typename T> const int ImportClassTmplMembers<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}}
+template<typename T> constexpr int ImportClassTmplMembers<T>::ConstexprFieldDef; // expected-warning{{definition of dllimport static field}}
+
+
+// Redeclarations cannot add dllimport.
+template<typename T>
+struct CTMR /*ClassTmplMemberRedecl*/ {
+ void normalDef(); // expected-note{{previous declaration is here}}
+ void normalInlineDef(); // expected-note{{previous declaration is here}}
+ inline void normalInlineDecl(); // expected-note{{previous declaration is here}}
+ virtual void virtualDef(); // expected-note{{previous declaration is here}}
+ virtual void virtualInlineDef(); // expected-note{{previous declaration is here}}
+ virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}}
+ static void staticDef(); // expected-note{{previous declaration is here}}
+ static void staticInlineDef(); // expected-note{{previous declaration is here}}
+ static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
+
+ static int StaticField; // expected-note{{previous declaration is here}}
+ static const int StaticConstField; // expected-note{{previous declaration is here}}
+ constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
+};
+
+template<typename T> __declspec(dllimport) void CTMR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllimport' attribute}}
+ // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
+template<typename T> __declspec(dllimport) inline void CTMR<T>::normalInlineDef() {} // expected-error{{redeclaration of 'CTMR::normalInlineDef' cannot add 'dllimport' attribute}}
+template<typename T> __declspec(dllimport) void CTMR<T>::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMR::normalInlineDecl' cannot add 'dllimport' attribute}}
+template<typename T> __declspec(dllimport) void CTMR<T>::virtualDef() {} // expected-error{{redeclaration of 'CTMR::virtualDef' cannot add 'dllimport' attribute}}
+ // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
+template<typename T> __declspec(dllimport) inline void CTMR<T>::virtualInlineDef() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDef' cannot add 'dllimport' attribute}}
+template<typename T> __declspec(dllimport) void CTMR<T>::virtualInlineDecl() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDecl' cannot add 'dllimport' attribute}}
+template<typename T> __declspec(dllimport) void CTMR<T>::staticDef() {} // expected-error{{redeclaration of 'CTMR::staticDef' cannot add 'dllimport' attribute}}
+ // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
+template<typename T> __declspec(dllimport) inline void CTMR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllimport' attribute}}
+template<typename T> __declspec(dllimport) void CTMR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllimport' attribute}}
+
+template<typename T> __declspec(dllimport) int CTMR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllimport' attribute}}
+ // expected-warning@-1{{definition of dllimport static field}}
+ // expected-note@-2{{attribute is here}}
+template<typename T> __declspec(dllimport) const int CTMR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllimport' attribute}}
+ // expected-warning@-1{{definition of dllimport static field}}
+ // expected-note@-2{{attribute is here}}
+template<typename T> __declspec(dllimport) constexpr int CTMR<T>::ConstexprField; // expected-error{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllimport' attribute}}
+ // expected-warning@-1{{definition of dllimport static field}}
+ // expected-note@-2{{attribute is here}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Class template member templates
+//===----------------------------------------------------------------------===//
+
+template<typename T>
+struct ImportClsTmplMemTmpl {
+ template<typename U> __declspec(dllimport) void normalDecl();
+ template<typename U> __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ template<typename U> __declspec(dllimport) void normalInclass() {}
+ template<typename U> __declspec(dllimport) void normalInlineDef();
+ template<typename U> __declspec(dllimport) inline void normalInlineDecl();
+ template<typename U> __declspec(dllimport) static void staticDecl();
+ template<typename U> __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ template<typename U> __declspec(dllimport) static void staticInclass() {}
+ template<typename U> __declspec(dllimport) static void staticInlineDef();
+ template<typename U> __declspec(dllimport) static inline void staticInlineDecl();
+
+#if __has_feature(cxx_variable_templates)
+ template<typename U> __declspec(dllimport) static int StaticField;
+ template<typename U> __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}}
+ template<typename U> __declspec(dllimport) static const int StaticConstField;
+ template<typename U> __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}}
+ template<typename U> __declspec(dllimport) static const int StaticConstFieldEqualInit = 1;
+ template<typename U> __declspec(dllimport) static const int StaticConstFieldBraceInit{1};
+ template<typename U> __declspec(dllimport) constexpr static int ConstexprField = 1;
+ template<typename U> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
+#endif // __has_feature(cxx_variable_templates)
+};
+
+template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::normalDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::normalInlineDef() {}
+template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::normalInlineDecl() {}
+template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::staticDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::staticInlineDef() {}
+template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::staticInlineDecl() {}
+
+#if __has_feature(cxx_variable_templates)
+template<typename T> template<typename U> int ImportClsTmplMemTmpl<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}}
+template<typename T> template<typename U> const int ImportClsTmplMemTmpl<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}}
+template<typename T> template<typename U> constexpr int ImportClsTmplMemTmpl<T>::ConstexprFieldDef; // expected-warning{{definition of dllimport static field}}
+#endif // __has_feature(cxx_variable_templates)
+
+
+// Redeclarations cannot add dllimport.
+template<typename T>
+struct CTMTR /*ClassTmplMemberTmplRedecl*/ {
+ template<typename U> void normalDef(); // expected-note{{previous declaration is here}}
+ template<typename U> void normalInlineDef(); // expected-note{{previous declaration is here}}
+ template<typename U> inline void normalInlineDecl(); // expected-note{{previous declaration is here}}
+ template<typename U> static void staticDef(); // expected-note{{previous declaration is here}}
+ template<typename U> static void staticInlineDef(); // expected-note{{previous declaration is here}}
+ template<typename U> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
+
+#if __has_feature(cxx_variable_templates)
+ template<typename U> static int StaticField; // expected-note{{previous declaration is here}}
+ template<typename U> static const int StaticConstField; // expected-note{{previous declaration is here}}
+ template<typename U> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
+#endif // __has_feature(cxx_variable_templates)
+};
+
+template<typename T> template<typename U> __declspec(dllimport) void CTMTR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllimport' attribute}}
+ // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
+template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::normalInlineDef() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDef' cannot add 'dllimport' attribute}}
+template<typename T> template<typename U> __declspec(dllimport) void CTMTR<T>::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDecl' cannot add 'dllimport' attribute}}
+template<typename T> template<typename U> __declspec(dllimport) void CTMTR<T>::staticDef() {} // expected-error{{redeclaration of 'CTMTR::staticDef' cannot add 'dllimport' attribute}}
+ // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
+template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllimport' attribute}}
+template<typename T> template<typename U> __declspec(dllimport) void CTMTR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllimport' attribute}}
+
+#if __has_feature(cxx_variable_templates)
+template<typename T> template<typename U> __declspec(dllimport) int CTMTR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllimport' attribute}}
+ // expected-warning@-1{{definition of dllimport static field}}
+ // expected-note@-2{{attribute is here}}
+template<typename T> template<typename U> __declspec(dllimport) const int CTMTR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllimport' attribute}}
+ // expected-warning@-1{{definition of dllimport static field}}
+ // expected-note@-2{{attribute is here}}
+template<typename T> template<typename U> __declspec(dllimport) constexpr int CTMTR<T>::ConstexprField; // expected-error{{redeclaration of 'CTMTR::ConstexprField' cannot add 'dllimport' attribute}}
+ // expected-warning@-1{{definition of dllimport static field}}
+ // expected-note@-2{{attribute is here}}
+#endif // __has_feature(cxx_variable_templates)
+
+
+
+//===----------------------------------------------------------------------===//
+// Classes
+//===----------------------------------------------------------------------===//
+
+class __declspec(dllimport) ClassDecl;
+
+class __declspec(dllimport) ClassDef { };
+
+template <typename T> class ClassTemplate {};
+
+#ifdef MS
+// expected-note@+5{{previous attribute is here}}
+// expected-note@+4{{previous attribute is here}}
+// expected-error@+4{{attribute 'dllexport' cannot be applied to member of 'dllimport' class}}
+// expected-error@+4{{attribute 'dllimport' cannot be applied to member of 'dllimport' class}}
+#endif
+class __declspec(dllimport) ImportClassWithDllMember {
+ void __declspec(dllexport) foo();
+ void __declspec(dllimport) bar();
+};
+
+#ifdef MS
+// expected-note@+5{{previous attribute is here}}
+// expected-note@+4{{previous attribute is here}}
+// expected-error@+4{{attribute 'dllimport' cannot be applied to member of 'dllexport' class}}
+// expected-error@+4{{attribute 'dllexport' cannot be applied to member of 'dllexport' class}}
+#endif
+class __declspec(dllexport) ExportClassWithDllMember {
+ void __declspec(dllimport) foo();
+ void __declspec(dllexport) bar();
+};
+
+namespace ImportedExplicitSpecialization {
+template <typename T> struct S { static int x; };
+template <typename T> int S<T>::x = sizeof(T);
+template <> struct __declspec(dllimport) S<int> { static int x; }; // expected-note{{attribute is here}}
+int S<int>::x = -1; // expected-error{{definition of dllimport static field not allowed}}
+}
+
+namespace PR19988 {
+// Don't error about applying delete to dllimport member function when instantiating.
+template <typename> struct __declspec(dllimport) S {
+ void foo() = delete;
+};
+S<int> s;
+}
+
+#ifdef MS
+// expected-warning@+3{{'dllimport' attribute ignored}}
+#endif
+template <typename T> struct PartiallySpecializedClassTemplate {};
+template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f() {} };
+
+template <typename T> struct ExpliciallySpecializedClassTemplate {};
+template <> struct __declspec(dllimport) ExpliciallySpecializedClassTemplate<int> { void f() {} };
+
+
+//===----------------------------------------------------------------------===//
+// Classes with template base classes
+//===----------------------------------------------------------------------===//
+
+template <typename T> class __declspec(dllexport) ExportedClassTemplate {};
+
+template <typename T> class __declspec(dllimport) ImportedClassTemplate {};
+
+// ClassTemplate<int> gets imported.
+class __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {};
+
+// ClassTemplate<int> is already imported.
+class __declspec(dllimport) DerivedFromTemplate2 : public ClassTemplate<int> {};
+
+// ImportedClassTemplate is expliitly imported.
+class __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
+
+// ExportedClassTemplate is explicitly exported.
+class __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
+
+#ifdef MS
+// expected-note@+4{{class template 'ClassTemplate<double>' was instantiated here}}
+// expected-warning@+4{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}}
+// expected-note@+3{{attribute is here}}
+#endif
+class DerivedFromTemplateD : public ClassTemplate<double> {};
+class __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
+
+#ifdef MS
+// expected-note@+4{{class template 'ClassTemplate<bool>' was instantiated here}}
+// expected-warning@+4{{propagating dll attribute to already instantiated base class template with different dll attribute is not supported}}
+// expected-note@+3{{attribute is here}}
+#endif
+class __declspec(dllexport) DerivedFromTemplateB : public ClassTemplate<bool> {};
+class __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
+
+template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
+#ifdef MS
+// expected-note@+2{{class template 'ExplicitlySpecializedTemplate<int>' was explicitly specialized here}}
+#endif
+template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
+
+template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
+#ifdef MS
+// expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate<int>' was instantiated here}}
+#endif
+template struct ExplicitlyInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };
+template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
+template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
+
+#ifdef MS
+// expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is not supported}}
+// expected-note@+2{{attribute is here}}
+#endif
+struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
+
+// Base class already specialized with export attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
+
+// Base class already specialized with import attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
+
+#ifdef MS
+// expected-warning@+3{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}}
+// expected-note@+2{{attribute is here}}
+#endif
+struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
+
+// Base class already instantiated with export attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
+
+// Base class already instantiated with import attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
diff --git a/test/SemaCXX/elaborated-type-specifier.cpp b/test/SemaCXX/elaborated-type-specifier.cpp
index 1b1770a89f850..81c5cb4eac59b 100644
--- a/test/SemaCXX/elaborated-type-specifier.cpp
+++ b/test/SemaCXX/elaborated-type-specifier.cpp
@@ -43,3 +43,12 @@ int test_funcparam_scope(struct S5 * s5) {
if (s5 == s5_2) return 1; // expected-error {{comparison of distinct pointer types ('struct S5 *' and 'struct S5 *')}}
return 0;
}
+
+namespace test5 {
+ struct A {
+ class __attribute__((visibility("hidden"))) B {};
+
+ void test(class __attribute__((visibility("hidden"), noreturn)) B b) { // expected-warning {{'noreturn' attribute only applies to functions and methods}}
+ }
+ };
+}
diff --git a/test/SemaCXX/enable_if.cpp b/test/SemaCXX/enable_if.cpp
new file mode 100644
index 0000000000000..e9dc24254f209
--- /dev/null
+++ b/test/SemaCXX/enable_if.cpp
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+typedef int (*fp)(int);
+int surrogate(int);
+
+struct X {
+ X() = default; // expected-note{{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
+ X(const X&) = default; // expected-note{{candidate constructor not viable: no known conversion from 'bool' to 'const X' for 1st argument}}
+ X(bool b) __attribute__((enable_if(b, "chosen when 'b' is true"))); // expected-note{{candidate disabled: chosen when 'b' is true}}
+
+ void f(int n) __attribute__((enable_if(n == 0, "chosen when 'n' is zero")));
+ void f(int n) __attribute__((enable_if(n == 1, "chosen when 'n' is one"))); // expected-note{{member declaration nearly matches}} expected-note{{candidate disabled: chosen when 'n' is one}}
+
+ static void s(int n) __attribute__((enable_if(n == 0, "chosen when 'n' is zero"))); // expected-note2{{candidate disabled: chosen when 'n' is zero}}
+
+ void conflict(int n) __attribute__((enable_if(n+n == 10, "chosen when 'n' is five"))); // expected-note{{candidate function}}
+ void conflict(int n) __attribute__((enable_if(n*2 == 10, "chosen when 'n' is five"))); // expected-note{{candidate function}}
+
+ operator long() __attribute__((enable_if(true, "chosen on your platform")));
+ operator int() __attribute__((enable_if(false, "chosen on other platform")));
+
+ operator fp() __attribute__((enable_if(false, "never enabled"))) { return surrogate; } // expected-note{{conversion candidate of type 'int (*)(int)'}} // FIXME: the message is not displayed
+};
+
+void X::f(int n) __attribute__((enable_if(n == 0, "chosen when 'n' is zero"))) // expected-note{{member declaration nearly matches}} expected-note{{candidate disabled: chosen when 'n' is zero}}
+{
+}
+
+void X::f(int n) __attribute__((enable_if(n == 2, "chosen when 'n' is two"))) // expected-error{{out-of-line definition of 'f' does not match any declaration in 'X'}} expected-note{{candidate disabled: chosen when 'n' is two}}
+{
+}
+
+X x1(true);
+X x2(false); // expected-error{{no matching constructor for initialization of 'X'}}
+
+__attribute__((deprecated)) constexpr int old() { return 0; } // expected-note2{{'old' has been explicitly marked deprecated here}}
+void deprec1(int i) __attribute__((enable_if(old() == 0, "chosen when old() is zero"))); // expected-warning{{'old' is deprecated}}
+void deprec2(int i) __attribute__((enable_if(old() == 0, "chosen when old() is zero"))); // expected-warning{{'old' is deprecated}}
+
+void overloaded(int);
+void overloaded(long);
+
+struct Nothing { };
+template<typename T> void typedep(T t) __attribute__((enable_if(t, ""))); // expected-note{{candidate disabled:}} expected-error{{value of type 'Nothing' is not contextually convertible to 'bool'}}
+template<int N> void valuedep() __attribute__((enable_if(N == 1, "")));
+
+// FIXME: we skip potential constant expression evaluation on value dependent
+// enable-if expressions
+int not_constexpr();
+template<int N> void valuedep() __attribute__((enable_if(N == not_constexpr(), "")));
+
+template <typename T> void instantiationdep() __attribute__((enable_if(sizeof(sizeof(T)) != 0, "")));
+
+void test() {
+ X x;
+ x.f(0);
+ x.f(1);
+ x.f(2); // no error, suppressed by erroneous out-of-line definition
+ x.f(3); // expected-error{{no matching member function for call to 'f'}}
+
+ x.s(0);
+ x.s(1); // expected-error{{no matching member function for call to 's'}}
+
+ X::s(0);
+ X::s(1); // expected-error{{no matching member function for call to 's'}}
+
+ x.conflict(5); // expected-error{{call to member function 'conflict' is ambiguous}}
+
+ deprec2(0);
+
+ overloaded(x);
+
+ int i = x(1); // expected-error{{no matching function for call to object of type 'X'}}
+
+ Nothing n;
+ typedep(0); // expected-error{{no matching function for call to 'typedep'}}
+ typedep(1);
+ typedep(n); // expected-note{{in instantiation of function template specialization 'typedep<Nothing>' requested here}}
+}
diff --git a/test/SemaCXX/enum-bitfield.cpp b/test/SemaCXX/enum-bitfield.cpp
index 63445ca0583fa..ec849b79a7460 100644
--- a/test/SemaCXX/enum-bitfield.cpp
+++ b/test/SemaCXX/enum-bitfield.cpp
@@ -16,3 +16,15 @@ struct Y {
enum E : int(2);
enum E : Z(); // expected-error{{integral constant expression must have integral or unscoped enumeration type, not 'Z'}}
};
+
+namespace pr18587 {
+struct A {
+ enum class B {
+ C
+ };
+};
+const int C = 4;
+struct D {
+ A::B : C;
+};
+}
diff --git a/test/SemaCXX/enum-scoped.cpp b/test/SemaCXX/enum-scoped.cpp
index b4aad18b17c93..1eed2281e9358 100644
--- a/test/SemaCXX/enum-scoped.cpp
+++ b/test/SemaCXX/enum-scoped.cpp
@@ -78,22 +78,22 @@ Complete2 complete2;
// All the redeclarations below are done twice on purpose. Tests that the type
// of the declaration isn't changed.
-enum class Redeclare2; // expected-note{{previous use is here}} expected-note{{previous use is here}}
+enum class Redeclare2; // expected-note{{previous declaration is here}} expected-note{{previous declaration is here}}
enum Redeclare2; // expected-error{{previously declared as scoped}}
enum Redeclare2; // expected-error{{previously declared as scoped}}
-enum Redeclare3 : int; // expected-note{{previous use is here}} expected-note{{previous use is here}}
+enum Redeclare3 : int; // expected-note{{previous declaration is here}} expected-note{{previous declaration is here}}
enum Redeclare3; // expected-error{{previously declared with fixed underlying type}}
enum Redeclare3; // expected-error{{previously declared with fixed underlying type}}
enum class Redeclare5;
enum class Redeclare5 : int; // ok
-enum Redeclare6 : int; // expected-note{{previous use is here}} expected-note{{previous use is here}}
+enum Redeclare6 : int; // expected-note{{previous declaration is here}} expected-note{{previous declaration is here}}
enum Redeclare6 : short; // expected-error{{redeclared with different underlying type}}
enum Redeclare6 : short; // expected-error{{redeclared with different underlying type}}
-enum class Redeclare7; // expected-note{{previous use is here}} expected-note{{previous use is here}}
+enum class Redeclare7; // expected-note{{previous declaration is here}} expected-note{{previous declaration is here}}
enum class Redeclare7 : short; // expected-error{{redeclared with different underlying type}}
enum class Redeclare7 : short; // expected-error{{redeclared with different underlying type}}
@@ -272,6 +272,11 @@ namespace PR16900 {
A f(A a) { return -a; } // expected-error {{invalid argument type 'PR16900::A' to unary expression}}
}
+namespace PR18551 {
+ enum class A { A };
+ bool f() { return !A::A; } // expected-error {{invalid argument type 'PR18551::A' to unary expression}}
+}
+
namespace rdar15124329 {
enum class B : bool { F, T };
diff --git a/test/SemaCXX/err_init_conversion_failed.cpp b/test/SemaCXX/err_init_conversion_failed.cpp
index 0652e7a9ea6af..e31f215b4528c 100644
--- a/test/SemaCXX/err_init_conversion_failed.cpp
+++ b/test/SemaCXX/err_init_conversion_failed.cpp
@@ -43,3 +43,19 @@ void test14(const float2 in, const float2 out) {
const float4 V = (float4){ in, out };
// expected-error@-1{{cannot initialize a compound literal initializer}}
}
+
+namespace template_test {
+class S {
+public:
+ void foo(int);
+};
+
+template <class P> struct S2 {
+ void (P::*a)(const int &);
+};
+
+void test_15() {
+ S2<S> X = {&S::foo};
+ // expected-error-re@-1{{cannot initialize a member subobject of type 'void (template_test::S::*)(const int &){{( __attribute__\(\(thiscall\)\))?}}' with an rvalue of type 'void (template_test::S::*)(int){{( __attribute__\(\(thiscall\)\))?}}': type mismatch at 1st parameter ('const int &' vs 'int')}}
+}
+}
diff --git a/test/SemaCXX/explicit.cpp b/test/SemaCXX/explicit.cpp
index 1c4d7704511b9..aa28bd85af465 100644
--- a/test/SemaCXX/explicit.cpp
+++ b/test/SemaCXX/explicit.cpp
@@ -246,3 +246,8 @@ namespace pr8264 {
explicit explicit Test(int x); // expected-warning{{duplicate 'explicit' declaration specifier}}
};
}
+
+namespace PR18777 {
+ struct S { explicit operator bool() const; } s;
+ int *p = new int(s); // expected-error {{no viable conversion}}
+}
diff --git a/test/SemaCXX/expression-traits.cpp b/test/SemaCXX/expression-traits.cpp
index 3a00687f11255..51bb90e8bbf95 100644
--- a/test/SemaCXX/expression-traits.cpp
+++ b/test/SemaCXX/expression-traits.cpp
@@ -520,20 +520,19 @@ void expr_cond(bool cond)
// 5.16 Conditional operator [expr.cond]
//
// 2 If either the second or the third operand has type (possibly
- // cv-qualified) void, then the lvalue-to-rvalue (4.1),
- // array-to-pointer (4.2), and function-to-pointer (4.3) standard
- // conversions are performed on the second and third operands, and one
- // of the following shall hold:
+ // cv-qualified) void, one of the following shall hold:
//
// - The second or the third operand (but not both) is a
- // throw-expression (15.1); the result is of the type of the other and
- // is an rvalue.
+ // (possibly parenthesized) throw-expression (15.1); the result
+ // is of the type and value category of the other.
Class classLvalue;
ASSERT_RVALUE(cond ? throw 1 : (void)0);
ASSERT_RVALUE(cond ? (void)0 : throw 1);
- ASSERT_RVALUE(cond ? throw 1 : classLvalue);
- ASSERT_RVALUE(cond ? classLvalue : throw 1);
+ ASSERT_RVALUE(cond ? throw 1 : 0);
+ ASSERT_RVALUE(cond ? 0 : throw 1);
+ ASSERT_LVALUE(cond ? throw 1 : classLvalue);
+ ASSERT_LVALUE(cond ? classLvalue : throw 1);
// - Both the second and the third operands have type void; the result
// is of type void and is an rvalue. [Note: this includes the case
diff --git a/test/SemaCXX/expressions.cpp b/test/SemaCXX/expressions.cpp
index 2635fb8d176a8..1a50c99c59047 100644
--- a/test/SemaCXX/expressions.cpp
+++ b/test/SemaCXX/expressions.cpp
@@ -118,3 +118,20 @@ void test3() {
(void)s1.foo();
(void)s2.foo();
}
+
+namespace pr16992 {
+ typedef int T;
+ unsigned getsz() {
+ return (sizeof T());
+ }
+}
+
+void test4() {
+ #define X 0
+ #define Y 1
+ bool r1 = X || Y;
+
+ #define Y2 2
+ bool r2 = X || Y2; // expected-warning {{use of logical '||' with constant operand}} \
+ // expected-note {{use '|' for a bitwise operation}}
+}
diff --git a/test/SemaCXX/flexible-array-test.cpp b/test/SemaCXX/flexible-array-test.cpp
index f287711eeb6a5..e58f19a62eca9 100644
--- a/test/SemaCXX/flexible-array-test.cpp
+++ b/test/SemaCXX/flexible-array-test.cpp
@@ -36,14 +36,20 @@ void foo()
}
struct S {
- virtual void foo();
+ virtual void foo();
};
struct X {
int blah;
- S strings[]; // expected-error {{flexible array member 'strings' of non-POD element type 'S []'}}
+ S strings[];
};
+S a, b = a;
+S f(X &x) {
+ a = b;
+ return x.strings[0];
+}
+
class A {
int s;
char c[];
@@ -71,3 +77,14 @@ struct VirtStorage : virtual StorageBase {
};
}
+
+struct NonTrivDtor { ~NonTrivDtor(); };
+// FIXME: It's not clear whether we should disallow examples like this. GCC accepts.
+struct FlexNonTrivDtor {
+ int n;
+ NonTrivDtor ntd[]; // expected-error {{flexible array member 'ntd' of type 'NonTrivDtor []' with non-trivial destruction}}
+ ~FlexNonTrivDtor() {
+ for (int i = n; i != 0; --i)
+ ntd[i-1].~NonTrivDtor();
+ }
+};
diff --git a/test/SemaCXX/for-range-dereference.cpp b/test/SemaCXX/for-range-dereference.cpp
index bf3187da30e2e..7377199024e51 100644
--- a/test/SemaCXX/for-range-dereference.cpp
+++ b/test/SemaCXX/for-range-dereference.cpp
@@ -11,7 +11,7 @@ struct NoBegin {
struct DeletedEnd : public T {
Data *begin();
- Data *end() = delete; //expected-note {{function has been explicitly marked deleted here}}
+ Data *end() = delete; //expected-note {{'end' has been explicitly marked deleted here}}
};
struct DeletedADLBegin { };
diff --git a/test/SemaCXX/for-range-examples.cpp b/test/SemaCXX/for-range-examples.cpp
index b3cf9c326421d..2f777fb46df05 100644
--- a/test/SemaCXX/for-range-examples.cpp
+++ b/test/SemaCXX/for-range-examples.cpp
@@ -176,8 +176,9 @@ namespace test4 {
// Make sure these don't crash. Better diagnostics would be nice.
for (: {1, 2, 3}) {} // expected-error {{expected expression}} expected-error {{expected ';'}}
- for (x : {1, 2, 3}) {} // expected-error {{undeclared identifier}} expected-error {{expected ';'}}
- for (y : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}}
+ for (1 : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}}
+ for (+x : {1, 2, 3}) {} // expected-error {{undeclared identifier}} expected-error {{expected ';'}}
+ for (+y : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}}
}
}
@@ -209,3 +210,32 @@ namespace test6 {
// expected-error@-1 {{cannot build range expression with array function parameter 'arr' since parameter with array type 'test6::vector []' is treated as pointer type 'test6::vector *'}}
}
}
+
+namespace test7 {
+ void f() {
+ int arr[5], b;
+ for (a : arr) {} // expected-warning {{extension}}
+ // FIXME: Give a -Wshadow for this by default?
+ for (b : arr) {} // expected-warning {{extension}}
+ for (arr : arr) {} // expected-warning {{extension}}
+ for (c alignas(8) : arr) { // expected-warning {{extension}}
+ static_assert(alignof(c) == 8, ""); // expected-warning {{extension}}
+ }
+ // FIXME: We should reject this, but don't, because we only check the
+ // attribute before we deduce the 'auto' type.
+ for (d alignas(1) : arr) {} // expected-warning {{extension}}
+ for (e [[deprecated]] : arr) { e = 0; } // expected-warning {{deprecated}} expected-note {{here}} expected-warning {{extension}}
+ }
+}
+
+namespace pr18587 {
+ class Arg {};
+ struct Cont {
+ int *begin();
+ int *end();
+ };
+ void AddAllArgs(Cont &x) {
+ for (auto Arg: x) {
+ }
+ }
+}
diff --git a/test/SemaCXX/format-strings.cpp b/test/SemaCXX/format-strings.cpp
index 299aa81bb1612..41775708feb71 100644
--- a/test/SemaCXX/format-strings.cpp
+++ b/test/SemaCXX/format-strings.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -pedantic -fblocks %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -Wformat-non-iso -fblocks %s
#include <stdarg.h>
diff --git a/test/SemaCXX/friend.cpp b/test/SemaCXX/friend.cpp
index aed2ab2c7d0c0..03589101e1b85 100644
--- a/test/SemaCXX/friend.cpp
+++ b/test/SemaCXX/friend.cpp
@@ -288,3 +288,11 @@ namespace test10 {
::test10::f10_d(z);
}
}
+
+namespace test11 {
+ class __attribute__((visibility("hidden"))) B;
+
+ class A {
+ friend class __attribute__((visibility("hidden"), noreturn)) B; // expected-warning {{'noreturn' attribute only applies to functions and methods}}
+ };
+}
diff --git a/test/SemaCXX/funcdname.cpp b/test/SemaCXX/funcdname.cpp
new file mode 100644
index 0000000000000..d63d3f54c3395
--- /dev/null
+++ b/test/SemaCXX/funcdname.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -std=c++1y -triple i386-pc-win32 -fms-compatibility -fms-extensions -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+int foo() {
+ static_assert(sizeof(__FUNCDNAME__) == 12, "?foo@@YAHXZ");
+ return 0;
+}
+
+// Within templates.
+template <typename T>
+int baz() {
+ static_assert(sizeof(__FUNCDNAME__) == 16, "??$baz@H@@YAHXZ");
+
+ return 0;
+}
+
+struct A {
+ A() {
+ static_assert(sizeof(__FUNCDNAME__) == 13, "??0A@@QAE@XZ");
+ }
+ ~A() {
+ static_assert(sizeof(__FUNCDNAME__) == 13, "??1A@@QAE@XZ");
+ }
+};
+
+int main() {
+ static_assert(sizeof(__FUNCDNAME__) == 5, "main");
+
+ baz<int>();
+
+ return 0;
+}
diff --git a/test/SemaCXX/functional-cast.cpp b/test/SemaCXX/functional-cast.cpp
index f8e0c465875ef..f5ca76c38c065 100644
--- a/test/SemaCXX/functional-cast.cpp
+++ b/test/SemaCXX/functional-cast.cpp
@@ -305,8 +305,8 @@ void memptrs()
(void)structureimfp(psf);
typedef void (structure::*structurevmfp)();
- (void)structurevmfp(psi); // expected-error {{functional-style cast from 'const int structure::*' to 'structurevmfp' (aka 'void (structure::*)()') is not allowed}}
- (void)structureimp(psf); // expected-error {{functional-style cast from 'void (structure::*)()' to 'structureimp' (aka 'int structure::*') is not allowed}}
+ (void)structurevmfp(psi); // expected-error-re {{functional-style cast from 'const int structure::*' to 'structurevmfp' (aka 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}') is not allowed}}
+ (void)structureimp(psf); // expected-error-re {{functional-style cast from 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' to 'structureimp' (aka 'int structure::*') is not allowed}}
}
// ---------------- misc ------------------
diff --git a/test/SemaCXX/goto.cpp b/test/SemaCXX/goto.cpp
index 24bcb7c516738..042ec3cd8035c 100644
--- a/test/SemaCXX/goto.cpp
+++ b/test/SemaCXX/goto.cpp
@@ -118,7 +118,7 @@ namespace PR10620 {
namespace test12 {
struct A { A(); A(const A&); ~A(); };
- void test(A a) { // expected-note {{jump enters lifetime of block}} FIXME: wierd location
+ void test(A a) { // expected-note {{jump enters lifetime of block}} FIXME: weird location
goto lbl; // expected-error {{goto into protected scope}}
(void) ^{ (void) a; };
lbl:
diff --git a/test/SemaCXX/implicit-member-functions.cpp b/test/SemaCXX/implicit-member-functions.cpp
index b5f7fe1016b9d..de679fe14a065 100644
--- a/test/SemaCXX/implicit-member-functions.cpp
+++ b/test/SemaCXX/implicit-member-functions.cpp
@@ -58,13 +58,13 @@ namespace Recursion {
};
struct B;
struct A {
+ // expected-note@-1 {{while substituting deduced template arguments}}
typedef B type;
template<typename T,
typename = typename InvokeCopyConstructor<typename T::type>::type>
// expected-note@-1 {{in instantiation of template class}}
A(const T &);
// expected-note@-1 {{in instantiation of default argument}}
- // expected-note@-2 {{while substituting deduced template arguments}}
};
struct B { // expected-note {{candidate constructor (the implicit move }}
B(); // expected-note {{candidate constructor not viable}}
diff --git a/test/SemaCXX/implicit-virtual-member-functions.cpp b/test/SemaCXX/implicit-virtual-member-functions.cpp
index cd547f5764593..f88a55c3d5b4b 100644
--- a/test/SemaCXX/implicit-virtual-member-functions.cpp
+++ b/test/SemaCXX/implicit-virtual-member-functions.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify %s
struct A {
virtual ~A();
};
@@ -9,8 +10,12 @@ struct B : A { // expected-error {{no suitable member 'operator delete' in 'B'}}
void operator delete (void *, int); // expected-note {{'operator delete' declared here}}
};
+#ifdef MSABI
+B b; // expected-note {{implicit destructor for 'B' first required here}}
+#else
void B::f() { // expected-note {{implicit destructor for 'B' first required here}}
}
+#endif
struct C : A { // expected-error {{no suitable member 'operator delete' in 'C'}}
C();
@@ -26,4 +31,3 @@ struct D : A { // expected-error {{no suitable member 'operator delete' in 'D'}}
void f() {
new D; // expected-note {{implicit destructor for 'D' first required here}}
}
-
diff --git a/test/SemaCXX/init-priority-attr.cpp b/test/SemaCXX/init-priority-attr.cpp
index a91eb60ba96cf..a2e6df26ba1b7 100644
--- a/test/SemaCXX/init-priority-attr.cpp
+++ b/test/SemaCXX/init-priority-attr.cpp
@@ -25,8 +25,7 @@ Two coo[2] __attribute__((init_priority(3))); // expected-error {{init_priority
Two koo[4] __attribute__((init_priority(1.13))); // expected-error {{'init_priority' attribute requires an integer constant}}
-
-Two func() __attribute__((init_priority(1001))); // expected-error {{can only use 'init_priority' attribute on file-scope definitions of objects of class type}}
+Two func() __attribute__((init_priority(1001))); // expected-error {{'init_priority' attribute only applies to variables}}
int i __attribute__((init_priority(1001))); // expected-error {{can only use 'init_priority' attribute on file-scope definitions of objects of class type}}
diff --git a/test/SemaCXX/lambda-expressions.cpp b/test/SemaCXX/lambda-expressions.cpp
index 65f4856dda24c..9a53e4604f763 100644
--- a/test/SemaCXX/lambda-expressions.cpp
+++ b/test/SemaCXX/lambda-expressions.cpp
@@ -284,6 +284,67 @@ namespace lambdas_in_NSDMIs {
}
}
+// PR18477: don't try to capture 'this' from an NSDMI encountered while parsing
+// a lambda.
+namespace NSDMIs_in_lambdas {
+ template<typename T> struct S { int a = 0; int b = a; };
+ void f() { []() { S<int> s; }; }
+
+ auto x = []{ struct S { int n, m = n; }; };
+ auto y = [&]{ struct S { int n, m = n; }; }; // expected-error {{non-local lambda expression cannot have a capture-default}}
+ void g() { auto z = [&]{ struct S { int n, m = n; }; }; }
+}
+
+namespace CaptureIncomplete {
+ struct Incomplete; // expected-note 2{{forward decl}}
+ void g(const Incomplete &a);
+ void f(Incomplete &a) {
+ (void) [a] {}; // expected-error {{incomplete}}
+ (void) [&a] {};
+
+ (void) [=] { g(a); }; // expected-error {{incomplete}}
+ (void) [&] { f(a); };
+ }
+}
+
+namespace CaptureAbstract {
+ struct S {
+ virtual void f() = 0; // expected-note {{unimplemented}}
+ int n = 0;
+ };
+ struct T : S {
+ constexpr T() {}
+ void f();
+ };
+ void f() {
+ constexpr T t = T();
+ S &s = const_cast<T&>(t);
+ // FIXME: Once we properly compute odr-use per DR712, this should be
+ // accepted (and should not capture 's').
+ [=] { return s.n; }; // expected-error {{abstract}}
+ }
+}
+
+namespace PR18128 {
+ auto l = [=]{}; // expected-error {{non-local lambda expression cannot have a capture-default}}
+
+ struct S {
+ int n;
+ int (*f())[true ? 1 : ([=]{ return n; }(), 0)];
+ // expected-error@-1 {{non-local lambda expression cannot have a capture-default}}
+ // expected-error@-2 {{invalid use of non-static data member 'n'}}
+ // expected-error@-3 {{a lambda expression may not appear inside of a constant expression}}
+ int g(int k = ([=]{ return n; }(), 0));
+ // expected-error@-1 {{non-local lambda expression cannot have a capture-default}}
+ // expected-error@-2 {{invalid use of non-static data member 'n'}}
+
+ int a = [=]{ return n; }(); // ok
+ int b = [=]{ return [=]{ return n; }(); }(); // ok
+ int c = []{ int k = 0; return [=]{ return k; }(); }(); // ok
+ int d = []{ return [=]{ return n; }(); }(); // expected-error {{'this' cannot be implicitly captured in this context}}
+ };
+}
+
namespace PR18473 {
template<typename T> void f() {
T t(0);
@@ -298,3 +359,7 @@ namespace PR18473 {
};
template void f<NoCopy>(); // expected-note {{instantiation}}
}
+
+void PR19249() {
+ auto x = [&x]{}; // expected-error {{cannot appear in its own init}}
+}
diff --git a/test/SemaCXX/linkage.cpp b/test/SemaCXX/linkage.cpp
index 13d295a5d59b0..8a2013fd52b42 100644
--- a/test/SemaCXX/linkage.cpp
+++ b/test/SemaCXX/linkage.cpp
@@ -5,6 +5,8 @@
// RUN: %clang_cc1 -Werror -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
+// CHECK: @_ZZN5test61A3fooEvE3bar = linkonce_odr global i32 0, align 4
+
// PR8926
namespace test0 {
typedef struct {
@@ -103,3 +105,20 @@ namespace test5 {
};
}
}
+
+// Test that we don't compute linkage too hastily before we're done
+// processing a record decl. rdar://15928125
+namespace test6 {
+ typedef struct {
+ int foo() {
+ // Tested at top of file.
+ static int bar = 0;
+ return bar++;
+ }
+ } A;
+
+ void test() {
+ A a;
+ a.foo();
+ }
+}
diff --git a/test/SemaCXX/linkage2.cpp b/test/SemaCXX/linkage2.cpp
index 075f5e70c247d..a7eb15f7c6be6 100644
--- a/test/SemaCXX/linkage2.cpp
+++ b/test/SemaCXX/linkage2.cpp
@@ -213,3 +213,7 @@ namespace PR16247 {
void pr16247_bar(int) {}
void pr16247_bar(double) {}
}
+namespace PR18964 {
+ unsigned &*foo; //expected-error{{'foo' declared as a pointer to a reference of type}}
+ extern struct {} *foo; // don't assert
+}
diff --git a/test/SemaCXX/member-expr.cpp b/test/SemaCXX/member-expr.cpp
index 239aecff815d8..e0955aeb9ce9d 100644
--- a/test/SemaCXX/member-expr.cpp
+++ b/test/SemaCXX/member-expr.cpp
@@ -193,7 +193,7 @@ namespace PR15045 {
};
template <class T> void call_func(T t) {
- t->func(); // expected-error-re 2 {{member reference type 'PR15045::bar' is not a pointer$}} \
+ t->func(); // expected-error-re 2 {{member reference type 'PR15045::bar' is not a pointer{{$}}}} \
// expected-note {{did you mean to use '.' instead?}}
}
@@ -207,7 +207,7 @@ namespace PR15045 {
// Make sure a fixit isn't given in the case that the '->' isn't actually
// the problem (the problem is with the return value of an operator->).
- f->func(); // expected-error-re {{member reference type 'PR15045::bar' is not a pointer$}}
+ f->func(); // expected-error-re {{member reference type 'PR15045::bar' is not a pointer{{$}}}}
call_func(e); // expected-note {{in instantiation of function template specialization 'PR15045::call_func<PR15045::bar>' requested here}}
diff --git a/test/SemaCXX/member-init.cpp b/test/SemaCXX/member-init.cpp
index 6e4fd5df5a08a..d8a00b3b1e24d 100644
--- a/test/SemaCXX/member-init.cpp
+++ b/test/SemaCXX/member-init.cpp
@@ -100,3 +100,13 @@ namespace rdar14084171 {
};
void f(Sprite& x) { x = x; }
}
+
+namespace PR18560 {
+ struct X { int m; };
+
+ template<typename T = X,
+ typename U = decltype(T::m)>
+ int f();
+
+ struct Y { int b = f(); };
+}
diff --git a/test/SemaCXX/member-pointer-ms.cpp b/test/SemaCXX/member-pointer-ms.cpp
index aee8e2eca7742..e7c4ae9409e04 100644
--- a/test/SemaCXX/member-pointer-ms.cpp
+++ b/test/SemaCXX/member-pointer-ms.cpp
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -std=c++11 -cxx-abi microsoft -fms-compatibility -fsyntax-only -triple=i386-pc-win32 -verify %s
-// RUN: %clang_cc1 -std=c++11 -cxx-abi microsoft -fms-compatibility -fsyntax-only -triple=x86_64-pc-win32 -verify %s
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -triple=i386-pc-win32 -verify -DVMB %s
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -triple=x86_64-pc-win32 -verify -DVMB %s
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -triple=x86_64-pc-win32 -verify -DVMV -fms-memptr-rep=virtual %s
//
// This file should also give no diagnostics when run through cl.exe from MSVS
// 2012, which supports C++11 and static_assert. It should pass for both 64-bit
@@ -18,22 +19,73 @@ struct Foo {
int f;
};
+#ifdef VMB
enum {
+ kSingleDataAlign = 1 * sizeof(int),
+ kSingleFunctionAlign = 1 * sizeof(void *),
+ kMultipleDataAlign = 1 * sizeof(int),
+ // Everything with more than 1 field is 8 byte aligned, except virtual data
+ // member pointers on x64 (ugh).
+ kMultipleFunctionAlign = 8,
+#ifdef _M_X64
+ kVirtualDataAlign = 4,
+#else
+ kVirtualDataAlign = 8,
+#endif
+ kVirtualFunctionAlign = 8,
+ kUnspecifiedDataAlign = 8,
+ kUnspecifiedFunctionAlign = 8,
+
kSingleDataSize = 1 * sizeof(int),
kSingleFunctionSize = 1 * sizeof(void *),
kMultipleDataSize = 1 * sizeof(int),
kMultipleFunctionSize = 2 * sizeof(void *),
kVirtualDataSize = 2 * sizeof(int),
kVirtualFunctionSize = 2 * sizeof(int) + 1 * sizeof(void *),
- // Unspecified is weird, it's 1 more slot than virtual.
- kUnspecifiedDataSize = kVirtualDataSize + 1 * sizeof(int),
- kUnspecifiedFunctionSize = kVirtualFunctionSize + 1 * sizeof(void *),
+ kUnspecifiedDataSize = 3 * sizeof(int),
+ kUnspecifiedFunctionSize = 2 * sizeof(int) + 2 * sizeof(void *),
+};
+#elif VMV
+enum {
+ // Everything with more than 1 field is 8 byte aligned, except virtual data
+ // member pointers on x64 (ugh).
+#ifdef _M_X64
+ kVirtualDataAlign = 4,
+#else
+ kVirtualDataAlign = 8,
+#endif
+ kMultipleDataAlign = kVirtualDataAlign,
+ kSingleDataAlign = kVirtualDataAlign,
+
+ kUnspecifiedFunctionAlign = 8,
+ kVirtualFunctionAlign = kUnspecifiedFunctionAlign,
+ kMultipleFunctionAlign = kUnspecifiedFunctionAlign,
+ kSingleFunctionAlign = kUnspecifiedFunctionAlign,
+
+ kUnspecifiedDataSize = 3 * sizeof(int),
+ kVirtualDataSize = kUnspecifiedDataSize,
+ kMultipleDataSize = kUnspecifiedDataSize,
+ kSingleDataSize = kUnspecifiedDataSize,
+
+ kUnspecifiedFunctionSize = 2 * sizeof(int) + 2 * sizeof(void *),
+ kVirtualFunctionSize = kUnspecifiedFunctionSize,
+ kMultipleFunctionSize = kUnspecifiedFunctionSize,
+ kSingleFunctionSize = kUnspecifiedFunctionSize,
};
+#else
+#error "test doesn't yet support this mode!"
+#endif
// incomplete types
+#ifdef VMB
class __single_inheritance IncSingle;
class __multiple_inheritance IncMultiple;
class __virtual_inheritance IncVirtual;
+#else
+class IncSingle;
+class IncMultiple;
+class IncVirtual;
+#endif
static_assert(sizeof(int IncSingle::*) == kSingleDataSize, "");
static_assert(sizeof(int IncMultiple::*) == kMultipleDataSize, "");
static_assert(sizeof(int IncVirtual::*) == kVirtualDataSize, "");
@@ -41,6 +93,13 @@ static_assert(sizeof(void (IncSingle::*)()) == kSingleFunctionSize, "");
static_assert(sizeof(void (IncMultiple::*)()) == kMultipleFunctionSize, "");
static_assert(sizeof(void (IncVirtual::*)()) == kVirtualFunctionSize, "");
+static_assert(__alignof(int IncSingle::*) == kSingleDataAlign, "");
+static_assert(__alignof(int IncMultiple::*) == kMultipleDataAlign, "");
+static_assert(__alignof(int IncVirtual::*) == kVirtualDataAlign, "");
+static_assert(__alignof(void (IncSingle::*)()) == kSingleFunctionAlign, "");
+static_assert(__alignof(void (IncMultiple::*)()) == kMultipleFunctionAlign, "");
+static_assert(__alignof(void (IncVirtual::*)()) == kVirtualFunctionAlign, "");
+
// An incomplete type with an unspecified inheritance model seems to take one
// more slot than virtual. It's not clear what it's used for yet.
class IncUnspecified;
@@ -62,9 +121,15 @@ static_assert(sizeof(void (Virtual::*)()) == kVirtualFunctionSize, "");
// Test both declared and defined templates.
template <typename T> class X;
+#ifdef VMB
template <> class __single_inheritance X<IncSingle>;
template <> class __multiple_inheritance X<IncMultiple>;
template <> class __virtual_inheritance X<IncVirtual>;
+#else
+template <> class X<IncSingle>;
+template <> class X<IncMultiple>;
+template <> class X<IncVirtual>;
+#endif
// Don't declare X<IncUnspecified>.
static_assert(sizeof(int X<IncSingle>::*) == kSingleDataSize, "");
static_assert(sizeof(int X<IncMultiple>::*) == kMultipleDataSize, "");
@@ -117,9 +182,7 @@ struct ForwardDecl2 : B {
static_assert(sizeof(variable_forces_sizing) == kUnspecifiedDataSize, "");
static_assert(sizeof(MemPtr1) == kUnspecifiedDataSize, "");
-// FIXME: Clang fails this assert because it locks in the inheritance model at
-// the point of the typedef instead of the first usage, while MSVC does not.
-//static_assert(sizeof(MemPtr2) == kSingleDataSize, "");
+static_assert(sizeof(MemPtr2) == kSingleDataSize, "");
struct MemPtrInBody {
typedef int MemPtrInBody::*MemPtr;
@@ -164,5 +227,48 @@ struct MemPtrInTemplate {
void (T::*func_ptr)();
};
+#ifdef VMB
int Virtual::*CastTest = reinterpret_cast<int Virtual::*>(&AA::x);
// expected-error@-1 {{cannot reinterpret_cast from member pointer type}}
+#endif
+
+namespace ErrorTest {
+template <typename T, typename U> struct __single_inheritance A;
+ // expected-warning@-1 {{inheritance model ignored on primary template}}
+template <typename T> struct __multiple_inheritance A<T, T>;
+ // expected-warning@-1 {{inheritance model ignored on partial specialization}}
+template <> struct __single_inheritance A<int, float>;
+
+struct B {}; // expected-note {{B defined here}}
+struct __multiple_inheritance B; // expected-error{{inheritance model does not match definition}}
+
+struct __multiple_inheritance C {}; // expected-error{{inheritance model does not match definition}}
+ // expected-note@-1 {{C defined here}}
+
+struct __virtual_inheritance D;
+struct D : virtual B {};
+}
+#ifdef VMB
+#pragma pointers_to_members(full_generality, multiple_inheritance)
+struct TrulySingleInheritance;
+static_assert(sizeof(int TrulySingleInheritance::*) == kMultipleDataSize, "");
+#pragma pointers_to_members(best_case)
+// This definition shouldn't conflict with the increased generality that the
+// multiple_inheritance model gave to TrulySingleInheritance.
+struct TrulySingleInheritance {};
+
+// Even if a definition proceeds the first mention of a pointer to member, we
+// still give the record the fully general representation.
+#pragma pointers_to_members(full_generality, virtual_inheritance)
+struct SingleInheritanceAsVirtualAfterPragma {};
+static_assert(sizeof(int SingleInheritanceAsVirtualAfterPragma::*) == 12, "");
+
+#pragma pointers_to_members(best_case)
+
+// The above holds even if the pragma comes after the definition.
+struct SingleInheritanceAsVirtualBeforePragma {};
+#pragma pointers_to_members(virtual_inheritance)
+static_assert(sizeof(int SingleInheritanceAsVirtualBeforePragma::*) == 12, "");
+
+#pragma pointers_to_members(single) // expected-error{{unexpected 'single'}}
+#endif
diff --git a/test/SemaCXX/member-pointer.cpp b/test/SemaCXX/member-pointer.cpp
index 4e8b4a813ba73..b8631bcf3efc9 100644
--- a/test/SemaCXX/member-pointer.cpp
+++ b/test/SemaCXX/member-pointer.cpp
@@ -7,12 +7,13 @@ struct D : A {};
struct E : A {};
struct F : D, E {};
struct G : virtual D {};
+class H : A {}; // expected-note 2{{implicitly declared private here}}
int A::*pdi1;
int (::A::*pdi2);
int (A::*pfi)(int);
-int B::*pbi; // expected-error {{expected a class or namespace}}
+int B::*pbi; // expected-error {{'B' is not a class, namespace, or scoped enumeration}}
int C::*pci; // expected-error {{'pci' does not point into a class}}
void A::*pdv; // expected-error {{'pdv' declared as a member pointer to void}}
int& A::*pdr; // expected-error {{'pdr' declared as a member pointer to a reference}}
@@ -115,8 +116,11 @@ void h() {
(void)(d.*pai);
(void)(pd->*pai);
F f, *ptrf = &f;
- (void)(f.*pai); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'F'}}
- (void)(ptrf->*pai); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'F *'}}
+ (void)(f.*pai); // expected-error {{ambiguous conversion from derived class 'F' to base class 'A'}}
+ (void)(ptrf->*pai); // expected-error {{ambiguous conversion from derived class 'F' to base class 'A'}}
+ H h, *ptrh = &h;
+ (void)(h.*pai); // expected-error {{cannot cast 'H' to its private base class 'A'}}
+ (void)(ptrh->*pai); // expected-error {{cannot cast 'H' to its private base class 'A'}}
(void)(hm.*i); // expected-error {{pointer-to-member}}
(void)(phm->*i); // expected-error {{pointer-to-member}}
diff --git a/test/SemaCXX/microsoft-cxx0x.cpp b/test/SemaCXX/microsoft-cxx0x.cpp
index 79bd7c39e5a54..58ab940f583ea 100644
--- a/test/SemaCXX/microsoft-cxx0x.cpp
+++ b/test/SemaCXX/microsoft-cxx0x.cpp
@@ -6,7 +6,7 @@ struct A {
unsigned int a;
};
int b = 3;
-A var = { b }; // expected-warning {{ cannot be narrowed }} expected-note {{override}}
+A var = { b }; // expected-warning {{ cannot be narrowed }} expected-note {{insert an explicit cast to silence this issue}}
namespace PR13433 {
diff --git a/test/SemaCXX/microsoft-dtor-lookup-cxx11.cpp b/test/SemaCXX/microsoft-dtor-lookup-cxx11.cpp
new file mode 100644
index 0000000000000..5a399aa7eac22
--- /dev/null
+++ b/test/SemaCXX/microsoft-dtor-lookup-cxx11.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -std=c++11 -verify %s
+
+struct S {
+ virtual ~S() = delete; // expected-note {{'~S' has been explicitly marked deleted here}}
+ void operator delete(void*, int);
+ void operator delete(void*, double);
+} s; // expected-error {{attempt to use a deleted function}}
+
+struct T { // expected-note{{virtual destructor requires an unambiguous, accessible 'operator delete'}}
+ virtual ~T() = default; // expected-note {{explicitly defaulted function was implicitly deleted here}}
+ void operator delete(void*, int);
+ void operator delete(void*, double);
+} t; // expected-error {{attempt to use a deleted function}}
diff --git a/test/SemaCXX/microsoft-dtor-lookup.cpp b/test/SemaCXX/microsoft-dtor-lookup.cpp
index d264bab09bf74..412749f707ee4 100644
--- a/test/SemaCXX/microsoft-dtor-lookup.cpp
+++ b/test/SemaCXX/microsoft-dtor-lookup.cpp
@@ -1,12 +1,11 @@
-// RUN: %clang_cc1 -triple i686-pc-win32 -cxx-abi itanium -fsyntax-only %s
-// RUN: %clang_cc1 -triple i686-pc-win32 -cxx-abi microsoft -verify -DMSVC_ABI %s
+// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -std=c++11 -triple %itanium_abi_triple -fsyntax-only %s
+// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -std=c++11 -triple %ms_abi_triple -verify %s
namespace Test1 {
// Should be accepted under the Itanium ABI (first RUN line) but rejected
// under the Microsoft ABI (second RUN line), as Microsoft ABI requires
-// operator delete() lookups to be done at all virtual destructor declaration
-// points.
+// operator delete() lookups to be done when vtables are marked used.
struct A {
void operator delete(void *); // expected-note {{member found by ambiguous name lookup}}
@@ -24,6 +23,10 @@ struct VC : A, B {
virtual ~VC(); // expected-error {{member 'operator delete' found in multiple base classes of different types}}
};
+void f(VC vc) {
+ // This marks VC's vtable used.
+}
+
}
namespace Test2 {
@@ -32,14 +35,13 @@ namespace Test2 {
// requires a dtor for B, but we can't implicitly define it because ~A is
// private. bar should be able to call A's private dtor without error, even
// though MSVC rejects bar.
-
class A {
private:
- ~A(); // expected-note 2{{declared private here}}
+ ~A();
int a;
};
-struct B : public A { // expected-error {{base class 'Test2::A' has private destructor}}
+struct B : public A { // expected-note {{destructor of 'B' is implicitly deleted because base class 'Test2::A' has an inaccessible destructor}}
int b;
};
@@ -53,8 +55,8 @@ struct D {
C o;
};
-void foo(B b) { } // expected-note {{implicit destructor for 'Test2::B' first required here}}
-void bar(A a) { } // expected-error {{variable of type 'Test2::A' has private destructor}}
+void foo(B b) { } // expected-error {{attempt to use a deleted function}}
+void bar(A a) { } // no error; MSVC rejects this, but we skip the direct access check.
void baz(D d) { } // no error
}
@@ -64,13 +66,13 @@ namespace Test3 {
class A {
A();
- ~A(); // expected-note 2{{implicitly declared private here}}
+ ~A(); // expected-note {{implicitly declared private here}}
friend void bar(A);
int a;
};
void bar(A a) { }
-void baz(A a) { } // expected-error {{variable of type 'Test3::A' has private destructor}}
+void baz(A a) { } // no error; MSVC rejects this, but the standard allows it.
// MSVC accepts foo() but we reject it for consistency with Itanium. MSVC also
// rejects this if A has a copy ctor or if we call A's ctor.
@@ -85,3 +87,45 @@ namespace Test4 {
class A;
void foo(A a);
}
+
+#ifdef MSVC_ABI
+namespace Test5 {
+// Do the operator delete access control check from the context of the dtor.
+class A {
+ protected:
+ void operator delete(void *);
+};
+class B : public A {
+ virtual ~B();
+};
+B *test() {
+ // Previously, marking the vtable used here would do the operator delete
+ // lookup from this context, which doesn't have access.
+ return new B;
+}
+}
+#endif
+
+namespace Test6 {
+class A {
+protected:
+ void operator delete(void *);
+};
+class B : public A {
+ virtual ~B();
+public:
+ virtual void m_fn1();
+};
+void fn1(B *b) { b->m_fn1(); }
+}
+
+namespace Test7 {
+class A {
+protected:
+ void operator delete(void *);
+};
+struct B : public A {
+ virtual ~B();
+};
+void fn1(B b) {}
+}
diff --git a/test/SemaCXX/microsoft-new-delete.cpp b/test/SemaCXX/microsoft-new-delete.cpp
index e0d25dcd86f78..6c9be228935ee 100644
--- a/test/SemaCXX/microsoft-new-delete.cpp
+++ b/test/SemaCXX/microsoft-new-delete.cpp
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -verify %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -verify -std=c++11 %s
#include <stddef.h>
@@ -10,3 +9,26 @@ void f() {
// Expect no error in MSVC compatibility mode
int *p = new(arbitrary) int[4];
}
+
+class noncopyable { noncopyable(const noncopyable&); } extern nc; // expected-note {{here}}
+void *operator new[](size_t, noncopyable);
+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, const int &);
+void *r = new (bf.n) int[4]; // expected-error {{non-const reference cannot bind to bit-field}}
+
+struct base {};
+struct derived : private base {} der; // expected-note {{here}}
+void *operator new[](size_t, base &);
+void *operator new(size_t, derived &);
+void *s = new (der) int[4]; // expected-error {{private}}
+
+struct explicit_ctor { explicit explicit_ctor(int); };
+struct explicit_ctor_tag {} ect;
+void *operator new[](size_t, explicit_ctor_tag, explicit_ctor);
+void *operator new(size_t, explicit_ctor_tag, int);
+void *t = new (ect, 0) int[4];
+void *u = new (ect, {0}) int[4];
diff --git a/test/SemaCXX/microsoft-varargs-diagnostics.cpp b/test/SemaCXX/microsoft-varargs-diagnostics.cpp
new file mode 100644
index 0000000000000..0b76fdd92dabd
--- /dev/null
+++ b/test/SemaCXX/microsoft-varargs-diagnostics.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple thumbv7-windows -fms-compatibility -fsyntax-only %s -verify
+
+extern "C" {
+typedef char * va_list;
+}
+
+void test_no_arguments(int i, ...) {
+ __va_start(); // expected-error{{too few arguments to function call, expected at least 3, have 0}}
+}
+
+void test_one_argument(int i, ...) {
+ va_list ap;
+ __va_start(&ap); // expected-error{{too few arguments to function call, expected at least 3, have 1}}
+}
+
+void test_two_arguments(int i, ...) {
+ va_list ap;
+ __va_start(&ap, &i); // expected-error{{too few arguments to function call, expected at least 3, have 2}}
+}
+
+void test_non_last_argument(int i, int j, ...) {
+ va_list ap;
+ __va_start(&ap, &i, 4);
+ // expected-error@-1{{passing 'int *' to parameter of incompatible type 'const char *': type mismatch at 2nd parameter ('int *' vs 'const char *')}}
+ // expected-error@-2{{passing 'int' to parameter of incompatible type 'unsigned int': type mismatch at 3rd parameter ('int' vs 'unsigned int')}}
+}
+
+void test_stack_allocated(int i, ...) {
+ va_list ap;
+ int j;
+ __va_start(&ap, &j, 4);
+ // expected-error@-1{{passing 'int *' to parameter of incompatible type 'const char *': type mismatch at 2nd parameter ('int *' vs 'const char *')}}
+ // expected-error@-2{{passing 'int' to parameter of incompatible type 'unsigned int': type mismatch at 3rd parameter ('int' vs 'unsigned int')}}
+}
+
+void test_non_pointer_addressof(int i, ...) {
+ va_list ap;
+ __va_start(&ap, 1, 4);
+ // expected-error@-1{{passing 'int' to parameter of incompatible type 'const char *': type mismatch at 2nd parameter ('int' vs 'const char *')}}
+ // expected-error@-2{{passing 'int' to parameter of incompatible type 'unsigned int': type mismatch at 3rd parameter ('int' vs 'unsigned int')}}
+}
+
diff --git a/test/SemaCXX/microsoft-varargs.cpp b/test/SemaCXX/microsoft-varargs.cpp
new file mode 100644
index 0000000000000..35f31a97c4f16
--- /dev/null
+++ b/test/SemaCXX/microsoft-varargs.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple thumbv7-windows -fms-compatibility -fsyntax-only %s -verify
+// expected-no-diagnostics
+
+extern "C" {
+typedef char * va_list;
+void __va_start(va_list *, ...);
+}
+
+int test___va_start(int i, ...) {
+ va_list ap;
+ __va_start(&ap, ( &reinterpret_cast<const char &>(i) ),
+ ( (sizeof(i) + 4 - 1) & ~(4 - 1) ),
+ ( &reinterpret_cast<const char &>(i) ));
+ return (*(int *)((ap += ( (sizeof(int) + 4 - 1) & ~(4 - 1) ) + ( ((va_list)0 - (ap)) & (__alignof(int) - 1) )) - ( (sizeof(int) + 4 - 1) & ~(4 - 1) )));
+}
+
+int builtin(int i, ...) {
+ __builtin_va_list ap;
+ __builtin_va_start(ap, i);
+ return __builtin_va_arg(ap, int);
+}
+
diff --git a/test/SemaCXX/missing-members.cpp b/test/SemaCXX/missing-members.cpp
index 619bc61f25011..96bed074db857 100644
--- a/test/SemaCXX/missing-members.cpp
+++ b/test/SemaCXX/missing-members.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
namespace A {
namespace B {
- class C { }; // expected-note 2 {{'A::B::C' declared here}}
+ class C { }; // expected-note {{'A::B::C' declared here}}
struct S { };
union U { };
}
@@ -18,13 +18,12 @@ namespace B {
}
void g() {
- A::B::D::E; // expected-error {{no member named 'D' in namespace 'A::B'}}
+ A::B::D::E; // expected-error-re {{no member named 'D' in namespace 'A::B'{{$}}}}
// FIXME: The typo corrections below should be suppressed since A::B::C
// doesn't have a member named D.
B::B::C::D; // expected-error {{no member named 'C' in 'B::B'; did you mean 'A::B::C'?}} \
- // expected-error {{no member named 'D' in 'A::B::C'}}
- ::C::D; // expected-error {{no member named 'C' in the global namespace; did you mean 'A::B::C'?}}\
- // expected-error {{no member named 'D' in 'A::B::C'}}
+ // expected-error-re {{no member named 'D' in 'A::B::C'{{$}}}}
+ ::C::D; // expected-error-re {{no member named 'C' in the global namespace{{$}}}}
}
int A::B::i = 10; // expected-error {{no member named 'i' in namespace 'A::B'}}
diff --git a/test/SemaCXX/ms-friend-lookup.cpp b/test/SemaCXX/ms-friend-lookup.cpp
new file mode 100644
index 0000000000000..c63160f5b9f9c
--- /dev/null
+++ b/test/SemaCXX/ms-friend-lookup.cpp
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -std=c++11 -Wmicrosoft -fms-compatibility -verify
+// RUN: not %clang_cc1 %s -triple i686-pc-win32 -std=c++11 -Wmicrosoft -fms-compatibility -fdiagnostics-parseable-fixits 2>&1 | FileCheck %s
+
+struct X;
+namespace name_at_tu_scope {
+struct Y {
+ friend struct X; // expected-warning-re {{unqualified friend declaration {{.*}} is a Microsoft extension}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:"::"
+};
+}
+
+namespace enclosing_friend_decl {
+struct B;
+namespace ns {
+struct A {
+ friend struct B; // expected-warning-re {{unqualified friend declaration {{.*}} is a Microsoft extension}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:"enclosing_friend_decl::"
+protected:
+ A();
+};
+}
+struct B {
+ static void f() { ns::A x; }
+};
+}
+
+namespace enclosing_friend_qualified {
+struct B;
+namespace ns {
+struct A {
+ friend struct enclosing_friend_qualified::B; // Adding name specifiers fixes it.
+protected:
+ A();
+};
+}
+struct B {
+ static void f() { ns::A x; }
+};
+}
+
+namespace enclosing_friend_no_tag {
+struct B;
+namespace ns {
+struct A {
+ friend B; // Removing the tag decl fixes it.
+protected:
+ A();
+};
+}
+struct B {
+ static void f() { ns::A x; }
+};
+}
+
+namespace enclosing_friend_func {
+void f();
+namespace ns {
+struct A {
+ // Amusingly, in MSVC, this declares ns::f(), and doesn't find the outer f().
+ friend void f();
+protected:
+ A(); // expected-note {{declared protected here}}
+};
+}
+void f() { ns::A x; } // expected-error {{calling a protected constructor of class 'enclosing_friend_func::ns::A'}}
+}
+
+namespace test_nns_fixit_hint {
+namespace name1 {
+namespace name2 {
+struct X;
+struct name2;
+namespace name3 {
+struct Y {
+ friend struct X; // expected-warning-re {{unqualified friend declaration {{.*}} is a Microsoft extension}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:"name1::name2::"
+};
+}
+}
+}
+}
+
+// A friend declaration injects a forward declaration into the nearest enclosing
+// non-member scope.
+namespace friend_as_a_forward_decl {
+
+class A {
+ class Nested {
+ friend class B;
+ B *b;
+ };
+ B *b;
+};
+B *global_b;
+
+void f() {
+ class Local {
+ friend class Z;
+ Z *b;
+ };
+ Z *b;
+}
+
+}
diff --git a/test/SemaCXX/ms-interface.cpp b/test/SemaCXX/ms-interface.cpp
index 3625f7027aa47..e7386ce5b8e7b 100644
--- a/test/SemaCXX/ms-interface.cpp
+++ b/test/SemaCXX/ms-interface.cpp
@@ -10,7 +10,7 @@ __interface I1 {
bool operator!();
// expected-error@+1 {{operator 'operator int' is not permitted within an interface type}}
operator int();
- // expected-error@+1 {{nested class I1::<anonymous> is not permitted within an interface type}}
+ // expected-error@+1 {{nested class I1::(anonymous) is not permitted within an interface type}}
struct { int a; };
void fn2() {
struct A { }; // should be ignored: not a nested class
diff --git a/test/SemaCXX/ms_integer_suffix.cpp b/test/SemaCXX/ms_integer_suffix.cpp
new file mode 100644
index 0000000000000..6b4594dd5b55d
--- /dev/null
+++ b/test/SemaCXX/ms_integer_suffix.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fms-extensions -verify %s
+// expected-no-diagnostics
+
+#ifdef __SIZEOF_INT8__
+static_assert(sizeof(0i8) == __SIZEOF_INT8__, "");
+#endif
+#ifdef __SIZEOF_INT16__
+static_assert(sizeof(0i16) == __SIZEOF_INT16__, "");
+#endif
+#ifdef __SIZEOF_INT32__
+static_assert(sizeof(0i32) == __SIZEOF_INT32__, "");
+#endif
+#ifdef __SIZEOF_INT64__
+static_assert(sizeof(0i64) == __SIZEOF_INT64__, "");
+#endif
+#ifdef __SIZEOF_INT128__
+static_assert(sizeof(0i128) == __SIZEOF_INT128__, "");
+#endif
diff --git a/test/SemaCXX/ms_struct.cpp b/test/SemaCXX/ms_struct.cpp
index 37fa9a7c687ca..2832b5620f3b6 100644
--- a/test/SemaCXX/ms_struct.cpp
+++ b/test/SemaCXX/ms_struct.cpp
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-apple-darwin9 -std=c++11 %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -fsyntax-only -Wno-error=incompatible-ms-struct -verify -triple i686-apple-darwin9 -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-error=incompatible-ms-struct -verify -triple armv7-apple-darwin9 -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -DTEST_FOR_ERROR -verify -triple armv7-apple-darwin9 -std=c++11 %s
#pragma ms_struct on
@@ -9,10 +10,29 @@ struct A {
};
struct B : public A {
+#ifdef TEST_FOR_ERROR
+ // expected-error@-2 {{ms_struct may not produce MSVC-compatible layouts for classes with base classes or virtual functions}}
+#else
+ // expected-warning@-4 {{ms_struct may not produce MSVC-compatible layouts for classes with base classes or virtual functions}}
+#endif
unsigned long c:16;
int d;
B();
};
static_assert(__builtin_offsetof(B, d) == 12,
- "We can't allocate the bitfield into the padding under ms_struct"); \ No newline at end of file
+ "We can't allocate the bitfield into the padding under ms_struct");
+
+// rdar://16178895
+struct C {
+#ifdef TEST_FOR_ERROR
+ // expected-error@-2 {{ms_struct may not produce MSVC-compatible layouts for classes with base classes or virtual functions}}
+#else
+ // expected-warning@-4 {{ms_struct may not produce MSVC-compatible layouts for classes with base classes or virtual functions}}
+#endif
+ virtual void foo();
+ long long n;
+};
+
+static_assert(__builtin_offsetof(C, n) == 8,
+ "long long field in ms_struct should be 8-byte aligned");
diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp
index df4f1b269d70a..bdeb00d357347 100644
--- a/test/SemaCXX/nested-name-spec.cpp
+++ b/test/SemaCXX/nested-name-spec.cpp
@@ -8,13 +8,12 @@ namespace A {
static int Ag1();
static int Ag2();
};
- int ax;
+ int ax; // expected-note {{'ax' declared here}}
void Af();
}
A:: ; // expected-error {{expected unqualified-id}}
-// FIXME: there is a member 'ax'; it's just not a class.
-::A::ax::undef ex3; // expected-error {{no member named 'ax'}}
+::A::ax::undef ex3; // expected-error {{'ax' is not a class, namespace, or scoped enumeration}}
A::undef1::undef2 ex4; // expected-error {{no member named 'undef1'}}
int A::C::Ag1() { return 0; }
@@ -85,10 +84,13 @@ struct A2::CC::NC {
void f3() {
N::x = 0; // expected-error {{use of undeclared identifier 'N'}}
- int N;
- N::x = 0; // expected-error {{expected a class or namespace}}
+ // FIXME: Consider including the kind of entity that 'N' is ("variable 'N'
+ // declared here", "template 'X' declared here", etc) to help explain what it
+ // is if it's 'not a class, namespace, or scoped enumeration'.
+ int N; // expected-note {{'N' declared here}}
+ N::x = 0; // expected-error {{'N' is not a class, namespace, or scoped enumeration}}
{ int A; A::ax = 0; }
- { typedef int A; A::ax = 0; } // expected-error{{expected a class or namespace}}
+ { typedef int A; A::ax = 0; } // expected-error{{'A' (aka 'int') is not a class, namespace, or scoped enumeration}}
{ typedef A::C A; A::ax = 0; } // expected-error {{no member named 'ax'}}
{ typedef A::C A; A::cx = 0; }
}
@@ -114,7 +116,7 @@ namespace E {
};
void f() {
- return E::X; // expected-error{{expected a class or namespace}}
+ return E::X; // expected-error{{'E::Nested::E' is not a class, namespace, or scoped enumeration}}
}
}
}
@@ -143,7 +145,7 @@ namespace A {
void g(int&); // expected-note{{type of 1st parameter of member declaration does not match definition ('int &' vs 'const int &')}}
}
-void A::f() {} // expected-error-re{{out-of-line definition of 'f' does not match any declaration in namespace 'A'$}}
+void A::f() {} // expected-error-re{{out-of-line definition of 'f' does not match any declaration in namespace 'A'{{$}}}}
void A::g(const int&) { } // expected-error{{out-of-line definition of 'g' does not match any declaration in namespace 'A'}}
@@ -160,7 +162,7 @@ namespace N {
void f();
// FIXME: if we move this to a separate definition of N, things break!
}
-void ::global_func2(int) { } // expected-error{{extra qualification on member 'global_func2'}}
+void ::global_func2(int) { } // expected-warning{{extra qualification on member 'global_func2'}}
void N::f() { } // okay
@@ -308,4 +310,103 @@ namespace N {
}
namespace TypedefNamespace { typedef int F; };
-TypedefNamespace::F::NonexistentName BadNNSWithCXXScopeSpec; // expected-error {{expected a class or namespace}}
+TypedefNamespace::F::NonexistentName BadNNSWithCXXScopeSpec; // expected-error {{'F' (aka 'int') is not a class, namespace, or scoped enumeration}}
+
+namespace PR18587 {
+
+struct C1 {
+ int a, b, c;
+ typedef int C2;
+ struct B1 {
+ struct B2 {
+ int a, b, c;
+ };
+ };
+};
+struct C2 { static const unsigned N1 = 1; };
+struct B1 {
+ enum E1 { B2 = 2 };
+ static const int B3 = 3;
+};
+const int N1 = 2;
+
+// Function declarators
+struct S1a { int f(C1::C2); };
+struct S1b { int f(C1:C2); }; // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+
+struct S2a {
+ C1::C2 f(C1::C2);
+};
+struct S2c {
+ C1::C2 f(C1:C2); // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+};
+
+struct S3a {
+ int f(C1::C2), C2 : N1;
+ int g : B1::B2;
+};
+struct S3b {
+ int g : B1:B2; // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+};
+
+// Inside square brackets
+struct S4a {
+ int f[C2::N1];
+};
+struct S4b {
+ int f[C2:N1]; // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+};
+
+struct S5a {
+ int f(int xx[B1::B3 ? C2::N1 : B1::B2]);
+};
+struct S5b {
+ int f(int xx[B1::B3 ? C2::N1 : B1:B2]); // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+};
+struct S5c {
+ int f(int xx[B1:B3 ? C2::N1 : B1::B2]); // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+};
+
+// Bit fields
+struct S6a {
+ C1::C2 m1 : B1::B2;
+};
+struct S6c {
+ C1::C2 m1 : B1:B2; // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+};
+struct S6d {
+ int C2:N1;
+};
+struct S6e {
+ static const int N = 3;
+ B1::E1 : N;
+};
+struct S6g {
+ C1::C2 : B1:B2; // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+ B1::E1 : B1:B2; // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+};
+
+// Template parameters
+template <int N> struct T1 {
+ int a,b,c;
+ static const unsigned N1 = N;
+ typedef unsigned C1;
+};
+T1<C2::N1> var_1a;
+T1<C2:N1> var_1b; // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+template<int N> int F() {}
+int (*X1)() = (B1::B2 ? F<1> : F<2>);
+int (*X2)() = (B1:B2 ? F<1> : F<2>); // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+
+// Bit fields + templates
+struct S7a {
+ T1<B1::B2>::C1 m1 : T1<B1::B2>::N1;
+};
+struct S7b {
+ T1<B1:B2>::C1 m1 : T1<B1::B2>::N1; // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+};
+struct S7c {
+ T1<B1::B2>::C1 m1 : T1<B1:B2>::N1; // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+};
+
+}
diff --git a/test/SemaCXX/new-delete-cxx0x.cpp b/test/SemaCXX/new-delete-cxx0x.cpp
index c404faba2a251..899cb4cda87a2 100644
--- a/test/SemaCXX/new-delete-cxx0x.cpp
+++ b/test/SemaCXX/new-delete-cxx0x.cpp
@@ -2,8 +2,8 @@
void ugly_news(int *ip) {
// These are ill-formed according to one reading of C++98, and at the least
- // have undefined behavior. But they're well-formed, and defined to throw
- // std::bad_array_new_length, in C++11.
+ // 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}}
}
@@ -22,5 +22,12 @@ struct T { // expected-note 2 {{not viable}}
void fn() {
(void) new int[2] {1, 2};
(void) new S[2] {1, 2};
- (void) new T[2] {1, 2}; // expected-error {{no matching constructor}}
+ // 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,
+ // the deallocation function (12.5), and the constructor (12.1).
+ //
+ // 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}}
}
diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp
index 7facd10ca5fc8..cb43458d45786 100644
--- a/test/SemaCXX/new-delete.cpp
+++ b/test/SemaCXX/new-delete.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -triple=i686-pc-linux-gnu
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple=i686-pc-linux-gnu -Wno-new-returns-null
#include <stddef.h>
@@ -517,3 +517,10 @@ class DeletingPlaceholder {
return 0;
}
};
+
+namespace PR18544 {
+ inline void *operator new(size_t); // expected-error {{'operator new' cannot be declared inside a namespace}}
+}
+
+// PR19968
+inline void* operator new(); // expected-error {{'operator new' must have at least one parameter}}
diff --git a/test/SemaCXX/new-null.cpp b/test/SemaCXX/new-null.cpp
new file mode 100644
index 0000000000000..b2be0c5b382f2
--- /dev/null
+++ b/test/SemaCXX/new-null.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+
+typedef __SIZE_TYPE__ size_t;
+
+#if __cplusplus >= 201103L
+struct S1 {
+ void *operator new(size_t n) {
+ return nullptr; // expected-warning {{'operator new' should not return a null pointer unless it is declared 'throw()' or 'noexcept'}}
+ }
+ void *operator new[](size_t n) noexcept {
+ return __null;
+ }
+};
+#endif
+
+struct S2 {
+ static size_t x;
+ void *operator new(size_t n) throw() {
+ return 0;
+ }
+ void *operator new[](size_t n) {
+ return (void*)0;
+#if __cplusplus >= 201103L
+ // expected-warning@-2 {{'operator new[]' should not return a null pointer unless it is declared 'throw()' or 'noexcept'}}
+#else
+ // expected-warning-re@-4 {{'operator new[]' should not return a null pointer unless it is declared 'throw()'{{$}}}}
+#endif
+ }
+};
+
+struct S3 {
+ void *operator new(size_t n) {
+ return 1-1;
+#if __cplusplus >= 201103L
+ // expected-error@-2 {{cannot initialize return object of type 'void *' with an rvalue of type 'int'}}
+#else
+ // expected-warning@-4 {{expression which evaluates to zero treated as a null pointer constant of type 'void *'}}
+ // expected-warning@-5 {{'operator new' should not return a null pointer unless it is declared 'throw()'}}
+#endif
+ }
+ void *operator new[](size_t n) {
+ return (void*)(1-1); // expected-warning {{'operator new[]' should not return a null pointer unless it is declared 'throw()'}}
+ }
+};
+
+#if __cplusplus >= 201103L
+template<bool B> struct S4 {
+ void *operator new(size_t n) noexcept(B) {
+ return 0; // expected-warning {{'operator new' should not return a null pointer}}
+ }
+};
+template struct S4<true>;
+template struct S4<false>; // expected-note {{in instantiation of}}
+#endif
+
+template<typename ...T> struct S5 { // expected-warning 0-1{{extension}}
+ void *operator new(size_t n) throw(T...) {
+ return 0; // expected-warning {{'operator new' should not return a null pointer}}
+ }
+};
+template struct S5<>;
+template struct S5<int>; // expected-note {{in instantiation of}}
diff --git a/test/SemaCXX/nonnull.cpp b/test/SemaCXX/nonnull.cpp
new file mode 100644
index 0000000000000..9ff6d115bd16b
--- /dev/null
+++ b/test/SemaCXX/nonnull.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<int I>
+struct TS {
+ __attribute__((returns_nonnull))
+ void *value_dependent(void) {
+ return I; // no-warning
+ }
+
+ __attribute__((returns_nonnull))
+ void *value_independent(void) {
+ return 0; // expected-warning {{null returned from function that requires a non-null return value}}
+ }
+};
+
diff --git a/test/SemaCXX/ns_returns_retained_block_return.cpp b/test/SemaCXX/ns_returns_retained_block_return.cpp
new file mode 100644
index 0000000000000..9d04536e0f1b9
--- /dev/null
+++ b/test/SemaCXX/ns_returns_retained_block_return.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fblocks -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fblocks -fobjc-arc -fsyntax-only -verify %s
+// expected-no-diagnostics
+// rdar://17259812
+
+typedef void (^BT) ();
+
+class S {
+ BT br() __attribute__((ns_returns_retained)) {
+ return ^{};
+ }
+ BT br1() __attribute__((ns_returns_retained));
+};
+
+BT S::br1() {
+ return ^{};
+}
diff --git a/test/SemaCXX/null_in_arithmetic_ops.cpp b/test/SemaCXX/null_in_arithmetic_ops.cpp
index a919213fb2085..3b42ab44feb9e 100644
--- a/test/SemaCXX/null_in_arithmetic_ops.cpp
+++ b/test/SemaCXX/null_in_arithmetic_ops.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -fblocks -Wnull-arithmetic -verify -Wno-string-plus-int %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -fblocks -Wnull-arithmetic -verify -Wno-string-plus-int -Wno-tautological-pointer-compare %s
#include <stddef.h>
void f() {
diff --git a/test/SemaCXX/nullptr_in_arithmetic_ops.cpp b/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
index 9671353907c76..60b4670b3a5ec 100644
--- a/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
+++ b/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fblocks -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-tautological-pointer-compare -fblocks -std=c++11 -verify %s
void foo() {
int a;
diff --git a/test/SemaCXX/old-style-cast.cpp b/test/SemaCXX/old-style-cast.cpp
new file mode 100644
index 0000000000000..73a78e40ac353
--- /dev/null
+++ b/test/SemaCXX/old-style-cast.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -verify -Wold-style-cast %s
+
+void test1() {
+ long x = (long)12; // expected-warning {{use of old-style cast}}
+ (long)x; // expected-warning {{use of old-style cast}} expected-warning {{expression result unused}}
+ (void**)x; // expected-warning {{use of old-style cast}} expected-warning {{expression result unused}}
+ long y = static_cast<long>(12);
+ (void)y;
+ typedef void VOID;
+ (VOID)y;
+}
diff --git a/test/SemaCXX/operator-arrow-depth.cpp b/test/SemaCXX/operator-arrow-depth.cpp
index 3e2ba8e45228a..769dae0d2461e 100644
--- a/test/SemaCXX/operator-arrow-depth.cpp
+++ b/test/SemaCXX/operator-arrow-depth.cpp
@@ -9,7 +9,7 @@ template<int N> struct A {
template<int N> struct B {
A<N-1> operator->(); // expected-note +{{'operator->' declared here produces an object of type 'A<}}
#if MAX != 2
- // expected-note-re@-2 {{(skipping (120|2) 'operator->'s in backtrace)}}
+ // expected-note-re@-2 {{(skipping {{120|2}} 'operator->'s in backtrace)}}
#endif
};
@@ -22,5 +22,5 @@ A<MAX/2> good;
int n = good->n;
B<MAX/2 + 1> bad;
-int m = bad->n; // expected-error-re {{use of 'operator->' on type 'B<(2|10|128) / 2 \+ 1>' would invoke a sequence of more than (2|10|128) 'operator->' calls}}
+int m = bad->n; // expected-error-re {{use of 'operator->' on type 'B<{{2|10|128}} / 2 + 1>' would invoke a sequence of more than {{2|10|128}} 'operator->' calls}}
// expected-note@-1 {{use -foperator-arrow-depth=N to increase 'operator->' limit}}
diff --git a/test/SemaCXX/overload-0x.cpp b/test/SemaCXX/overload-0x.cpp
index 677d16a32c121..1c185a5725bd6 100644
--- a/test/SemaCXX/overload-0x.cpp
+++ b/test/SemaCXX/overload-0x.cpp
@@ -1,7 +1,11 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
namespace test0 {
- struct A { // expected-note {{candidate function (the implicit copy assignment operator) not viable: 'this' argument has type 'const test0::A', but method is not marked const}} expected-note {{candidate function (the implicit move assignment operator) not viable: 'this' argument has type 'const test0::A', but method is not marked const}}
+ struct A { // expected-note {{candidate function (the implicit copy assignment operator) not viable: 'this' argument has type 'const test0::A', but method is not marked const}}
+#if __cplusplus >= 201103L
+ // expected-note@-2 {{candidate function (the implicit move assignment operator) not viable: 'this' argument has type 'const test0::A', but method is not marked const}}
+#endif
A &operator=(void*); // expected-note {{candidate function not viable: 'this' argument has type 'const test0::A', but method is not marked const}}
};
@@ -9,3 +13,79 @@ namespace test0 {
a = "help"; // expected-error {{no viable overloaded '='}}
}
}
+
+namespace PR16314 {
+ void f(char*);
+ int &f(...);
+ void x()
+ {
+ int &n = f("foo");
+#if __cplusplus < 201103L
+ // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}
+ // expected-error@-3 {{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'void'}}
+#endif
+ }
+}
+
+namespace warn_if_best {
+ int f(char *);
+ void f(double);
+ void x()
+ {
+ int n = f("foo");
+#if __cplusplus < 201103L
+ // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}
+#else
+ // expected-warning@-4 {{ISO C++11 does not allow conversion from string literal to 'char *'}}
+#endif
+ }
+}
+
+namespace userdefined_vs_illformed {
+ struct X { X(const char *); };
+
+ void *f(char *p); // best for C++03
+ double f(X x); // best for C++11
+ void g()
+ {
+ double d = f("foo");
+#if __cplusplus < 201103L
+ // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}
+ // expected-error@-3 {{cannot initialize a variable of type 'double' with an rvalue of type 'void *'}}
+#endif
+ }
+}
+
+namespace sfinae_test {
+ int f(int, char*);
+
+ template<int T>
+ struct S { typedef int type; };
+
+ template<>
+ struct S<sizeof(int)> { typedef void type; };
+
+ // C++11: SFINAE failure
+ // C++03: ok
+ template<typename T> int cxx11_ignored(T, typename S<sizeof(f(T(), "foo"))>::type *);
+#if __cplusplus < 201103L
+ // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}
+#else
+ // expected-note@-4 {{candidate template ignored: substitution failure}}
+#endif
+
+ // C++11: better than latter
+ // C++03: worse than latter
+ template<typename T> void g(T, ...);
+ template<typename T> int g(T, typename S<sizeof(f(T(), "foo"))>::type *);
+#if __cplusplus < 201103L
+ // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}
+#endif
+
+ int a = cxx11_ignored(0, 0);
+ int b = g(0, 0);
+#if __cplusplus >= 201103L
+ // expected-error@-3 {{no matching function for call to 'cxx11_ignored'}}
+ // expected-error@-3 {{cannot initialize a variable of type 'int' with an rvalue of type 'void'}}
+#endif
+}
diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp
index 615b10a439715..19ce14481f8ef 100644
--- a/test/SemaCXX/overload-call.cpp
+++ b/test/SemaCXX/overload-call.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+// RUN: %clang_cc1 -pedantic -verify %s
int* f(int) { return 0; }
float* f(float) { return 0; }
void f();
@@ -580,3 +580,31 @@ namespace PR12931 {
void f(const volatile int &, int);
void g() { f(0, 0); }
}
+
+void test5() {
+ struct {
+ typedef void F1(int);
+ typedef void F2(double);
+ operator F1*(); // expected-note{{conversion candidate}}
+ operator F2*(); // expected-note{{conversion candidate}}
+ } callable;
+ callable(); // expected-error{{no matching function for call}}
+}
+
+namespace PR20218 {
+ void f(void (*const &)()); // expected-note 2{{candidate}}
+ void f(void (&&)()) = delete; // expected-note 2{{candidate}} expected-warning 2{{extension}}
+ void g(void (&&)()) = delete; // expected-note 2{{candidate}} expected-warning 2{{extension}}
+ void g(void (*const &)()); // expected-note 2{{candidate}}
+
+ void x();
+ typedef void (&fr)();
+ struct Y { operator fr(); } y;
+
+ void h() {
+ f(x); // expected-error {{ambiguous}}
+ g(x); // expected-error {{ambiguous}}
+ f(y); // expected-error {{ambiguous}}
+ g(y); // expected-error {{ambiguous}}
+ }
+}
diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp
index 99105cb5b60bc..feb7c716ff008 100644
--- a/test/SemaCXX/overloaded-operator.cpp
+++ b/test/SemaCXX/overloaded-operator.cpp
@@ -452,3 +452,70 @@ namespace PR7681 {
Result = 1; // expected-error {{no viable overloaded '='}} // expected-note {{type 'PointerUnion<int *, float *>' is incomplete}}
}
}
+
+namespace PR14995 {
+ struct B {};
+ template<typename ...T> void operator++(B, T...) {}
+
+ void f() {
+ B b;
+ b++; // ok
+ ++b; // ok
+ }
+
+ template<typename... T>
+ struct C {
+ void operator-- (T...) {}
+ };
+
+ void g() {
+ C<int> postfix;
+ C<> prefix;
+ postfix--; // ok
+ --prefix; // ok
+ }
+
+ struct D {};
+ template<typename T> void operator++(D, T) {}
+
+ void h() {
+ D d;
+ d++; // ok
+ ++d; // expected-error{{cannot increment value of type 'PR14995::D'}}
+ }
+
+ template<typename...T> struct E {
+ void operator++(T...) {} // expected-error{{parameter of overloaded post-increment operator must have type 'int' (not 'char')}}
+ };
+
+ E<char> e; // expected-note {{in instantiation of template class 'PR14995::E<char>' requested here}}
+
+ struct F {
+ template<typename... T>
+ int operator++ (T...) {}
+ };
+
+ int k1 = F().operator++(0, 0);
+ int k2 = F().operator++('0');
+ // expected-error@-5 {{overloaded 'operator++' must be a unary or binary operator}}
+ // expected-note@-3 {{in instantiation of function template specialization 'PR14995::F::operator++<int, int>' requested here}}
+ // expected-error@-4 {{no matching member function for call to 'operator++'}}
+ // expected-note@-8 {{candidate template ignored: substitution failure}}
+ // expected-error@-9 {{parameter of overloaded post-increment operator must have type 'int' (not 'char')}}
+ // expected-note@-6 {{in instantiation of function template specialization 'PR14995::F::operator++<char>' requested here}}
+ // expected-error@-7 {{no matching member function for call to 'operator++'}}
+ // expected-note@-12 {{candidate template ignored: substitution failure}}
+} // namespace PR14995
+
+namespace ConversionVersusTemplateOrdering {
+ struct A {
+ operator short() = delete;
+ template <typename T> operator T();
+ } a;
+ struct B {
+ template <typename T> operator T();
+ operator short() = delete;
+ } b;
+ int x = a;
+ int y = b;
+}
diff --git a/test/SemaCXX/pr13394-crash-on-invalid.cpp b/test/SemaCXX/pr13394-crash-on-invalid.cpp
index 841e3c203402c..304ee92f6a8da 100644
--- a/test/SemaCXX/pr13394-crash-on-invalid.cpp
+++ b/test/SemaCXX/pr13394-crash-on-invalid.cpp
@@ -8,12 +8,12 @@ namespace stretch_v1 {
}
namespace gatekeeper_v1 {
namespace gatekeeper_factory_v1 {
- struct closure_t { // expected-note {{'closure_t' declared here}}
+ struct closure_t { // expected-note {{'closure_t' declared here}} expected-note {{'gatekeeper_factory_v1::closure_t' declared here}}
gatekeeper_v1::closure_t* create(); // expected-error {{no type named 'closure_t' in namespace 'gatekeeper_v1'; did you mean simply 'closure_t'?}}
};
}
// FIXME: Typo correction should remove the 'gatekeeper_v1::' name specifier
- gatekeeper_v1::closure_t *x; // expected-error-re {{no type named 'closure_t' in namespace 'gatekeeper_v1'$}}
+ gatekeeper_v1::closure_t *x; // expected-error {{no type named 'closure_t' in namespace 'gatekeeper_v1'; did you mean 'gatekeeper_factory_v1::closure_t'}}
}
namespace Foo {
diff --git a/test/SemaCXX/pr18284-crash-on-invalid.cpp b/test/SemaCXX/pr18284-crash-on-invalid.cpp
new file mode 100644
index 0000000000000..5b1cb21f4bb6b
--- /dev/null
+++ b/test/SemaCXX/pr18284-crash-on-invalid.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// Don't crash (PR18284).
+
+namespace n1 {
+class A { };
+class C { A a; };
+
+A::RunTest() {} // expected-error {{C++ requires a type specifier for all declarations}}
+
+void f() {
+ new C;
+}
+} // namespace n1
+
+namespace n2 {
+class A { };
+class C : public A { };
+
+A::RunTest() {} // expected-error {{C++ requires a type specifier for all declarations}}
+
+void f() {
+ new C;
+}
+} // namespace n2
diff --git a/test/SemaCXX/pr9812.c b/test/SemaCXX/pr9812.c
new file mode 100644
index 0000000000000..cbbe44ba7ca0d
--- /dev/null
+++ b/test/SemaCXX/pr9812.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#define bool _Bool
+int test1(int argc, char** argv)
+{
+ bool signed; // expected-error {{'bool' cannot be signed or unsigned}} expected-warning {{declaration does not declare anything}}
+
+ return 0;
+}
+#undef bool
+
+typedef int bool;
+
+int test2(int argc, char** argv)
+{
+ bool signed; // expected-error {{'type-name' cannot be signed or unsigned}} expected-warning {{declaration does not declare anything}}
+ _Bool signed; // expected-error {{'_Bool' cannot be signed or unsigned}} expected-warning {{declaration does not declare anything}}
+
+ return 0;
+}
+
diff --git a/test/SemaCXX/pr9812.cpp b/test/SemaCXX/pr9812.cpp
new file mode 100644
index 0000000000000..2cd0bede02012
--- /dev/null
+++ b/test/SemaCXX/pr9812.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int test(int, char**)
+{
+ bool signed; // expected-error {{'bool' cannot be signed or unsigned}} expected-warning {{declaration does not declare anything}}
+
+ return 0;
+}
+
diff --git a/test/SemaCXX/pragma-init_seg.cpp b/test/SemaCXX/pragma-init_seg.cpp
new file mode 100644
index 0000000000000..e18d0e6814afc
--- /dev/null
+++ b/test/SemaCXX/pragma-init_seg.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s -triple x86_64-pc-win32
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s -triple i386-apple-darwin13.3.0
+
+#ifndef __APPLE__
+#pragma init_seg(L".my_seg") // expected-warning {{expected 'compiler', 'lib', 'user', or a string literal}}
+#pragma init_seg( // expected-warning {{expected 'compiler', 'lib', 'user', or a string literal}}
+#pragma init_seg asdf // expected-warning {{missing '('}}
+#pragma init_seg) // expected-warning {{missing '('}}
+#pragma init_seg("a" "b") // no warning
+#pragma init_seg("a", "b") // expected-warning {{missing ')'}}
+#pragma init_seg("a") asdf // expected-warning {{extra tokens at end of '#pragma init_seg'}}
+#pragma init_seg("\x") // expected-error {{\x used with no following hex digits}}
+#pragma init_seg("a" L"b") // expected-warning {{expected non-wide string literal in '#pragma init_seg'}}
+
+#pragma init_seg(compiler)
+#else
+#pragma init_seg(compiler) // expected-warning {{'#pragma init_seg' is only supported when targeting a Microsoft environment}}
+#endif
+
+int f();
+int __declspec(thread) x = f(); // expected-error {{initializer for thread-local variable must be a constant expression}}
diff --git a/test/SemaCXX/pragma-optimize.cpp b/test/SemaCXX/pragma-optimize.cpp
new file mode 100644
index 0000000000000..0f03b81f5fffc
--- /dev/null
+++ b/test/SemaCXX/pragma-optimize.cpp
@@ -0,0 +1,113 @@
+// RUN: %clang_cc1 -x c++ -std=c++11 -triple x86_64-unknown-linux -emit-llvm -O2 < %s | FileCheck %s
+
+#pragma clang optimize off
+
+// This is a macro definition and therefore its text is not present after
+// preprocessing. The pragma has no effect here.
+#define CREATE_FUNC(name) \
+int name (int param) { \
+ return param; \
+} \
+
+// This is a declaration and therefore it is not decorated with `optnone`.
+extern int foo(int a, int b);
+// CHECK-DAG: @_Z3fooii{{.*}} [[ATTRFOO:#[0-9]+]]
+
+// This is a definition and therefore it will be decorated with `optnone`.
+int bar(int x, int y) {
+ for(int i = 0; i < x; ++i)
+ y += x;
+ return y + foo(x, y);
+}
+// CHECK-DAG: @_Z3barii{{.*}} [[ATTRBAR:#[0-9]+]]
+
+// The function "int created (int param)" created by the macro invocation
+// is also decorated with the `optnone` attribute because it is within a
+// region of code affected by the functionality (not because of the position
+// of the macro definition).
+CREATE_FUNC (created)
+// CHECK-DAG: @_Z7createdi{{.*}} [[ATTRCREATED:#[0-9]+]]
+
+class MyClass {
+ public:
+ // The declaration of the method is not decorated with `optnone`.
+ int method(int blah);
+};
+
+// The definition of the method instead is decorated with `optnone`.
+int MyClass::method(int blah) {
+ return blah + 1;
+}
+// CHECK-DAG: @_ZN7MyClass6methodEi{{.*}} [[ATTRMETHOD:#[0-9]+]]
+
+// A template declaration will not be decorated with `optnone`.
+template <typename T> T twice (T param);
+
+// The template definition will be decorated with the attribute `optnone`.
+template <typename T> T thrice (T param) {
+ return 3 * param;
+}
+
+// This function definition will not be decorated with `optnone` because the
+// attribute would conflict with `always_inline`.
+int __attribute__((always_inline)) baz(int z) {
+ return foo(z, 2);
+}
+// CHECK-DAG: @_Z3bazi{{.*}} [[ATTRBAZ:#[0-9]+]]
+
+#pragma clang optimize on
+
+// The function "int wombat(int param)" created by the macro is not
+// decorated with `optnone`, because the pragma applies its effects only
+// after preprocessing. The position of the macro definition is not
+// relevant.
+CREATE_FUNC (wombat)
+// CHECK-DAG: @_Z6wombati{{.*}} [[ATTRWOMBAT:#[0-9]+]]
+
+// This instantiation of the "twice" template function with a "float" type
+// will not have an `optnone` attribute because the template declaration was
+// not affected by the pragma.
+float container (float par) {
+ return twice(par);
+}
+// CHECK-DAG: @_Z9containerf{{.*}} [[ATTRCONTAINER:#[0-9]+]]
+// CHECK-DAG: @_Z5twiceIfET_S0_{{.*}} [[ATTRTWICE:#[0-9]+]]
+
+// This instantiation of the "thrice" template function with a "float" type
+// will have an `optnone` attribute because the template definition was
+// affected by the pragma.
+float container2 (float par) {
+ return thrice(par);
+}
+// CHECK-DAG: @_Z10container2f{{.*}} [[ATTRCONTAINER2:#[0-9]+]]
+// CHECK-DAG: @_Z6thriceIfET_S0_{{.*}} [[ATTRTHRICEFLOAT:#[0-9]+]]
+
+
+// A template specialization is a new definition and it will not be
+// decorated with an `optnone` attribute because it is now outside of the
+// affected region.
+template<> int thrice(int par) {
+ return (par << 1) + par;
+}
+int container3 (int par) {
+ return thrice(par);
+}
+// CHECK-DAG: @_Z10container3i{{.*}} [[ATTRCONTAINER3:#[0-9]+]]
+// CHECK-DAG: @_Z6thriceIiET_S0_{{.*}} [[ATTRTHRICEINT:#[0-9]+]]
+
+
+// Check for both noinline and optnone on each function that should have them.
+// CHECK-DAG: attributes [[ATTRBAR]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
+// CHECK-DAG: attributes [[ATTRCREATED]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
+// CHECK-DAG: attributes [[ATTRMETHOD]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
+// CHECK-DAG: attributes [[ATTRTHRICEFLOAT]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
+
+// Check that the other functions do NOT have optnone.
+// CHECK-DAG-NOT: attributes [[ATTRFOO]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRBAZ]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRWOMBAT]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRCONTAINER]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRTWICE]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRCONTAINER2]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRCONTAINER3]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRTHRICEINT]] = { {{.*}}optnone{{.*}} }
diff --git a/test/SemaCXX/pragma-vtordisp.cpp b/test/SemaCXX/pragma-vtordisp.cpp
new file mode 100644
index 0000000000000..49841c51ef054
--- /dev/null
+++ b/test/SemaCXX/pragma-vtordisp.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -std=c++11 -fms-extensions -fms-compatibility -fsyntax-only -triple=i386-pc-win32 -verify %s
+
+struct A { int a; };
+
+#pragma vtordisp(pop) // expected-warning {{#pragma vtordisp(pop, ...) failed: stack empty}}
+#pragma vtordisp(push, 0)
+#pragma vtordisp(push, 1)
+#pragma vtordisp(push, 2)
+struct B : virtual A { int b; };
+#pragma vtordisp(pop)
+#pragma vtordisp(pop)
+#pragma vtordisp(pop)
+#pragma vtordisp(pop) // expected-warning {{#pragma vtordisp(pop, ...) failed: stack empty}}
+
+#pragma vtordisp(push, 3) // expected-warning {{expected integer between 0 and 2 inclusive in '#pragma vtordisp' - ignored}}
+#pragma vtordisp()
+
+#define ONE 1
+#pragma vtordisp(push, ONE)
+#define TWO 1
+#pragma vtordisp(push, TWO)
+
+// Test a reset.
+#pragma vtordisp()
+#pragma vtordisp(pop) // expected-warning {{#pragma vtordisp(pop, ...) failed: stack empty}}
+
+#pragma vtordisp( // expected-warning {{unknown action for '#pragma vtordisp' - ignored}}
+#pragma vtordisp(asdf) // expected-warning {{unknown action for '#pragma vtordisp' - ignored}}
+#pragma vtordisp(,) // expected-warning {{unknown action for '#pragma vtordisp' - ignored}}
+#pragma vtordisp // expected-warning {{missing '(' after '#pragma vtordisp' - ignoring}}
+#pragma vtordisp(3) // expected-warning {{expected integer between 0 and 2 inclusive in '#pragma vtordisp' - ignored}}
+#pragma vtordisp(), stuff // expected-warning {{extra tokens}}
+
+struct C {
+// FIXME: Our implementation based on token insertion makes it impossible for
+// the pragma to appear everywhere we should support it.
+//#pragma vtordisp()
+ struct D : virtual A {
+ };
+};
diff --git a/test/SemaCXX/pragma-weak.cpp b/test/SemaCXX/pragma-weak.cpp
index 057cf6b463f39..c1ff2062fcfa2 100644
--- a/test/SemaCXX/pragma-weak.cpp
+++ b/test/SemaCXX/pragma-weak.cpp
@@ -6,3 +6,6 @@ extern "C" {
void foo() {
};
}
+
+extern "C" int Test;
+#pragma weak test = Test
diff --git a/test/SemaCXX/primary-base.cpp b/test/SemaCXX/primary-base.cpp
index 0b6aaef493cbf..d305aa3b72db8 100644
--- a/test/SemaCXX/primary-base.cpp
+++ b/test/SemaCXX/primary-base.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify %s
// expected-no-diagnostics
class A { virtual void f(); };
class B : virtual A { };
diff --git a/test/SemaCXX/qualified-id-lookup.cpp b/test/SemaCXX/qualified-id-lookup.cpp
index 23164fa42f325..8eef6f4182746 100644
--- a/test/SemaCXX/qualified-id-lookup.cpp
+++ b/test/SemaCXX/qualified-id-lookup.cpp
@@ -94,7 +94,7 @@ namespace a {
void test_a() {
a::a::i = 3; // expected-error{{no member named 'i' in namespace 'a::a'; did you mean 'a::a::a::i'?}}
a::a::a::i = 4;
- a::a::j = 3; // expected-error-re{{no member named 'j' in namespace 'a::a'$}}
+ a::a::j = 3; // expected-error-re{{no member named 'j' in namespace 'a::a'{{$}}}}
}
struct Undef { // expected-note{{definition of 'Undef' is not complete until the closing '}'}}
diff --git a/test/SemaCXX/references.cpp b/test/SemaCXX/references.cpp
index 37fc2a856fd97..cfe7dc1f428b8 100644
--- a/test/SemaCXX/references.cpp
+++ b/test/SemaCXX/references.cpp
@@ -85,9 +85,19 @@ void test8(int& const,// expected-error{{'const' qualifier may not be applied to
typedef int& intref;
typedef intref& intrefref; // C++ DR 106: reference collapsing
- typedef intref const intref_c; // okay. FIXME: how do we verify that this is the same type as intref?
+ typedef intref const intref_c; // expected-warning {{'const' qualifier on reference type 'intref' (aka 'int &') has no effect}}
+ typedef intref_c intref; // ok, same type
+
+ typedef intref volatile intref; // expected-warning {{'volatile' qualifier on reference type 'intref' (aka 'int &') has no effect}}
+ typedef intref _Atomic intref; // expected-warning {{'_Atomic' qualifier on reference type 'intref' (aka 'int &') has no effect}}
+
+ void restrict_ref(__restrict intref); // ok
+ void restrict_ref(int &__restrict); // ok
}
+template<typename T> int const_param(const T) {}
+int const_ref_param = const_param<int&>(const_ref_param); // no-warning
+
class string {
char *Data;
diff --git a/test/SemaCXX/reinterpret-cast.cpp b/test/SemaCXX/reinterpret-cast.cpp
index a4bc4325e6550..4284032d9ba9b 100644
--- a/test/SemaCXX/reinterpret-cast.cpp
+++ b/test/SemaCXX/reinterpret-cast.cpp
@@ -96,12 +96,12 @@ void memptrs()
void (structure::*psf)() = 0;
(void)reinterpret_cast<int (structure::*)()>(psf);
- (void)reinterpret_cast<void (structure::*)()>(psi); // expected-error {{reinterpret_cast from 'const int structure::*' to 'void (structure::*)()' is not allowed}}
- (void)reinterpret_cast<int structure::*>(psf); // expected-error {{reinterpret_cast from 'void (structure::*)()' to 'int structure::*' is not allowed}}
+ (void)reinterpret_cast<void (structure::*)()>(psi); // expected-error-re {{reinterpret_cast from 'const int structure::*' to 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' is not allowed}}
+ (void)reinterpret_cast<int structure::*>(psf); // expected-error-re {{reinterpret_cast from 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' to 'int structure::*' is not allowed}}
// Cannot cast from integers to member pointers, not even the null pointer
// literal.
- (void)reinterpret_cast<void (structure::*)()>(0); // expected-error {{reinterpret_cast from 'int' to 'void (structure::*)()' is not allowed}}
+ (void)reinterpret_cast<void (structure::*)()>(0); // expected-error-re {{reinterpret_cast from 'int' to 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' is not allowed}}
(void)reinterpret_cast<int structure::*>(0); // expected-error {{reinterpret_cast from 'int' to 'int structure::*' is not allowed}}
}
diff --git a/test/SemaCXX/return-noreturn.cpp b/test/SemaCXX/return-noreturn.cpp
index 617de0089585d..531dc23995d27 100644
--- a/test/SemaCXX/return-noreturn.cpp
+++ b/test/SemaCXX/return-noreturn.cpp
@@ -40,6 +40,14 @@ namespace abort_struct_complex_cfgs {
switch (x) default: L1: L2: case 4: { pr6884_abort_struct(); }
}
+ // FIXME: detect noreturn destructors triggered by calls to delete.
+ int f7(int x) {
+ switch (x) default: L1: L2: case 4: {
+ pr6884_abort_struct *p = new pr6884_abort_struct();
+ delete p;
+ }
+ } // expected-warning {{control reaches end of non-void function}}
+
// Test that these constructs work even when extraneous blocks are created
// before and after the switch due to implicit destructors.
int g1(int x) {
@@ -138,3 +146,25 @@ void PR9412_f() {
PR9412_t<PR9412_Exact>(); // expected-note {{in instantiation of function template specialization 'PR9412_t<0>' requested here}}
}
+#if __cplusplus >= 201103L
+namespace LambdaVsTemporaryDtor {
+ struct Y { ~Y(); };
+ struct X { template<typename T> X(T, Y = Y()) {} };
+
+ struct Fatal { ~Fatal() __attribute__((noreturn)); };
+ struct FatalCopy { FatalCopy(); FatalCopy(const FatalCopy&, Fatal F = Fatal()); };
+
+ void foo();
+
+ int bar() {
+ X work([](){ Fatal(); });
+ foo();
+ } // expected-warning {{control reaches end of non-void function}}
+
+ int baz() {
+ FatalCopy fc;
+ X work([fc](){});
+ foo();
+ } // ok, initialization of lambda does not return
+}
+#endif
diff --git a/test/SemaCXX/return-stack-addr.cpp b/test/SemaCXX/return-stack-addr.cpp
index fbbaf836f1abf..7670798ecb9c1 100644
--- a/test/SemaCXX/return-stack-addr.cpp
+++ b/test/SemaCXX/return-stack-addr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
int* ret_local() {
int x = 1;
@@ -108,6 +108,11 @@ int* ret_cpp_const_cast(const int x) {
return const_cast<int*>(&x); // expected-warning {{address of stack memory}}
}
+struct A { virtual ~A(); }; struct B : A {};
+A* ret_cpp_dynamic_cast(B b) {
+ return dynamic_cast<A*>(&b); // expected-warning {{address of stack memory}}
+}
+
// PR 7999 - handle the case where a field is itself a reference.
template <typename T> struct PR7999 {
PR7999(T& t) : value(t) {}
@@ -137,5 +142,17 @@ namespace PR8774 {
}
}
-// TODO: test case for dynamic_cast. clang does not yet have
-// support for C++ classes to write such a test case.
+// Don't warn about returning a local variable from a surrounding function if
+// we're within a lambda-expression.
+void ret_from_lambda() {
+ int a;
+ int &b = a;
+ (void) [&]() -> int& { return a; };
+ (void) [&]() -> int& { return b; };
+ (void) [=]() mutable -> int& { return a; };
+ (void) [=]() mutable -> int& { return b; };
+ (void) [&]() -> int& { int a; return a; }; // expected-warning {{reference to stack}}
+ (void) [=]() -> int& { int a; return a; }; // expected-warning {{reference to stack}}
+ (void) [&]() -> int& { int &a = b; return a; };
+ (void) [=]() mutable -> int& { int &a = b; return a; };
+}
diff --git a/test/SemaCXX/return.cpp b/test/SemaCXX/return.cpp
index 580f0a7233e2c..98dbd51f58068 100644
--- a/test/SemaCXX/return.cpp
+++ b/test/SemaCXX/return.cpp
@@ -102,3 +102,13 @@ namespace return_has_expr {
}
};
}
+
+// rdar://15366494
+// pr17759
+namespace ctor_returns_void {
+ void f() {}
+ struct S {
+ S() { return f(); }; // expected-error {{constructor 'S' must not return void expression}}
+ ~S() { return f(); } // expected-error {{destructor '~S' must not return void expression}}
+ };
+}
diff --git a/test/SemaCXX/rval-references-examples.cpp b/test/SemaCXX/rval-references-examples.cpp
index 110ae26fb5d29..8a5b562bbb982 100644
--- a/test/SemaCXX/rval-references-examples.cpp
+++ b/test/SemaCXX/rval-references-examples.cpp
@@ -4,7 +4,7 @@ template<typename T>
class unique_ptr {
T *ptr;
- unique_ptr(const unique_ptr&) = delete; // expected-note 3{{function has been explicitly marked deleted here}}
+ unique_ptr(const unique_ptr&) = delete; // expected-note 3{{'unique_ptr' has been explicitly marked deleted here}}
unique_ptr &operator=(const unique_ptr&) = delete; // expected-note{{candidate function has been explicitly deleted}}
public:
unique_ptr() : ptr(0) { }
diff --git a/test/SemaCXX/scope-check.cpp b/test/SemaCXX/scope-check.cpp
index 90c9317ecdfb8..dc15dc8b3e600 100644
--- a/test/SemaCXX/scope-check.cpp
+++ b/test/SemaCXX/scope-check.cpp
@@ -1,6 +1,18 @@
// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -fcxx-exceptions %s -Wno-unreachable-code
// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -fcxx-exceptions -std=gnu++11 %s -Wno-unreachable-code
+namespace testInvalid {
+Invalid inv; // expected-error {{unknown type name}}
+// Make sure this doesn't assert.
+void fn()
+{
+ int c = 0;
+ if (inv)
+Here: ;
+ goto Here;
+}
+}
+
namespace test0 {
struct D { ~D(); };
@@ -226,7 +238,7 @@ namespace test12 {
static void *ips[] = { &&l0 };
const C c0 = 17;
l0: // expected-note {{possible target of indirect goto}}
- const C &c1 = 42; // expected-note {{jump exits scope of variable with non-trivial destructor}}
+ const C &c1 = 42; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
const C &c2 = c0;
goto *ip; // expected-error {{indirect goto might cross protected scopes}}
}
@@ -241,7 +253,7 @@ namespace test13 {
void f(void **ip) {
static void *ips[] = { &&l0 };
l0: // expected-note {{possible target of indirect goto}}
- const int &c1 = C(1).i; // expected-note {{jump exits scope of variable with non-trivial destructor}}
+ const int &c1 = C(1).i; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
goto *ip; // expected-error {{indirect goto might cross protected scopes}}
}
}
@@ -295,15 +307,137 @@ x: return s.get();
}
#endif
-// This test must be last, because the error prohibits further jump diagnostics.
-namespace testInvalid {
-Invalid inv; // expected-error {{unknown type name}}
-// Make sure this doesn't assert.
-void fn()
-{
- int c = 0;
- if (inv)
-Here: ;
- goto Here;
+namespace test18 {
+ struct A { ~A(); };
+ struct B { const int &r; const A &a; };
+ int f() {
+ void *p = &&x;
+ const A a = A();
+ x:
+ B b = { 0, a }; // ok
+ goto *p;
+ }
+ int g() {
+ void *p = &&x;
+ x: // expected-note {{possible target of indirect goto}}
+ B b = { 0, A() }; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
+ goto *p; // expected-error {{indirect goto might cross protected scopes}}
+ }
+}
+
+#if __cplusplus >= 201103L
+namespace std {
+ typedef decltype(sizeof(int)) size_t;
+ template<typename T> struct initializer_list {
+ const T *begin;
+ size_t size;
+ initializer_list(const T *, size_t);
+ };
+}
+namespace test19 {
+ struct A { ~A(); };
+
+ int f() {
+ void *p = &&x;
+ A a;
+ x: // expected-note {{possible target of indirect goto}}
+ std::initializer_list<A> il = { a }; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
+ goto *p; // expected-error {{indirect goto might cross protected scopes}}
+ }
+}
+
+namespace test20 {
+ struct A { ~A(); };
+ struct B {
+ const A &a;
+ };
+
+ int f() {
+ void *p = &&x;
+ A a;
+ x:
+ std::initializer_list<B> il = {
+ a,
+ a
+ };
+ goto *p;
+ }
+ int g() {
+ void *p = &&x;
+ A a;
+ x: // expected-note {{possible target of indirect goto}}
+ std::initializer_list<B> il = {
+ a,
+ { A() } // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
+ };
+ goto *p; // expected-error {{indirect goto might cross protected scopes}}
+ }
}
+#endif
+
+namespace test21 {
+ template<typename T> void f() {
+ goto x; // expected-error {{protected scope}}
+ T t; // expected-note {{bypasses}}
+ x: return;
+ }
+
+ template void f<int>();
+ struct X { ~X(); };
+ template void f<X>(); // expected-note {{instantiation of}}
+}
+
+namespace PR18217 {
+ typedef int *X;
+
+ template <typename T>
+ class MyCl {
+ T mem;
+ };
+
+ class Source {
+ MyCl<X> m;
+ public:
+ int getKind() const;
+ };
+
+ bool b;
+ template<typename TT>
+ static void foo(const Source &SF, MyCl<TT *> Source::*m) {
+ switch (SF.getKind()) {
+ case 1: return;
+ case 2: break;
+ case 3:
+ case 4: return;
+ };
+ if (b) {
+ auto &y = const_cast<MyCl<TT *> &>(SF.*m); // expected-warning 0-1{{extension}}
+ }
+ }
+
+ int Source::getKind() const {
+ foo(*this, &Source::m);
+ return 0;
+ }
+}
+
+namespace test_recovery {
+ // Test that jump scope checking recovers when there are unspecified errors
+ // in the function declaration or body.
+
+ void test(nexist, int c) { // expected-error {{}}
+ nexist_fn(); // expected-error {{}}
+ goto nexist_label; // expected-error {{use of undeclared label}}
+ goto a0; // expected-error {{goto into protected scope}}
+ int a = 0; // expected-note {{jump bypasses variable initialization}}
+ a0:;
+
+ switch (c) {
+ case $: // expected-error {{}}
+ case 0:
+ int x = 56; // expected-note {{jump bypasses variable initialization}}
+ case 1: // expected-error {{switch case is in protected scope}}
+ x = 10;
+ }
+ }
}
diff --git a/test/SemaCXX/sourceranges.cpp b/test/SemaCXX/sourceranges.cpp
index 1f25d5bce93ca..9ba003aa204a7 100644
--- a/test/SemaCXX/sourceranges.cpp
+++ b/test/SemaCXX/sourceranges.cpp
@@ -12,7 +12,7 @@ enum B {};
typedef int C;
}
-// CHECK: VarDecl {{0x[0-9a-fA-F]+}} <line:16:1, col:36> ImplicitConstrArray 'foo::A [2]'
+// CHECK: VarDecl {{0x[0-9a-fA-F]+}} <line:16:1, col:36> col:15 ImplicitConstrArray 'foo::A [2]'
static foo::A ImplicitConstrArray[2];
int main() {
@@ -28,3 +28,12 @@ foo::A getName() {
// CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:10, col:17> 'foo::A'
return foo::A();
}
+
+void destruct(foo::A *a1, foo::A *a2, P<int> *p1) {
+ // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:8> '<bound member function type>' ->~A
+ a1->~A();
+ // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:16> '<bound member function type>' ->~A
+ a2->foo::A::~A();
+ // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:13> '<bound member function type>' ->~P
+ p1->~P<int>();
+}
diff --git a/test/SemaCXX/static-assert.cpp b/test/SemaCXX/static-assert.cpp
index 4a7560ba5b6a2..7de4d07b50b8e 100644
--- a/test/SemaCXX/static-assert.cpp
+++ b/test/SemaCXX/static-assert.cpp
@@ -48,3 +48,6 @@ template<typename T> struct StaticAssertProtected {
struct X { ~X(); };
StaticAssertProtected<int> sap1;
StaticAssertProtected<X> sap2; // expected-note {{instantiation}}
+
+static_assert(true); // expected-warning {{C++1z extension}}
+static_assert(false); // expected-error-re {{failed{{$}}}} expected-warning {{extension}}
diff --git a/test/SemaCXX/static-cast.cpp b/test/SemaCXX/static-cast.cpp
index 7fb016ea86d8b..06fd8636e5d6d 100644
--- a/test/SemaCXX/static-cast.cpp
+++ b/test/SemaCXX/static-cast.cpp
@@ -9,6 +9,8 @@ struct F : public C1 {}; // Single path to B with virtual.
struct G1 : public B {};
struct G2 : public B {};
struct H : public G1, public G2 {}; // Ambiguous path to B.
+struct I; // Incomplete.
+struct J; // Incomplete.
enum Enum { En1, En2 };
enum Onom { On1, On2 };
@@ -131,6 +133,7 @@ void t_529_9()
// Bad code below
(void)static_cast<int A::*>((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'H' to pointer to member of base class 'A':}}
(void)static_cast<int A::*>((int F::*)0); // expected-error {{conversion from pointer to member of class 'F' to pointer to member of class 'A' via virtual base 'B' is not allowed}}
+ (void)static_cast<int I::*>((int J::*)0); // expected-error {{static_cast from 'int J::*' to 'int I::*' is not allowed}}
}
// PR 5261 - static_cast should instantiate template if possible
@@ -192,6 +195,6 @@ namespace PR6072 {
(void)static_cast<void (A::*)()>(&B::f);
(void)static_cast<void (B::*)()>(&B::f);
(void)static_cast<void (C::*)()>(&B::f);
- (void)static_cast<void (D::*)()>(&B::f); // expected-error{{address of overloaded function 'f' cannot be static_cast to type 'void (PR6072::D::*)()'}}
+ (void)static_cast<void (D::*)()>(&B::f); // expected-error-re{{address of overloaded function 'f' cannot be static_cast to type 'void (PR6072::D::*)(){{( __attribute__\(\(thiscall\)\))?}}'}}
}
}
diff --git a/test/SemaCXX/switch-implicit-fallthrough-blocks.cpp b/test/SemaCXX/switch-implicit-fallthrough-blocks.cpp
new file mode 100644
index 0000000000000..9a16f2b4b402f
--- /dev/null
+++ b/test/SemaCXX/switch-implicit-fallthrough-blocks.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++11 -Wimplicit-fallthrough %s
+
+void fallthrough_in_blocks() {
+ void (^block)() = ^{
+ int x = 0;
+ switch (x) {
+ case 0:
+ x++;
+ [[clang::fallthrough]]; // no diagnostics
+ case 1:
+ x++;
+ default: // \
+ expected-warning{{unannotated fall-through between switch labels}} \
+ expected-note{{insert 'break;' to avoid fall-through}}
+ break;
+ }
+ };
+ block();
+}
diff --git a/test/SemaCXX/switch-implicit-fallthrough.cpp b/test/SemaCXX/switch-implicit-fallthrough.cpp
index d7959238c6b36..0bc43cdbd45b2 100644
--- a/test/SemaCXX/switch-implicit-fallthrough.cpp
+++ b/test/SemaCXX/switch-implicit-fallthrough.cpp
@@ -229,6 +229,59 @@ int fallthrough_covered_enums(Enum e) {
return n;
}
+// Fallthrough annotations in local classes used to generate "fallthrough
+// annotation does not directly precede switch label" warning.
+void fallthrough_in_local_class() {
+ class C {
+ void f(int x) {
+ switch (x) {
+ case 0:
+ x++;
+ [[clang::fallthrough]]; // no diagnostics
+ case 1:
+ x++;
+ default: // \
+ expected-warning{{unannotated fall-through between switch labels}} \
+ expected-note{{insert 'break;' to avoid fall-through}}
+ break;
+ }
+ }
+ };
+}
+
+// Fallthrough annotations in lambdas used to generate "fallthrough
+// annotation does not directly precede switch label" warning.
+void fallthrough_in_lambda() {
+ (void)[] {
+ int x = 0;
+ switch (x) {
+ case 0:
+ x++;
+ [[clang::fallthrough]]; // no diagnostics
+ case 1:
+ x++;
+ default: // \
+ expected-warning{{unannotated fall-through between switch labels}} \
+ expected-note{{insert 'break;' to avoid fall-through}}
+ break;
+ }
+ };
+}
+
+namespace PR18983 {
+ void fatal() __attribute__((noreturn));
+ int num();
+ void test() {
+ switch (num()) {
+ case 1:
+ fatal();
+ // Don't issue a warning.
+ case 2:
+ break;
+ }
+ }
+}
+
int fallthrough_targets(int n) {
[[clang::fallthrough]]; // expected-error{{fallthrough annotation is outside switch statement}}
@@ -247,21 +300,3 @@ int fallthrough_targets(int n) {
}
return n;
}
-
-// Fallthrough annotations in local classes used to generate "fallthrough
-// annotation does not directly precede switch label" warning.
-void fallthrough_in_local_class() {
- class C {
- void f(int x) {
- switch (x) {
- case 0:
- x++;
- [[clang::fallthrough]]; // no diagnostics
- case 1:
- x++;
- break;
- }
- }
- };
-}
-
diff --git a/test/SemaCXX/template-implicit-vars.cpp b/test/SemaCXX/template-implicit-vars.cpp
new file mode 100644
index 0000000000000..25d35fbdb84f5
--- /dev/null
+++ b/test/SemaCXX/template-implicit-vars.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -ast-dump | FileCheck %s
+template<typename T>
+void f(T t) {
+ T a[] = {t};
+ for (auto x : a) {}
+}
+
+void g() {
+ f(1);
+}
+// CHECK: VarDecl {{.*}} implicit used __range
+// CHECK: VarDecl {{.*}} implicit used __range
+// CHECK: VarDecl {{.*}} implicit used __begin
+// CHECK: VarDecl {{.*}} implicit used __end
diff --git a/test/SemaCXX/trailing-return-0x.cpp b/test/SemaCXX/trailing-return-0x.cpp
index f7e3433a76086..cf5e659660eb0 100644
--- a/test/SemaCXX/trailing-return-0x.cpp
+++ b/test/SemaCXX/trailing-return-0x.cpp
@@ -17,7 +17,9 @@ auto f() -> int
return 0;
}
-auto g(); // expected-error{{return without trailing return type}}
+auto g(); // expected-error{{return without trailing return type; deduced return types are a C++1y extension}}
+decltype(auto) g2(); // expected-warning{{extension}} expected-error-re{{{{^}}deduced return types are a C++1y extension}}
+auto badness = g2();
int h() -> int; // expected-error{{trailing return type must specify return type 'auto', not 'int'}}
diff --git a/test/SemaCXX/type-definition-in-specifier.cpp b/test/SemaCXX/type-definition-in-specifier.cpp
index a614e6c2812ec..43443a00e44ba 100644
--- a/test/SemaCXX/type-definition-in-specifier.cpp
+++ b/test/SemaCXX/type-definition-in-specifier.cpp
@@ -13,13 +13,54 @@ struct S0 { int x; };
void f0() {
typedef struct S1 { int x; } S1_typedef;
- (void)((struct S2 { int x; }*)0); // expected-error{{can not be defined}}
+ (void)((struct S2 { int x; }*)0); // expected-error{{cannot be defined}}
struct S3 { int x; } s3;
- (void)static_cast<struct S4 { int x; } *>(0); // expected-error{{can not be defined}}
+ (void)static_cast<struct S4 { int x; } *>(0); // expected-error{{cannot be defined}}
}
struct S5 { int x; } f1() { return S5(); } // expected-error{{result type}}
void f2(struct S6 { int x; } p); // expected-error{{parameter type}}
+
+struct pr19018 {
+ short foo6 (enum bar0 {qq} bar3); // expected-error{{cannot be defined in a parameter type}}
+};
+
+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'}}
+
+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}}
+void pr19018_4 (struct {int qq;} x); // expected-error{{cannot be defined in a parameter type}}
+void pr19018_5 (struct { void qq(); } x); // expected-error{{cannot be defined in a parameter type}}
+void pr19018_5 (struct s19018_2 { void qq(); } x); // expected-error{{cannot be defined in a parameter type}}
+
+struct pr19018a {
+ static int xx;
+ void func1(enum t19018 {qq} x); // expected-error{{cannot be defined in a parameter type}}
+ void func2(enum t19018 {qq} x); // expected-error{{cannot be defined in a parameter type}}
+ void func3(enum {qq} x); // expected-error{{cannot be defined in a parameter type}}
+ void func4(struct t19018 {int qq;} x); // expected-error{{cannot be defined in a parameter type}}
+ void func5(struct {int qq;} x); // expected-error{{cannot be defined in a parameter type}}
+ void func6(struct { void qq(); } x); // expected-error{{cannot be defined in a parameter type}}
+ void func7(struct t19018 { void qq(); } x); // expected-error{{cannot be defined in a parameter type}}
+ void func8(struct { int qq() { return xx; }; } x); // expected-error{{cannot be defined in a parameter type}}
+ void func9(struct t19018 { int qq() { return xx; }; } x); // expected-error{{cannot be defined in a parameter type}}
+};
+
+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'}}
+ 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'}}
+};
+
+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'}}
+};
diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp
index 3e479215838e4..3b94ef0951ebf 100644
--- a/test/SemaCXX/type-traits.cpp
+++ b/test/SemaCXX/type-traits.cpp
@@ -112,6 +112,14 @@ struct HasNoThrowConstructor { HasNoThrowConstructor() throw(); };
struct HasNoThrowConstructorWithArgs {
HasNoThrowConstructorWithArgs(HasCons i = HasCons(0)) throw();
};
+struct HasMultipleDefaultConstructor1 {
+ HasMultipleDefaultConstructor1() throw();
+ HasMultipleDefaultConstructor1(int i = 0);
+};
+struct HasMultipleDefaultConstructor2 {
+ HasMultipleDefaultConstructor2(int i = 0);
+ HasMultipleDefaultConstructor2() throw();
+};
struct HasNoThrowCopy { HasNoThrowCopy(const HasNoThrowCopy&) throw(); };
struct HasMultipleCopy {
@@ -1475,6 +1483,10 @@ void has_nothrow_move_assign() {
{ int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToUDCopyCtor))]; }
{ int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToUDCopyAssign))]; }
{ int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToDtor))]; }
+
+
+ { int arr[T(__is_nothrow_assignable(HasNoThrowMoveAssign, HasNoThrowMoveAssign))]; }
+ { int arr[F(__is_nothrow_assignable(HasThrowMoveAssign, HasThrowMoveAssign))]; }
}
void has_trivial_move_assign() {
@@ -1562,6 +1574,9 @@ void has_nothrow_constructor() {
{ int arr[F(__has_nothrow_constructor(void))]; }
{ int arr[F(__has_nothrow_constructor(cvoid))]; }
{ int arr[F(__has_nothrow_constructor(HasTemplateCons))]; }
+
+ { int arr[F(__has_nothrow_constructor(HasMultipleDefaultConstructor1))]; }
+ { int arr[F(__has_nothrow_constructor(HasMultipleDefaultConstructor2))]; }
}
void has_virtual_destructor() {
@@ -1931,6 +1946,30 @@ void trivial_checks()
TrivialMoveButNotCopy&&)))]; }
}
+void constructible_checks() {
+ { int arr[T(__is_constructible(HasNoThrowConstructorWithArgs))]; }
+ { int arr[F(__is_nothrow_constructible(HasNoThrowConstructorWithArgs))]; } // MSVC doesn't look into default args and gets this wrong.
+
+ { int arr[T(__is_constructible(HasNoThrowConstructorWithArgs, HasCons))]; }
+ { int arr[T(__is_nothrow_constructible(HasNoThrowConstructorWithArgs, HasCons))]; }
+
+ { int arr[T(__is_constructible(NonTrivialDefault))]; }
+ { int arr[F(__is_nothrow_constructible(NonTrivialDefault))]; }
+
+ { int arr[T(__is_constructible(int))]; }
+ { int arr[T(__is_nothrow_constructible(int))]; }
+
+ { int arr[F(__is_constructible(NonPOD))]; }
+ { int arr[F(__is_nothrow_constructible(NonPOD))]; }
+
+ { int arr[T(__is_constructible(NonPOD, int))]; }
+ { int arr[F(__is_nothrow_constructible(NonPOD, int))]; }
+
+ // PR19178
+ { int arr[F(__is_constructible(Abstract))]; }
+ { int arr[F(__is_nothrow_constructible(Abstract))]; }
+}
+
// Instantiation of __is_trivially_constructible
template<typename T, typename ...Args>
struct is_trivially_constructible {
@@ -1956,6 +1995,7 @@ void is_trivially_constructible_test() {
{ int arr[F((is_trivially_constructible<int, int*>::value))]; }
{ int arr[F((is_trivially_constructible<NonTrivialDefault>::value))]; }
{ int arr[F((is_trivially_constructible<ThreeArgCtor, int*, char*, int&>::value))]; }
+ { int arr[F((is_trivially_constructible<Abstract>::value))]; } // PR19178
}
void array_rank() {
diff --git a/test/SemaCXX/typeid-ref.cpp b/test/SemaCXX/typeid-ref.cpp
index d01fd316854c3..7e5dbdd85adeb 100644
--- a/test/SemaCXX/typeid-ref.cpp
+++ b/test/SemaCXX/typeid-ref.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
namespace std {
class type_info;
}
@@ -7,6 +7,6 @@ struct X { };
void f() {
// CHECK: @_ZTS1X = linkonce_odr constant
- // CHECK: @_ZTI1X = linkonce_odr unnamed_addr constant
+ // CHECK: @_ZTI1X = linkonce_odr constant
(void)typeid(X&);
}
diff --git a/test/SemaCXX/types_compatible_p.cpp b/test/SemaCXX/types_compatible_p.cpp
index 4aa9a1cfa939b..29e06405adeae 100644
--- a/test/SemaCXX/types_compatible_p.cpp
+++ b/test/SemaCXX/types_compatible_p.cpp
@@ -1,5 +1,9 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -x c++ %s
+// RUN: %clang_cc1 -fsyntax-only -x c %s
-bool f() {
- return __builtin_types_compatible_p(int, const int); // expected-error{{C++}}
+// Test that GNU C extension __builtin_types_compatible_p() is not available in C++ mode.
+
+int f() {
+ return __builtin_types_compatible_p(int, const int); // expected-error{{expected '(' for function-style cast or type construction}} \
+ // expected-error{{expected expression}}
}
diff --git a/test/SemaCXX/typo-correction-pt2.cpp b/test/SemaCXX/typo-correction-pt2.cpp
index 525d11b0a67b9..88a7073f99468 100644
--- a/test/SemaCXX/typo-correction-pt2.cpp
+++ b/test/SemaCXX/typo-correction-pt2.cpp
@@ -5,10 +5,19 @@
// attempt within a single file (which is to avoid having very broken files take
// minutes to finally be rejected by the parser).
+namespace PR12951 {
+// If there are two corrections that have the same identifier and edit distance
+// and only differ by their namespaces, don't suggest either as a correction
+// since both are equally likely corrections.
+namespace foobar { struct Thing {}; }
+namespace bazquux { struct Thing {}; }
+void f() { Thing t; } // expected-error{{unknown type name 'Thing'}}
+}
+
namespace bogus_keyword_suggestion {
void test() {
- status = "OK"; // expected-error-re {{use of undeclared identifier 'status'$}}
- return status; // expected-error-re {{use of undeclared identifier 'status'$}}
+ status = "OK"; // expected-error-re {{use of undeclared identifier 'status'{{$}}}}
+ return status; // expected-error-re {{use of undeclared identifier 'status'{{$}}}}
}
}
@@ -33,7 +42,7 @@ struct T {
};
// should be void T::f();
void f() {
- data_struct->foo(); // expected-error-re{{use of undeclared identifier 'data_struct'$}}
+ data_struct->foo(); // expected-error-re{{use of undeclared identifier 'data_struct'{{$}}}}
}
namespace PR12287 {
@@ -116,9 +125,9 @@ public:
void testAccess() {
Figure obj;
switch (obj.type()) { // expected-warning {{enumeration values 'SQUARE', 'TRIANGLE', and 'CIRCLE' not handled in switch}}
- case SQUARE: // expected-error-re {{use of undeclared identifier 'SQUARE'$}}
- case TRIANGLE: // expected-error-re {{use of undeclared identifier 'TRIANGLE'$}}
- case CIRCE: // expected-error-re {{use of undeclared identifier 'CIRCE'$}}
+ case SQUARE: // expected-error-re {{use of undeclared identifier 'SQUARE'{{$}}}}
+ case TRIANGLE: // expected-error-re {{use of undeclared identifier 'TRIANGLE'{{$}}}}
+ case CIRCE: // expected-error-re {{use of undeclared identifier 'CIRCE'{{$}}}}
break;
}
}
@@ -126,13 +135,13 @@ void testAccess() {
long readline(const char *, char *, unsigned long);
void assign_to_unknown_var() {
- deadline_ = 1; // expected-error-re {{use of undeclared identifier 'deadline_'$}}
+ deadline_ = 1; // expected-error-re {{use of undeclared identifier 'deadline_'{{$}}}}
}
namespace no_ns_before_dot {
namespace re2 {}
void test() {
- req.set_check(false); // expected-error-re {{use of undeclared identifier 'req'$}}
+ req.set_check(false); // expected-error-re {{use of undeclared identifier 'req'{{$}}}}
}
}
@@ -199,3 +208,95 @@ template <>
PR18213::WrapperInfo ::PR18213::Wrappable<int>::kWrapperInfo = { 0 }; // expected-error {{no member named 'PR18213' in 'PR18213::WrapperInfo'; did you mean simply 'PR18213'?}} \
// expected-error {{C++ requires a type specifier for all declarations}}
}
+
+namespace PR18651 {
+struct {
+ int x;
+} a, b;
+
+int y = x; // expected-error-re {{use of undeclared identifier 'x'{{$}}}}
+}
+
+namespace PR18685 {
+template <class C, int I, int J>
+class SetVector {
+ public:
+ SetVector() {}
+};
+
+template <class C, int I>
+class SmallSetVector : public SetVector<C, I, 8> {};
+
+class foo {};
+SmallSetVector<foo*, 2> fooSet;
+}
+
+PR18685::BitVector Map; // expected-error-re {{no type named 'BitVector' in namespace 'PR18685'{{$}}}}
+
+namespace shadowed_template {
+template <typename T> class Fizbin {}; // expected-note {{'::shadowed_template::Fizbin' declared here}}
+class Baz {
+ int Fizbin();
+ // TODO: Teach the parser to recover from the typo correction instead of
+ // continuing to treat the template name as an implicit-int declaration.
+ Fizbin<int> qux; // expected-error {{unknown type name 'Fizbin'; did you mean '::shadowed_template::Fizbin'?}} \
+ // expected-error {{expected member name or ';' after declaration specifiers}}
+};
+}
+
+namespace PR18852 {
+void func() {
+ struct foo {
+ void bar() {}
+ };
+ bar(); // expected-error-re {{use of undeclared identifier 'bar'{{$}}}}
+}
+
+class Thread {
+ public:
+ void Start();
+ static void Stop(); // expected-note {{'Thread::Stop' declared here}}
+};
+
+class Manager {
+ public:
+ void Start(int); // expected-note {{'Start' declared here}}
+ void Stop(int); // expected-note {{'Stop' declared here}}
+};
+
+void test(Manager *m) {
+ // Don't suggest Thread::Start as a correction just because it has the same
+ // (unqualified) name and accepts the right number of args; this is a method
+ // call on an object in an unrelated class.
+ m->Start(); // expected-error-re {{too few arguments to function call, expected 1, have 0{{$}}}}
+ m->Stop(); // expected-error-re {{too few arguments to function call, expected 1, have 0{{$}}}}
+ Stop(); // expected-error {{use of undeclared identifier 'Stop'; did you mean 'Thread::Stop'?}}
+}
+
+}
+
+namespace std {
+class bernoulli_distribution {
+ public:
+ double p() const;
+};
+}
+void test() {
+ // Make sure that typo correction doesn't suggest changing 'p' to
+ // 'std::bernoulli_distribution::p' as that is most likely wrong.
+ if (p) // expected-error-re {{use of undeclared identifier 'p'{{$}}}}
+ return;
+}
+
+namespace PR19681 {
+ struct TypoA {};
+ struct TypoB {
+ void test();
+ private:
+ template<typename T> void private_memfn(T); // expected-note{{declared here}}
+ };
+ void TypoB::test() {
+ // FIXME: should suggest 'PR19681::TypoB::private_memfn' instead of '::PR19681::TypoB::private_memfn'
+ (void)static_cast<void(TypoB::*)(int)>(&TypoA::private_memfn); // expected-error{{no member named 'private_memfn' in 'PR19681::TypoA'; did you mean '::PR19681::TypoB::private_memfn'?}}
+ }
+}
diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp
index 4047e6a18cee2..e8160b066de42 100644
--- a/test/SemaCXX/typo-correction.cpp
+++ b/test/SemaCXX/typo-correction.cpp
@@ -202,15 +202,6 @@ namespace ImplicitInt {
};
}
-namespace PR12951 {
-// If there are two corrections that have the same identifier and edit distance
-// and only differ by their namespaces, don't suggest either as a correction
-// since both are equally likely corrections.
-namespace foobar { struct Thing {}; }
-namespace bazquux { struct Thing {}; }
-void f() { Thing t; } // expected-error{{unknown type name 'Thing'}}
-}
-
namespace PR13051 {
template<typename T> struct S {
template<typename U> void f();
@@ -282,13 +273,13 @@ namespace b6956809_test1 {
namespace b6956809_test2 {
template<typename T> struct Err { typename T::error n; }; // expected-error{{type 'void *' cannot be used prior to '::' because it has no members}}
struct S {
- template<typename T> typename Err<T>::type method(T); // expected-note{{in instantiation of template class 'b6956809_test2::Err<void *>' requested here}} expected-note{{while substituting deduced template arguments into function template 'method' [with T = void *]}}
+ template<typename T> typename Err<T>::type method(T); // expected-note{{in instantiation of template class 'b6956809_test2::Err<void *>' requested here}}
template<typename T> int method(T *);
};
void test() {
S s;
- int k = s.methodd((void*)0); // expected-error{{no member named 'methodd' in 'b6956809_test2::S'; did you mean 'method'?}}
+ int k = s.methodd((void*)0); // expected-error{{no member named 'methodd' in 'b6956809_test2::S'; did you mean 'method'?}} expected-note{{while substituting deduced template arguments into function template 'method' [with T = void *]}}
}
}
@@ -299,6 +290,6 @@ namespace CorrectTypo_has_reached_its_limit {
int flibberdy(); // expected-note{{'flibberdy' declared here}}
int no_correction() {
return hibberdy() + // expected-error{{use of undeclared identifier 'hibberdy'; did you mean 'flibberdy'?}}
- gibberdy(); // expected-error-re{{use of undeclared identifier 'gibberdy'$}}
+ gibberdy(); // expected-error-re{{use of undeclared identifier 'gibberdy'{{$}}}}
};
}
diff --git a/test/SemaCXX/undefined-inline.cpp b/test/SemaCXX/undefined-inline.cpp
index ad719ae03abb6..18973ef8b79c8 100644
--- a/test/SemaCXX/undefined-inline.cpp
+++ b/test/SemaCXX/undefined-inline.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple i686-pc-win32 -verify %s
// PR14993
namespace test1 {
@@ -55,3 +55,9 @@ namespace test10 {
void test() { foo(); }
inline void foo() __attribute__((gnu_inline));
}
+
+namespace test11 {
+ inline void foo() __attribute__((dllexport));
+ inline void bar() __attribute__((dllimport));
+ void test() { foo(); bar(); }
+}
diff --git a/test/SemaCXX/undefined-internal.cpp b/test/SemaCXX/undefined-internal.cpp
index 1b76a86dcb5ac..f32036a025f4c 100644
--- a/test/SemaCXX/undefined-internal.cpp
+++ b/test/SemaCXX/undefined-internal.cpp
@@ -15,9 +15,9 @@ namespace test1 {
namespace test2 {
namespace {
- void foo(); // expected-warning {{function 'test2::<anonymous namespace>::foo' has internal linkage but is not defined}}
- extern int var; // expected-warning {{variable 'test2::<anonymous namespace>::var' has internal linkage but is not defined}}
- template <class T> void bar(); // expected-warning {{function 'test2::<anonymous namespace>::bar<int>' has internal linkage but is not defined}}
+ void foo(); // expected-warning {{function 'test2::(anonymous namespace)::foo' has internal linkage but is not defined}}
+ extern int var; // expected-warning {{variable 'test2::(anonymous namespace)::var' has internal linkage but is not defined}}
+ template <class T> void bar(); // expected-warning {{function 'test2::(anonymous namespace)::bar<int>' has internal linkage but is not defined}}
}
void test() {
foo(); // expected-note {{used here}}
@@ -49,11 +49,11 @@ namespace test3 {
namespace test4 {
namespace {
struct A {
- A(); // expected-warning {{function 'test4::<anonymous namespace>::A::A' has internal linkage but is not defined}}
- ~A();// expected-warning {{function 'test4::<anonymous namespace>::A::~A' has internal linkage but is not defined}}
- virtual void foo(); // expected-warning {{function 'test4::<anonymous namespace>::A::foo' has internal linkage but is not defined}}
+ A(); // expected-warning {{function 'test4::(anonymous namespace)::A::A' has internal linkage but is not defined}}
+ ~A();// expected-warning {{function 'test4::(anonymous namespace)::A::~A' has internal linkage but is not defined}}
+ virtual void foo(); // expected-warning {{function 'test4::(anonymous namespace)::A::foo' has internal linkage but is not defined}}
virtual void bar() = 0;
- virtual void baz(); // expected-warning {{function 'test4::<anonymous namespace>::A::baz' has internal linkage but is not defined}}
+ virtual void baz(); // expected-warning {{function 'test4::(anonymous namespace)::A::baz' has internal linkage but is not defined}}
};
}
@@ -75,8 +75,8 @@ namespace test5 {
}
template <class N> struct B {
- static int var; // expected-warning {{variable 'test5::B<test5::<anonymous>::A>::var' has internal linkage but is not defined}}
- static void foo(); // expected-warning {{function 'test5::B<test5::<anonymous>::A>::foo' has internal linkage but is not defined}}
+ static int var; // expected-warning {{variable 'test5::B<test5::(anonymous namespace)::A>::var' has internal linkage but is not defined}}
+ static void foo(); // expected-warning {{function 'test5::B<test5::(anonymous namespace)::A>::foo' has internal linkage but is not defined}}
};
void test() {
@@ -175,7 +175,7 @@ namespace cxx11_odr_rules {
namespace OverloadUse {
namespace {
void f();
- void f(int); // expected-warning {{function 'OverloadUse::<anonymous namespace>::f' has internal linkage but is not defined}}
+ void f(int); // expected-warning {{function 'OverloadUse::(anonymous namespace)::f' has internal linkage but is not defined}}
}
template<void x()> void t(int*) { x(); }
template<void x(int)> void t(long*) { x(10); } // expected-note {{used here}}
@@ -193,7 +193,7 @@ namespace test7 {
namespace test8 {
typedef struct {
- void bar(); // expected-warning {{function 'test8::<anonymous struct>::bar' has internal linkage but is not defined}}
+ void bar(); // expected-warning {{function 'test8::(anonymous struct)::bar' has internal linkage but is not defined}}
void foo() {
bar(); // expected-note {{used here}}
}
@@ -204,7 +204,7 @@ namespace test9 {
namespace {
struct X {
virtual void notused() = 0;
- virtual void used() = 0; // expected-warning {{function 'test9::<anonymous namespace>::X::used' has internal linkage but is not defined}}
+ virtual void used() = 0; // expected-warning {{function 'test9::(anonymous namespace)::X::used' has internal linkage but is not defined}}
};
}
void test(X &x) {
@@ -217,7 +217,7 @@ namespace test10 {
namespace {
struct X {
virtual void notused() = 0;
- virtual void used() = 0; // expected-warning {{function 'test10::<anonymous namespace>::X::used' has internal linkage but is not defined}}
+ virtual void used() = 0; // expected-warning {{function 'test10::(anonymous namespace)::X::used' has internal linkage but is not defined}}
void test() {
notused();
@@ -244,11 +244,11 @@ namespace test11 {
};
struct B {
- bool operator()() const; // expected-warning {{function 'test11::<anonymous namespace>::B::operator()' has internal linkage but is not defined}}
- void operator!() const; // expected-warning {{function 'test11::<anonymous namespace>::B::operator!' has internal linkage but is not defined}}
- bool operator+(const B&) const; // expected-warning {{function 'test11::<anonymous namespace>::B::operator+' has internal linkage but is not defined}}
- int operator[](int) const; // expected-warning {{function 'test11::<anonymous namespace>::B::operator[]' has internal linkage but is not defined}}
- const B* operator->() const; // expected-warning {{function 'test11::<anonymous namespace>::B::operator->' has internal linkage but is not defined}}
+ bool operator()() const; // expected-warning {{function 'test11::(anonymous namespace)::B::operator()' has internal linkage but is not defined}}
+ void operator!() const; // expected-warning {{function 'test11::(anonymous namespace)::B::operator!' has internal linkage but is not defined}}
+ bool operator+(const B&) const; // expected-warning {{function 'test11::(anonymous namespace)::B::operator+' has internal linkage but is not defined}}
+ int operator[](int) const; // expected-warning {{function 'test11::(anonymous namespace)::B::operator[]' has internal linkage but is not defined}}
+ const B* operator->() const; // expected-warning {{function 'test11::(anonymous namespace)::B::operator->' has internal linkage but is not defined}}
int member;
};
}
@@ -278,18 +278,18 @@ namespace test12 {
struct Cls {
virtual void f(int) = 0;
virtual void f(int, double) = 0;
- void g(int); // expected-warning {{function 'test12::<anonymous namespace>::Cls::g' has internal linkage but is not defined}}
+ void g(int); // expected-warning {{function 'test12::(anonymous namespace)::Cls::g' has internal linkage but is not defined}}
void g(int, double);
virtual operator T1() = 0;
virtual operator T2() = 0;
virtual operator T3&() = 0;
- operator T4(); // expected-warning {{function 'test12::<anonymous namespace>::Cls::operator T4' has internal linkage but is not defined}}
- operator T5(); // expected-warning {{function 'test12::<anonymous namespace>::Cls::operator T5' has internal linkage but is not defined}}
- operator T6&(); // expected-warning {{function 'test12::<anonymous namespace>::Cls::operator class test12::T6 &' has internal linkage but is not defined}}
+ operator T4(); // expected-warning {{function 'test12::(anonymous namespace)::Cls::operator T4' has internal linkage but is not defined}}
+ operator T5(); // expected-warning {{function 'test12::(anonymous namespace)::Cls::operator T5' has internal linkage but is not defined}}
+ operator T6&(); // expected-warning {{function 'test12::(anonymous namespace)::Cls::operator test12::T6 &' has internal linkage but is not defined}}
};
struct Cls2 {
- Cls2(T7); // expected-warning {{function 'test12::<anonymous namespace>::Cls2::Cls2' has internal linkage but is not defined}}
+ Cls2(T7); // expected-warning {{function 'test12::(anonymous namespace)::Cls2::Cls2' has internal linkage but is not defined}}
};
}
diff --git a/test/SemaCXX/underlying_type.cpp b/test/SemaCXX/underlying_type.cpp
index 7bca06bf074e5..2a972b174e86f 100644
--- a/test/SemaCXX/underlying_type.cpp
+++ b/test/SemaCXX/underlying_type.cpp
@@ -41,3 +41,17 @@ enum class foo : uint { bar };
static_assert(is_same_type<underlying_type<foo>::type, unsigned>::value,
"foo has the wrong underlying type");
+
+namespace PR19966 {
+ void PR19966(enum Invalid) { // expected-note 2{{forward declaration of}}
+ // expected-error@-1 {{ISO C++ forbids forward references to 'enum'}}
+ // expected-error@-2 {{variable has incomplete type}}
+ __underlying_type(Invalid) dont_crash;
+ // expected-error@-1 {{cannot determine underlying type of incomplete enumeration type 'PR19966::Invalid'}}
+ }
+ enum E { // expected-note {{forward declaration of 'E'}}
+ a = (__underlying_type(E)){}
+ // expected-error@-1 {{cannot determine underlying type of incomplete enumeration type 'PR19966::E'}}
+ // expected-error@-2 {{constant expression}}
+ };
+}
diff --git a/test/SemaCXX/uninit-variables.cpp b/test/SemaCXX/uninit-variables.cpp
index 687bfd2638d4f..4dcd34858abbf 100644
--- a/test/SemaCXX/uninit-variables.cpp
+++ b/test/SemaCXX/uninit-variables.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -fsyntax-only -fcxx-exceptions %s -verify
+// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -fsyntax-only -fcxx-exceptions %s -verify -std=c++1y
// Stub out types for 'typeid' to work.
namespace std { class type_info {}; }
@@ -147,3 +147,6 @@ int test_const_ref() {
consume_const_ref(n);
return n; // expected-warning {{uninitialized when used here}}
}
+
+// Don't crash here.
+auto PR19996 = [a=0]{int t; return a;};
diff --git a/test/SemaCXX/uninitialized.cpp b/test/SemaCXX/uninitialized.cpp
index 4991ebee8b311..677a141f3ec35 100644
--- a/test/SemaCXX/uninitialized.cpp
+++ b/test/SemaCXX/uninitialized.cpp
@@ -117,7 +117,7 @@ void setupA(bool x) {
A a20{a20}; // expected-warning {{variable 'a20' is uninitialized when used within its own initialization}}
A a21 = {a21}; // expected-warning {{variable 'a21' is uninitialized when used within its own initialization}}
- // FIXME: Make the local uninitialized warning consistant with the global
+ // FIXME: Make the local uninitialized warning consistent with the global
// uninitialized checking.
A *a22 = new A(a22->count); // expected-warning {{variable 'a22' is uninitialized when used within its own initialization}}
A *a23 = new A(a23->ONE); // expected-warning {{variable 'a23' is uninitialized when used within its own initialization}}
diff --git a/test/SemaCXX/unreachable-code.cpp b/test/SemaCXX/unreachable-code.cpp
index 743290e1b9e55..fd006c099e7dc 100644
--- a/test/SemaCXX/unreachable-code.cpp
+++ b/test/SemaCXX/unreachable-code.cpp
@@ -1,17 +1,29 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -Wunreachable-code -fblocks -verify %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -Wunreachable-code-aggressive -fblocks -verify %s
int j;
-void bar() { }
+int bar();
int test1() {
for (int i = 0;
i != 10;
- ++i) { // expected-warning {{will never be executed}}
+ ++i) { // expected-warning {{loop will run at most once (loop increment never executed)}}
if (j == 23) // missing {}'s
bar();
return 1;
}
return 0;
- return 1; // expected-warning {{will never be executed}}
+ return 1; // expected-warning {{will never be executed}}
+}
+
+int test1_B() {
+ for (int i = 0;
+ i != 10;
+ ++i) { // expected-warning {{loop will run at most once (loop increment never executed)}}
+ if (j == 23) // missing {}'s
+ bar();
+ return 1;
+ }
+ return 0;
+ return bar(); // expected-warning {{will never be executed}}
}
void test2(int i) {
diff --git a/test/SemaCXX/using-decl-1.cpp b/test/SemaCXX/using-decl-1.cpp
index 24d92f175c302..40f80a70ef371 100644
--- a/test/SemaCXX/using-decl-1.cpp
+++ b/test/SemaCXX/using-decl-1.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
extern "C" { void f(bool); }
@@ -160,3 +161,97 @@ namespace M { }
}
using N::M::FFF; // expected-error {{no member named 'FFF' in namespace 'using_suggestion_val_dropped_nested_specifier::N::M'; did you mean 'N::FFF'?}}
}
+
+namespace UsingDeclVsHiddenName {
+ namespace A {
+ enum HiddenTag1 {}; // expected-note {{previous use is here}}
+ enum HiddenTag2 {}; // expected-note {{target}}
+ int HiddenFn1; // expected-note {{target}}
+ int HiddenFn2; // expected-note {{target}}
+ int HiddenLocalExtern1;
+ int HiddenLocalExtern2;
+ }
+
+ namespace B {
+ using A::HiddenTag1;
+ using A::HiddenFn1; // expected-note {{using declaration}}
+ using A::HiddenLocalExtern1;
+
+ struct S {
+ friend struct HiddenTag1; // expected-error {{tag type that does not match previous}}
+ friend struct HiddenTag2; // expected-note {{conflicting declaration}}
+ friend void HiddenFn1(); // expected-error {{cannot befriend target of using declaration}}
+ friend void HiddenFn2(); // expected-note {{conflicting declaration}}
+ void f() {
+ // OK, these are not in the scope of namespace B, even though they're
+ // members of the namespace.
+ void HiddenLocalExtern1();
+ void HiddenLocalExtern2();
+ }
+ };
+
+ using A::HiddenTag2; // expected-error {{conflicts with declaration already in scope}}
+ using A::HiddenFn2; // expected-error {{conflicts with declaration already in scope}}
+ using A::HiddenLocalExtern2;
+ }
+}
+
+namespace PR19171 {
+ struct Z {
+ Z();
+ };
+
+ typedef struct {
+ Z i;
+ } S;
+
+ struct Y : S {
+ using S::S;
+#if __cplusplus < 201103L
+ // expected-error@-2 {{no member named 'S' in 'PR19171::S'}}
+#endif
+ };
+
+ // [namespace.udecl]p3: In a using-declaration used as a member-declaration,
+ // the nested-name-specifier shall name a base class of the class being defined.
+ // If such a using-declaration names a constructor, the nested-name-specifier
+ // shall name a direct base class of the class being defined;
+
+ struct B_blah { };
+ struct C_blah : B_blah { C_blah(int); }; // expected-note 0-1{{declared here}}
+ struct D1 : C_blah {
+ // FIXME: We should be able to correct this in C++11 mode.
+ using B_blah::C_blah; // expected-error-re {{no member named 'C_blah' in 'PR19171::B_blah'{{$}}}}
+ };
+ struct D2 : C_blah {
+ // Somewhat bizarrely, this names the injected-class-name of B_blah within
+ // C_blah, and is valid.
+ using C_blah::B_blah;
+ };
+ struct D3 : C_blah {
+ using C_blah::D_blah;
+#if __cplusplus < 201103L
+ // expected-error-re@-2 {{no member named 'D_blah' in 'PR19171::C_blah'{{$}}}}
+#else
+ // expected-error@-4 {{no member named 'D_blah' in 'PR19171::C_blah'; did you mean 'C_blah'?}}
+#endif
+ };
+#if __cplusplus >= 201103L
+ D3 d3(0); // ok
+#endif
+
+ struct E { };
+ struct EE { int EE; };
+ struct F : E {
+ using E::EE; // expected-error-re {{no member named 'EE' in 'PR19171::E'{{$}}}}
+ };
+}
+
+namespace TypoCorrectTemplateMember {
+ struct A {
+ template<typename T> void foobar(T); // expected-note {{'foobar' declared here}}
+ };
+ struct B : A {
+ using A::goobar; // expected-error {{no member named 'goobar' in 'TypoCorrectTemplateMember::A'; did you mean 'foobar'?}}
+ };
+}
diff --git a/test/SemaCXX/vararg-class.cpp b/test/SemaCXX/vararg-class.cpp
new file mode 100644
index 0000000000000..08f521cbd539b
--- /dev/null
+++ b/test/SemaCXX/vararg-class.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -verify -Wclass-varargs -std=c++98 %s
+// RUN: %clang_cc1 -verify -Wclass-varargs -std=c++11 %s
+
+struct A {};
+struct B { ~B(); };
+class C { char *c_str(); };
+struct D { char *c_str(); };
+struct E { E(); };
+struct F { F(); char *c_str(); };
+
+void v(...);
+void w(const char*, ...) __attribute__((format(printf, 1, 2)));
+
+void test(A a, B b, C c, D d, E e, F f) {
+ v(a); // expected-warning-re {{passing object of class type 'A' through variadic function{{$}}}}
+ v(b); // expected-error-re {{cannot pass object of non-{{POD|trivial}} type 'B' through variadic function; call will abort at runtime}}
+ v(c); // expected-warning {{passing object of class type 'C' through variadic function; did you mean to call '.c_str()'?}}
+ v(d); // expected-warning {{passing object of class type 'D' through variadic function; did you mean to call '.c_str()'?}}
+ v(e);
+ v(f);
+#if __cplusplus < 201103L
+ // expected-error@-3 {{cannot pass object of non-POD type 'E' through variadic function; call will abort at runtime}}
+ // expected-error@-3 {{cannot pass object of non-POD type 'F' through variadic function; call will abort at runtime}}
+#else
+ // expected-warning-re@-6 {{passing object of class type 'E' through variadic function{{$}}}}
+ // expected-warning@-6 {{passing object of class type 'F' through variadic function; did you mean to call '.c_str()'?}}
+#endif
+
+ v(d.c_str());
+ v(f.c_str());
+ v(0);
+ v('x');
+
+ w("%s", a); // expected-warning {{format specifies type 'char *' but the argument has type 'A'}}
+ w("%s", b); // expected-error-re {{cannot pass non-{{POD|trivial}} object of type 'B' to variadic function; expected type from format string was 'char *'}}
+ w("%s", c); // expected-warning {{format specifies type 'char *' but the argument has type 'C'}}
+ w("%s", d); // expected-warning {{format specifies type 'char *' but the argument has type 'D'}}
+ w("%s", e);
+ w("%s", f);
+#if __cplusplus < 201103L
+ // expected-error@-3 {{cannot pass non-POD object of type 'E' to variadic function; expected type from format string was 'char *'}}
+ // expected-error@-3 {{cannot pass non-POD object of type 'F' to variadic function; expected type from format string was 'char *'}}
+ // expected-note@-4 {{did you mean to call the c_str() method?}}
+#else
+ // expected-warning@-7 {{format specifies type 'char *' but the argument has type 'E'}}
+ // expected-warning@-7 {{format specifies type 'char *' but the argument has type 'F'}}
+#endif
+}
diff --git a/test/SemaCXX/vector-casts.cpp b/test/SemaCXX/vector-casts.cpp
index 681a07ea4707d..2ccd5979c7f7b 100644
--- a/test/SemaCXX/vector-casts.cpp
+++ b/test/SemaCXX/vector-casts.cpp
@@ -2,6 +2,7 @@
typedef int __v2si __attribute__((__vector_size__(8)));
typedef short __v4hi __attribute__((__vector_size__(8)));
typedef short __v8hi __attribute__((__vector_size__(16)));
+typedef short __v3hi __attribute__((__ext_vector_type__(3)));
struct S { }; // expected-note 2 {{candidate constructor}}
@@ -22,19 +23,43 @@ void f() {
(void)reinterpret_cast<__v2si>(ll);
(void)(__v2si)(ll);
- (void)reinterpret_cast<S>(v2si); // expected-error {{reinterpret_cast from '__v2si' to 'S' is not allowed}}
- (void)(S)v2si; // expected-error {{no matching conversion for C-style cast from '__v2si' to 'S'}}
- (void)reinterpret_cast<__v2si>(s); // expected-error {{reinterpret_cast from 'S' to '__v2si' is not allowed}}
- (void)(__v2si)s; // expected-error {{cannot convert 'S' to '__v2si' without a conversion operator}}
+ (void)reinterpret_cast<S>(v2si); // expected-error {{reinterpret_cast from '__v2si' (vector of 2 'int' values) to 'S' is not allowed}}
+ (void)(S)v2si; // expected-error {{no matching conversion for C-style cast from '__v2si' (vector of 2 'int' values) to 'S'}}
+ (void)reinterpret_cast<__v2si>(s); // expected-error {{reinterpret_cast from 'S' to '__v2si' (vector of 2 'int' values) is not allowed}}
+ (void)(__v2si)s; // expected-error {{cannot convert 'S' to '__v2si' (vector of 2 'int' values) without a conversion operator}}
- (void)reinterpret_cast<unsigned char>(v2si); // expected-error {{reinterpret_cast from vector '__v2si' to scalar 'unsigned char' of different size}}
- (void)(unsigned char)v2si; // expected-error {{C-style cast from vector '__v2si' to scalar 'unsigned char' of different size}}
- (void)reinterpret_cast<__v2si>(c); // expected-error {{reinterpret_cast from scalar 'unsigned char' to vector '__v2si' of different size}}
+ (void)reinterpret_cast<unsigned char>(v2si); // expected-error {{reinterpret_cast from vector '__v2si' (vector of 2 'int' values) to scalar 'unsigned char' of different size}}
+ (void)(unsigned char)v2si; // expected-error {{C-style cast from vector '__v2si' (vector of 2 'int' values) to scalar 'unsigned char' of different size}}
+ (void)reinterpret_cast<__v2si>(c); // expected-error {{reinterpret_cast from scalar 'unsigned char' to vector '__v2si' (vector of 2 'int' values) of different size}}
- (void)reinterpret_cast<__v8hi>(v4hi); // expected-error {{reinterpret_cast from vector '__v4hi' to vector '__v8hi' of different size}}
- (void)(__v8hi)v4hi; // expected-error {{C-style cast from vector '__v4hi' to vector '__v8hi' of different size}}
- (void)reinterpret_cast<__v4hi>(v8hi); // expected-error {{reinterpret_cast from vector '__v8hi' to vector '__v4hi' of different size}}
- (void)(__v4hi)v8hi; // expected-error {{C-style cast from vector '__v8hi' to vector '__v4hi' of different size}}
+ (void)reinterpret_cast<__v8hi>(v4hi); // expected-error {{reinterpret_cast from vector '__v4hi' (vector of 4 'short' values) to vector '__v8hi' (vector of 8 'short' values) of different size}}
+ (void)(__v8hi)v4hi; // expected-error {{C-style cast from vector '__v4hi' (vector of 4 'short' values) to vector '__v8hi' (vector of 8 'short' values) of different size}}
+ (void)reinterpret_cast<__v4hi>(v8hi); // expected-error {{reinterpret_cast from vector '__v8hi' (vector of 8 'short' values) to vector '__v4hi' (vector of 4 'short' values) of different size}}
+ (void)(__v4hi)v8hi; // expected-error {{C-style cast from vector '__v8hi' (vector of 8 'short' values) to vector '__v4hi' (vector of 4 'short' values) of different size}}
}
+struct testvec {
+ __v2si v;
+ void madd(const testvec& rhs) {
+ v = v + rhs; // expected-error {{can't convert between vector and non-scalar values}}
+ }
+ void madd2(testvec rhs) {
+ v = v + rhs; // expected-error {{can't convert between vector and non-scalar values}}
+ }
+};
+// rdar://15931426
+// Conversions for return values.
+__v4hi threeToFour(__v3hi v) { // expected-note {{not viable}}
+ return v; // expected-error {{cannot initialize return object}}
+}
+__v3hi fourToThree(__v4hi v) { // expected-note {{not viable}}
+ return v; // expected-error {{cannot initialize return object}}
+}
+// Conversions for calls.
+void call3to4(__v4hi v) {
+ (void) threeToFour(v); // expected-error {{no matching function for call}}
+}
+void call4to3(__v3hi v) {
+ (void) fourToThree(v); // expected-error {{no matching function for call}}
+}
diff --git a/test/SemaCXX/vector.cpp b/test/SemaCXX/vector.cpp
index 7957c23e3e240..bcd7fedb4df2c 100644
--- a/test/SemaCXX/vector.cpp
+++ b/test/SemaCXX/vector.cpp
@@ -24,8 +24,8 @@ void f1_test(char16 c16, longlong16 ll16, char16_e c16e, longlong16_e ll16e) {
f1(ll16e); // expected-error{{call to 'f1' is ambiguous}}
}
-void f2(char16_e); // expected-note{{no known conversion from 'longlong16_e' to 'char16_e' for 1st argument}} \
- // expected-note{{candidate function not viable: no known conversion from 'convertible_to<longlong16_e>' to 'char16_e' for 1st argument}}
+void f2(char16_e); // expected-note{{no known conversion from 'longlong16_e' (vector of 2 'long long' values) to 'char16_e' (vector of 16 'char' values) for 1st argument}} \
+ // expected-note{{candidate function not viable: no known conversion from 'convertible_to<longlong16_e>' to 'char16_e' (vector of 16 'char' values) for 1st argument}}
void f2_test(char16 c16, longlong16 ll16, char16_e c16e, longlong16_e ll16e) {
f2(c16);
@@ -85,7 +85,7 @@ void casts(longlong16 ll16, longlong16_e ll16e) {
(void)static_cast<longlong16>(ll16);
(void)static_cast<longlong16_e>(ll16);
(void)static_cast<char16>(ll16e);
- (void)static_cast<char16_e>(ll16e); // expected-error{{static_cast from 'longlong16_e' to 'char16_e' is not allowed}}
+ (void)static_cast<char16_e>(ll16e); // expected-error{{static_cast from 'longlong16_e' (vector of 2 'long long' values) to 'char16_e' (vector of 16 'char' values) is not allowed}}
(void)static_cast<longlong16>(ll16e);
(void)static_cast<longlong16_e>(ll16e);
@@ -194,11 +194,11 @@ typedef float fltx4 __attribute__((__vector_size__(16)));
typedef double dblx2 __attribute__((__vector_size__(16)));
typedef double dblx4 __attribute__((__vector_size__(32)));
-void accept_fltx2(fltx2); // expected-note{{candidate function not viable: no known conversion from 'double' to 'fltx2' for 1st argument}}
+void accept_fltx2(fltx2); // expected-note{{candidate function not viable: no known conversion from 'double' to 'fltx2' (vector of 2 'float' values) for 1st argument}}
void accept_fltx4(fltx4);
void accept_dblx2(dblx2);
void accept_dblx4(dblx4);
-void accept_bool(bool); // expected-note{{candidate function not viable: no known conversion from 'fltx2' to 'bool' for 1st argument}}
+void accept_bool(bool); // expected-note{{candidate function not viable: no known conversion from 'fltx2' (vector of 2 'float' values) to 'bool' for 1st argument}}
void test(fltx2 fltx2_val, fltx4 fltx4_val, dblx2 dblx2_val, dblx4 dblx4_val) {
// Exact matches
diff --git a/test/SemaCXX/virtual-base-used.cpp b/test/SemaCXX/virtual-base-used.cpp
index 04518ce4d47b5..c46cf5a8c9ef7 100644
--- a/test/SemaCXX/virtual-base-used.cpp
+++ b/test/SemaCXX/virtual-base-used.cpp
@@ -1,42 +1,89 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify %s
// PR7800
+// The Microsoft ABI doesn't have the concept of key functions, so we have different
+// expectations about when functions are first required for that case.
+
+#ifdef MSABI
+// expected-note@+2 3 {{declared private here}}
+#endif
class NoDestroy { ~NoDestroy(); }; // expected-note 3 {{declared private here}}
struct A {
virtual ~A();
};
+#ifdef MSABI
+// expected-error@+3 {{field of type 'NoDestroy' has private destructor}}
+#endif
struct B : public virtual A {
NoDestroy x; // expected-error {{field of type 'NoDestroy' has private destructor}}
};
+#ifdef MSABI
+// expected-note@+3 {{implicit default constructor for 'B' first required here}}
+// expected-note@+2 {{implicit destructor for 'B' first required here}}
+#endif
struct D : public virtual B {
virtual void foo();
~D();
};
+#ifdef MSABI
+D d; // expected-note {{implicit default constructor for 'D' first required here}}
+#else
void D::foo() { // expected-note {{implicit destructor for 'B' first required here}}
}
+#endif
+#ifdef MSABI
+// expected-error@+3 {{field of type 'NoDestroy' has private destructor}}
+#endif
struct E : public virtual A {
NoDestroy x; // expected-error {{field of type 'NoDestroy' has private destructor}}
};
+#ifdef MSABI
+// expected-note@+2 {{implicit default constructor for 'E' first required here}}
+#endif
struct F : public E { // expected-note {{implicit destructor for 'E' first required here}}
};
+#ifdef MSABI
+// expected-note@+2 {{implicit default constructor for 'F' first required here}}
+#endif
struct G : public virtual F {
virtual void foo();
~G();
};
+#ifdef MSABI
+G g; // expected-note {{implicit default constructor for 'G' first required here}}
+#else
void G::foo() { // expected-note {{implicit destructor for 'F' first required here}}
}
+#endif
+#ifdef MSABI
+// expected-note@+3 {{'H' declared here}}
+// expected-error@+3 {{field of type 'NoDestroy' has private destructor}}
+#endif
struct H : public virtual A {
NoDestroy x; // expected-error {{field of type 'NoDestroy' has private destructor}}
};
+#ifdef MSABI
+// expected-error@+3 {{implicit default constructor for 'I' must explicitly initialize the base class 'H' which does not have a default constructor}}
+// expected-note@+2 {{implicit destructor for 'H' first required here}}
+#endif
struct I : public virtual H {
~I();
};
+#ifdef MSABI
+// expected-note@+3 {{implicit default constructor for 'H' first required here}}
+// expected-note@+2 {{implicit default constructor for 'I' first required here}}
+#endif
struct J : public I {
virtual void foo();
~J();
};
+#ifdef MSABI
+J j; // expected-note {{implicit default constructor for 'J' first required here}}
+#else
void J::foo() { // expected-note {{implicit destructor for 'H' first required here}}
}
+#endif
diff --git a/test/SemaCXX/virtual-override-x86.cpp b/test/SemaCXX/virtual-override-x86.cpp
index 75d8af3b3ea34..1d9d1fbe53b6b 100644
--- a/test/SemaCXX/virtual-override-x86.cpp
+++ b/test/SemaCXX/virtual-override-x86.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple=i686-pc-unknown -fsyntax-only -verify %s -std=c++11 -cxx-abi microsoft
+// RUN: %clang_cc1 -triple=i686-pc-win32 -fsyntax-only -verify %s -std=c++11
namespace PR14339 {
class A {
diff --git a/test/SemaCXX/virtual-override.cpp b/test/SemaCXX/virtual-override.cpp
index b477438ee9883..e95acabad2b1c 100644
--- a/test/SemaCXX/virtual-override.cpp
+++ b/test/SemaCXX/virtual-override.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -verify %s -std=c++11
namespace T1 {
class A {
diff --git a/test/SemaCXX/vla.cpp b/test/SemaCXX/vla.cpp
index d63b6335f4533..dae6450553aa3 100644
--- a/test/SemaCXX/vla.cpp
+++ b/test/SemaCXX/vla.cpp
@@ -3,3 +3,17 @@
// PR11925
int n;
int (&f())[n]; // expected-error {{function declaration cannot have variably modified type}}
+
+namespace PR18581 {
+ template<typename T> struct pod {};
+ template<typename T> struct error {
+ typename T::error e; // expected-error {{cannot be used prior to '::'}}
+ };
+ struct incomplete; // expected-note {{forward declaration}}
+
+ void f(int n) {
+ pod<int> a[n];
+ error<int> b[n]; // expected-note {{instantiation}}
+ incomplete c[n]; // expected-error {{incomplete}}
+ }
+}
diff --git a/test/SemaCXX/vtordisp-mode.cpp b/test/SemaCXX/vtordisp-mode.cpp
new file mode 100644
index 0000000000000..dc91534d26b7b
--- /dev/null
+++ b/test/SemaCXX/vtordisp-mode.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -std=c++11 -vtordisp-mode=0 -DVTORDISP_MODE=0 %s -verify
+// RUN: %clang_cc1 -triple i686-pc-win32 -std=c++11 -vtordisp-mode=1 -DVTORDISP_MODE=1 %s -verify
+// RUN: %clang_cc1 -triple i686-pc-win32 -std=c++11 -vtordisp-mode=2 -DVTORDISP_MODE=2 %s -verify
+
+// expected-no-diagnostics
+
+struct A {
+ A();
+ virtual void foo();
+};
+
+// At /vd1, there is a vtordisp before A.
+struct B : virtual A {
+ B();
+ virtual void foo();
+ virtual void bar();
+};
+
+// At /vd2, there is a vtordisp before B, but only because it has its own
+// vftable.
+struct C : virtual B {
+ C();
+};
+
+// There are two vfptrs, two vbptrs, and some number of vtordisps.
+static_assert(sizeof(C) == 2 * 4 + 2 * 4 + 4 * VTORDISP_MODE, "size mismatch");
diff --git a/test/SemaCXX/warn-absolute-value-header.cpp b/test/SemaCXX/warn-absolute-value-header.cpp
new file mode 100644
index 0000000000000..925be38ace087
--- /dev/null
+++ b/test/SemaCXX/warn-absolute-value-header.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -verify %s -Wabsolute-value
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only %s -Wabsolute-value -fdiagnostics-parseable-fixits 2>&1 | FileCheck %s
+
+extern "C" {
+ int abs(int);
+ float fabsf(float);
+}
+
+namespace std {
+ int abs(int);
+ float abs(float);
+}
+
+void test(long long ll, double d, int i, float f) {
+ // Suggest including cmath
+ (void)abs(d);
+ // expected-warning@-1{{using integer absolute value function 'abs' when argument is of floating point type}}
+ // expected-note@-2{{use function 'std::abs' instead}}
+ // expected-note@-3{{include the header <cmath> or explicitly provide a declaration for 'std::abs'}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:9-[[@LINE-4]]:12}:"std::abs"
+
+ (void)fabsf(d);
+ // expected-warning@-1{{absolute value function 'fabsf' given an argument of type 'double' but has parameter of type 'float' which may cause truncation of value}}
+ // expected-note@-2{{use function 'std::abs' instead}}
+ // expected-note@-3{{include the header <cmath> or explicitly provide a declaration for 'std::abs'}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:9-[[@LINE-4]]:14}:"std::abs"
+
+ // Suggest including cstdlib
+ (void)abs(ll);
+ // expected-warning@-1{{absolute value function 'abs' given an argument of type 'long long' but has parameter of type 'int' which may cause truncation of value}}
+ // expected-note@-2{{use function 'std::abs' instead}}
+ // expected-note@-3{{include the header <cstdlib> or explicitly provide a declaration for 'std::abs'}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:9-[[@LINE-4]]:12}:"std::abs"
+ (void)fabsf(ll);
+ // expected-warning@-1{{using floating point absolute value function 'fabsf' when argument is of integer type}}
+ // expected-note@-2{{use function 'std::abs' instead}}
+ // expected-note@-3{{include the header <cstdlib> or explicitly provide a declaration for 'std::abs'}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:9-[[@LINE-4]]:14}:"std::abs"
+
+ // Proper function already called, no warnings.
+ (void)abs(i);
+ (void)fabsf(f);
+
+ // Declarations found, suggest name change.
+ (void)fabsf(i);
+ // expected-warning@-1{{using floating point absolute value function 'fabsf' when argument is of integer type}}
+ // expected-note@-2{{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+ (void)abs(f);
+ // expected-warning@-1{{using integer absolute value function 'abs' when argument is of floating point type}}
+ // expected-note@-2{{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"std::abs"
+}
diff --git a/test/SemaCXX/warn-absolute-value.cpp b/test/SemaCXX/warn-absolute-value.cpp
new file mode 100644
index 0000000000000..8a8a6fd67d343
--- /dev/null
+++ b/test/SemaCXX/warn-absolute-value.cpp
@@ -0,0 +1,823 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -verify %s -Wabsolute-value -std=c++11
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only %s -Wabsolute-value -fdiagnostics-parseable-fixits -std=c++11 2>&1 | FileCheck %s
+
+extern "C" {
+int abs(int);
+long int labs(long int);
+long long int llabs(long long int);
+
+float fabsf(float);
+double fabs(double);
+long double fabsl(long double);
+
+float cabsf(float _Complex);
+double cabs(double _Complex);
+long double cabsl(long double _Complex);
+}
+
+namespace std {
+
+inline namespace __1 {
+int abs(int);
+long int abs(long int);
+long long int abs(long long int);
+}
+
+float abs(float);
+double abs(double);
+long double abs(long double);
+
+template <typename T>
+double abs(T);
+
+}
+
+void test_int(int x) {
+ (void)std::abs(x);
+
+ (void)abs(x);
+ (void)labs(x);
+ (void)llabs(x);
+
+ (void)fabsf(x);
+ // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+ (void)fabs(x);
+ // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+ (void)fabsl(x);
+ // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+ (void)cabsf(x);
+ // expected-warning@-1 {{using complex absolute value function 'cabsf' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+ (void)cabs(x);
+ // expected-warning@-1 {{using complex absolute value function 'cabs' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+ (void)cabsl(x);
+ // expected-warning@-1 {{using complex absolute value function 'cabsl' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+ (void)__builtin_abs(x);
+ (void)__builtin_labs(x);
+ (void)__builtin_llabs(x);
+
+ (void)__builtin_fabsf(x);
+ // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+ (void)__builtin_fabs(x);
+ // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+ (void)__builtin_fabsl(x);
+ // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+
+ (void)__builtin_cabsf(x);
+ // expected-warning@-1 {{using complex absolute value function '__builtin_cabsf' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+ (void)__builtin_cabs(x);
+ // expected-warning@-1 {{using complex absolute value function '__builtin_cabs' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+ (void)__builtin_cabsl(x);
+ // expected-warning@-1 {{using complex absolute value function '__builtin_cabsl' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+}
+
+void test_long(long x) {
+ (void)std::abs(x);
+
+ (void)abs(x); // no warning - int and long are same length for this target
+ (void)labs(x);
+ (void)llabs(x);
+
+ (void)fabsf(x);
+ // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+ (void)fabs(x);
+ // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+ (void)fabsl(x);
+ // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+ (void)cabsf(x);
+ // expected-warning@-1 {{using complex absolute value function 'cabsf' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+ (void)cabs(x);
+ // expected-warning@-1 {{using complex absolute value function 'cabs' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+ (void)cabsl(x);
+ // expected-warning@-1 {{using complex absolute value function 'cabsl' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+ (void)__builtin_abs(x); // no warning - int and long are same length for
+ // this target
+ (void)__builtin_labs(x);
+ (void)__builtin_llabs(x);
+
+ (void)__builtin_fabsf(x);
+ // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+ (void)__builtin_fabs(x);
+ // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+ (void)__builtin_fabsl(x);
+ // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+
+ (void)__builtin_cabsf(x);
+ // expected-warning@-1 {{using complex absolute value function '__builtin_cabsf' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+ (void)__builtin_cabs(x);
+ // expected-warning@-1 {{using complex absolute value function '__builtin_cabs' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+ (void)__builtin_cabsl(x);
+ // expected-warning@-1 {{using complex absolute value function '__builtin_cabsl' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+}
+
+void test_long_long(long long x) {
+ (void)std::abs(x);
+
+ (void)abs(x);
+ // expected-warning@-1{{absolute value function 'abs' given an argument of type 'long long' but has parameter of type 'int' which may cause truncation of value}}
+ // expected-note@-2{{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"std::abs"
+ (void)labs(x);
+ // expected-warning@-1{{absolute value function 'labs' given an argument of type 'long long' but has parameter of type 'long' which may cause truncation of value}}
+ // expected-note@-2{{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+ (void)llabs(x);
+
+ (void)fabsf(x);
+ // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+ (void)fabs(x);
+ // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+ (void)fabsl(x);
+ // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+ (void)cabsf(x);
+ // expected-warning@-1 {{using complex absolute value function 'cabsf' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+ (void)cabs(x);
+ // expected-warning@-1 {{using complex absolute value function 'cabs' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+ (void)cabsl(x);
+ // expected-warning@-1 {{using complex absolute value function 'cabsl' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+ (void)__builtin_abs(x);
+ // expected-warning@-1{{absolute value function '__builtin_abs' given an argument of type 'long long' but has parameter of type 'int' which may cause truncation of value}}
+ // expected-note@-2{{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"std::abs"
+ (void)__builtin_labs(x);
+ // expected-warning@-1{{absolute value function '__builtin_labs' given an argument of type 'long long' but has parameter of type 'long' which may cause truncation of value}}
+ // expected-note@-2{{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+ (void)__builtin_llabs(x);
+
+ (void)__builtin_fabsf(x);
+ // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+ (void)__builtin_fabs(x);
+ // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+ (void)__builtin_fabsl(x);
+ // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+
+ (void)__builtin_cabsf(x);
+ // expected-warning@-1 {{using complex absolute value function '__builtin_cabsf' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+ (void)__builtin_cabs(x);
+ // expected-warning@-1 {{using complex absolute value function '__builtin_cabs' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+ (void)__builtin_cabsl(x);
+ // expected-warning@-1 {{using complex absolute value function '__builtin_cabsl' when argument is of integer type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+}
+
+void test_float(float x) {
+ (void)std::abs(x);
+
+ (void)abs(x);
+ // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"std::abs"
+ (void)labs(x);
+ // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+ (void)llabs(x);
+ // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+ (void)fabsf(x);
+ (void)fabs(x);
+ (void)fabsl(x);
+
+ (void)cabsf(x);
+ // expected-warning@-1 {{using complex absolute value function 'cabsf' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+ (void)cabs(x);
+ // expected-warning@-1 {{using complex absolute value function 'cabs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+ (void)cabsl(x);
+ // expected-warning@-1 {{using complex absolute value function 'cabsl' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+ (void)__builtin_abs(x);
+ // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"std::abs"
+ (void)__builtin_labs(x);
+ // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+ (void)__builtin_llabs(x);
+ // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+
+ (void)__builtin_fabsf(x);
+ (void)__builtin_fabs(x);
+ (void)__builtin_fabsl(x);
+
+ (void)__builtin_cabsf(x);
+ // expected-warning@-1 {{using complex absolute value function '__builtin_cabsf' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+ (void)__builtin_cabs(x);
+ // expected-warning@-1 {{using complex absolute value function '__builtin_cabs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+ (void)__builtin_cabsl(x);
+ // expected-warning@-1 {{using complex absolute value function '__builtin_cabsl' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+}
+
+void test_double(double x) {
+ (void)std::abs(x);
+
+ (void)abs(x);
+ // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"std::abs"
+ (void)labs(x);
+ // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+ (void)llabs(x);
+ // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+ (void)fabsf(x);
+ // expected-warning@-1{{absolute value function 'fabsf' given an argument of type 'double' but has parameter of type 'float' which may cause truncation of value}}
+ // expected-note@-2{{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+ (void)fabs(x);
+ (void)fabsl(x);
+
+ (void)cabsf(x);
+ // expected-warning@-1 {{using complex absolute value function 'cabsf' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+ (void)cabs(x);
+ // expected-warning@-1 {{using complex absolute value function 'cabs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+ (void)cabsl(x);
+ // expected-warning@-1 {{using complex absolute value function 'cabsl' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+ (void)__builtin_abs(x);
+ // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"std::abs"
+ (void)__builtin_labs(x);
+ // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+ (void)__builtin_llabs(x);
+ // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+
+ (void)__builtin_fabsf(x);
+ // expected-warning@-1{{absolute value function '__builtin_fabsf' given an argument of type 'double' but has parameter of type 'float' which may cause truncation of value}}
+ // expected-note@-2{{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+ (void)__builtin_fabs(x);
+ (void)__builtin_fabsl(x);
+
+ (void)__builtin_cabsf(x);
+ // expected-warning@-1 {{using complex absolute value function '__builtin_cabsf' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+ (void)__builtin_cabs(x);
+ // expected-warning@-1 {{using complex absolute value function '__builtin_cabs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+ (void)__builtin_cabsl(x);
+ // expected-warning@-1 {{using complex absolute value function '__builtin_cabsl' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+}
+
+void test_long_double(long double x) {
+ (void)std::abs(x);
+
+ (void)abs(x);
+ // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"std::abs"
+ (void)labs(x);
+ // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+ (void)llabs(x);
+ // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+ (void)fabsf(x);
+ // expected-warning@-1{{absolute value function 'fabsf' given an argument of type 'long double' but has parameter of type 'float' which may cause truncation of value}}
+ // expected-note@-2{{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+ (void)fabs(x);
+ // expected-warning@-1{{absolute value function 'fabs' given an argument of type 'long double' but has parameter of type 'double' which may cause truncation of value}}
+ // expected-note@-2{{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+ (void)fabsl(x);
+
+ (void)cabsf(x);
+ // expected-warning@-1 {{using complex absolute value function 'cabsf' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+ (void)cabs(x);
+ // expected-warning@-1 {{using complex absolute value function 'cabs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+ (void)cabsl(x);
+ // expected-warning@-1 {{using complex absolute value function 'cabsl' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+ (void)__builtin_abs(x);
+ // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"std::abs"
+ (void)__builtin_labs(x);
+ // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+ (void)__builtin_llabs(x);
+ // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+
+ (void)__builtin_fabsf(x);
+ // expected-warning@-1{{absolute value function '__builtin_fabsf' given an argument of type 'long double' but has parameter of type 'float' which may cause truncation of value}}
+ // expected-note@-2{{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+ (void)__builtin_fabs(x);
+ // expected-warning@-1{{absolute value function '__builtin_fabs' given an argument of type 'long double' but has parameter of type 'double' which may cause truncation of value}}
+ // expected-note@-2{{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+ (void)__builtin_fabsl(x);
+
+ (void)__builtin_cabsf(x);
+ // expected-warning@-1 {{using complex absolute value function '__builtin_cabsf' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+ (void)__builtin_cabs(x);
+ // expected-warning@-1 {{using complex absolute value function '__builtin_cabs' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+ (void)__builtin_cabsl(x);
+ // expected-warning@-1 {{using complex absolute value function '__builtin_cabsl' when argument is of floating point type}}
+ // expected-note@-2 {{use function 'std::abs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+}
+
+void test_complex_float(_Complex float x) {
+ (void)abs(x);
+ // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of complex type}}
+ // expected-note@-2 {{use function 'cabsf' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"cabsf"
+ (void)labs(x);
+ // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of complex type}}
+ // expected-note@-2 {{use function 'cabsf' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsf"
+ (void)llabs(x);
+ // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of complex type}}
+ // expected-note@-2 {{use function 'cabsf' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsf"
+
+ (void)fabsf(x);
+ // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of complex type}}
+ // expected-note@-2 {{use function 'cabsf' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsf"
+ (void)fabs(x);
+ // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of complex type}}
+ // expected-note@-2 {{use function 'cabsf' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsf"
+ (void)fabsl(x);
+ // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of complex type}}
+ // expected-note@-2 {{use function 'cabsf' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsf"
+
+ (void)cabsf(x);
+ (void)cabs(x);
+ (void)cabsl(x);
+
+ (void)__builtin_abs(x);
+ // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of complex type}}
+ // expected-note@-2 {{use function '__builtin_cabsf' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_cabsf"
+ (void)__builtin_labs(x);
+ // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of complex type}}
+ // expected-note@-2 {{use function '__builtin_cabsf' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsf"
+ (void)__builtin_llabs(x);
+ // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of complex type}}
+ // expected-note@-2 {{use function '__builtin_cabsf' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsf"
+
+ (void)__builtin_fabsf(x);
+ // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of complex type}}
+ // expected-note@-2 {{use function '__builtin_cabsf' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsf"
+ (void)__builtin_fabs(x);
+ // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of complex type}}
+ // expected-note@-2 {{use function '__builtin_cabsf' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsf"
+ (void)__builtin_fabsl(x);
+ // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of complex type}}
+ // expected-note@-2 {{use function '__builtin_cabsf' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsf"
+
+ (void)__builtin_cabsf(x);
+ (void)__builtin_cabs(x);
+ (void)__builtin_cabsl(x);
+}
+
+void test_complex_double(_Complex double x) {
+ (void)abs(x);
+ // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of complex type}}
+ // expected-note@-2 {{use function 'cabs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"cabs"
+ (void)labs(x);
+ // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of complex type}}
+ // expected-note@-2 {{use function 'cabs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabs"
+ (void)llabs(x);
+ // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of complex type}}
+ // expected-note@-2 {{use function 'cabs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs"
+
+ (void)fabsf(x);
+ // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of complex type}}
+ // expected-note@-2 {{use function 'cabs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs"
+ (void)fabs(x);
+ // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of complex type}}
+ // expected-note@-2 {{use function 'cabs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabs"
+ (void)fabsl(x);
+ // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of complex type}}
+ // expected-note@-2 {{use function 'cabs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs"
+
+ (void)cabsf(x);
+ // expected-warning@-1 {{absolute value function 'cabsf' given an argument of type '_Complex double' but has parameter of type '_Complex float' which may cause truncation of value}}
+ // expected-note@-2 {{use function 'cabs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs"
+ (void)cabs(x);
+ (void)cabsl(x);
+
+ (void)__builtin_abs(x);
+ // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of complex type}}
+ // expected-note@-2 {{use function '__builtin_cabs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_cabs"
+ (void)__builtin_labs(x);
+ // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of complex type}}
+ // expected-note@-2 {{use function '__builtin_cabs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabs"
+ (void)__builtin_llabs(x);
+ // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of complex type}}
+ // expected-note@-2 {{use function '__builtin_cabs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs"
+
+ (void)__builtin_fabsf(x);
+ // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of complex type}}
+ // expected-note@-2 {{use function '__builtin_cabs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs"
+ (void)__builtin_fabs(x);
+ // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of complex type}}
+ // expected-note@-2 {{use function '__builtin_cabs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabs"
+ (void)__builtin_fabsl(x);
+ // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of complex type}}
+ // expected-note@-2 {{use function '__builtin_cabs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs"
+
+ (void)__builtin_cabsf(x);
+ // expected-warning@-1 {{absolute value function '__builtin_cabsf' given an argument of type '_Complex double' but has parameter of type '_Complex float' which may cause truncation of value}}
+ // expected-note@-2 {{use function '__builtin_cabs' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs"
+ (void)__builtin_cabs(x);
+ (void)__builtin_cabsl(x);
+}
+
+void test_complex_long_double(_Complex long double x) {
+ (void)abs(x);
+ // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of complex type}}
+ // expected-note@-2 {{use function 'cabsl' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"cabsl"
+ (void)labs(x);
+ // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of complex type}}
+ // expected-note@-2 {{use function 'cabsl' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsl"
+ (void)llabs(x);
+ // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of complex type}}
+ // expected-note@-2 {{use function 'cabsl' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl"
+
+ (void)fabsf(x);
+ // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of complex type}}
+ // expected-note@-2 {{use function 'cabsl' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl"
+ (void)fabs(x);
+ // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of complex type}}
+ // expected-note@-2 {{use function 'cabsl' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsl"
+ (void)fabsl(x);
+ // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of complex type}}
+ // expected-note@-2 {{use function 'cabsl' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl"
+
+ (void)cabsf(x);
+ // expected-warning@-1 {{absolute value function 'cabsf' given an argument of type '_Complex long double' but has parameter of type '_Complex float' which may cause truncation of value}}
+ // expected-note@-2 {{use function 'cabsl' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl"
+ (void)cabs(x);
+ // expected-warning@-1 {{absolute value function 'cabs' given an argument of type '_Complex long double' but has parameter of type '_Complex double' which may cause truncation of value}}
+ // expected-note@-2 {{use function 'cabsl' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsl"
+ (void)cabsl(x);
+
+ (void)__builtin_abs(x);
+ // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of complex type}}
+ // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_cabsl"
+ (void)__builtin_labs(x);
+ // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of complex type}}
+ // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsl"
+ (void)__builtin_llabs(x);
+ // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of complex type}}
+ // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl"
+
+ (void)__builtin_fabsf(x);
+ // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of complex type}}
+ // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl"
+ (void)__builtin_fabs(x);
+ // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of complex type}}
+ // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsl"
+ (void)__builtin_fabsl(x);
+ // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of complex type}}
+ // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl"
+
+ (void)__builtin_cabsf(x);
+ // expected-warning@-1 {{absolute value function '__builtin_cabsf' given an argument of type '_Complex long double' but has parameter of type '_Complex float' which may cause truncation of value}}
+ // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl"
+ (void)__builtin_cabs(x);
+ // expected-warning@-1 {{absolute value function '__builtin_cabs' given an argument of type '_Complex long double' but has parameter of type '_Complex double' which may cause truncation of value}}
+ // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsl"
+ (void)__builtin_cabsl(x);
+}
+
+void test_unsigned_int(unsigned int x) {
+ (void)std::abs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+ // expected-note@-2 {{remove the call to 'std::abs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:17}:""
+
+ (void)abs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+ // expected-note@-2 {{remove the call to 'abs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:""
+ (void)labs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+ // expected-note@-2 {{remove the call to 'labs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:""
+ (void)llabs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+ // expected-note@-2 {{remove the call to 'llabs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+
+ (void)fabsf(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+ // expected-note@-2 {{remove the call to 'fabsf' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+ (void)fabs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+ // expected-note@-2 {{remove the call to 'fabs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:""
+ (void)fabsl(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+ // expected-note@-2 {{remove the call to 'fabsl' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+
+ (void)cabsf(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+ // expected-note@-2 {{remove the call to 'cabsf' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+ (void)cabs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+ // expected-note@-2 {{remove the call to 'cabs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:""
+ (void)cabsl(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+ // expected-note@-2 {{remove the call to 'cabsl' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+
+ (void)__builtin_abs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+ // expected-note@-2 {{remove the call to '__builtin_abs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:""
+ (void)__builtin_labs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+ // expected-note@-2 {{remove the call to '__builtin_labs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:""
+ (void)__builtin_llabs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+ // expected-note@-2 {{remove the call to '__builtin_llabs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+
+ (void)__builtin_fabsf(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+ // expected-note@-2 {{remove the call to '__builtin_fabsf' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+ (void)__builtin_fabs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+ // expected-note@-2 {{remove the call to '__builtin_fabs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:""
+ (void)__builtin_fabsl(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+ // expected-note@-2 {{remove the call to '__builtin_fabsl' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+
+ (void)__builtin_cabsf(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+ // expected-note@-2 {{remove the call to '__builtin_cabsf' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+ (void)__builtin_cabs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+ // expected-note@-2 {{remove the call to '__builtin_cabs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:""
+ (void)__builtin_cabsl(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+ // expected-note@-2 {{remove the call to '__builtin_cabsl' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+}
+
+void test_unsigned_long(unsigned long x) {
+ (void)std::abs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+ // expected-note@-2 {{remove the call to 'std::abs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:17}:""
+
+ (void)abs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+ // expected-note@-2 {{remove the call to 'abs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:""
+ (void)labs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+ // expected-note@-2 {{remove the call to 'labs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:""
+ (void)llabs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+ // expected-note@-2 {{remove the call to 'llabs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+
+ (void)fabsf(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+ // expected-note@-2 {{remove the call to 'fabsf' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+ (void)fabs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+ // expected-note@-2 {{remove the call to 'fabs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:""
+ (void)fabsl(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+ // expected-note@-2 {{remove the call to 'fabsl' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+
+ (void)cabsf(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+ // expected-note@-2 {{remove the call to 'cabsf' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+ (void)cabs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+ // expected-note@-2 {{remove the call to 'cabs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:""
+ (void)cabsl(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+ // expected-note@-2 {{remove the call to 'cabsl' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+
+ (void)__builtin_abs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+ // expected-note@-2 {{remove the call to '__builtin_abs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:""
+ (void)__builtin_labs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+ // expected-note@-2 {{remove the call to '__builtin_labs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:""
+ (void)__builtin_llabs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+ // expected-note@-2 {{remove the call to '__builtin_llabs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+
+ (void)__builtin_fabsf(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+ // expected-note@-2 {{remove the call to '__builtin_fabsf' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+ (void)__builtin_fabs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+ // expected-note@-2 {{remove the call to '__builtin_fabs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:""
+ (void)__builtin_fabsl(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+ // expected-note@-2 {{remove the call to '__builtin_fabsl' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+
+ (void)__builtin_cabsf(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+ // expected-note@-2 {{remove the call to '__builtin_cabsf' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+ (void)__builtin_cabs(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+ // expected-note@-2 {{remove the call to '__builtin_cabs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:""
+ (void)__builtin_cabsl(x);
+ // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+ // expected-note@-2 {{remove the call to '__builtin_cabsl' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+}
+
diff --git a/test/SemaCXX/warn-address.cpp b/test/SemaCXX/warn-address.cpp
new file mode 100644
index 0000000000000..219edfdc80c2e
--- /dev/null
+++ b/test/SemaCXX/warn-address.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-bool-conversion -Wno-string-compare -Wno-tautological-compare -Waddress %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void foo();
+int arr[5];
+int global;
+const char* str = "";
+
+void test() {
+ if (foo) {} // expected-warning{{always evaluate to 'true'}} \
+ // expected-note{{silence}}
+ if (arr) {} // expected-warning{{always evaluate to 'true'}}
+ if (&global) {} // expected-warning{{always evaluate to 'true'}}
+ if (foo == 0) {} // expected-warning{{always false}} \
+ // expected-note{{silence}}
+ if (arr == 0) {} // expected-warning{{always false}}
+ if (&global == 0) {} // expected-warning{{always false}}
+
+ if (str == "foo") {} // expected-warning{{unspecified}}
+}
diff --git a/test/SemaCXX/warn-bad-memaccess.cpp b/test/SemaCXX/warn-bad-memaccess.cpp
index 7a7459acee1d3..e86610ab64d96 100644
--- a/test/SemaCXX/warn-bad-memaccess.cpp
+++ b/test/SemaCXX/warn-bad-memaccess.cpp
@@ -24,6 +24,11 @@ public:
struct X1 { virtual void f(); } x1;
struct X2 : virtual S1 {} x2;
+struct ContainsDynamic { X1 dynamic; } contains_dynamic;
+struct DeepContainsDynamic { ContainsDynamic m; } deep_contains_dynamic;
+struct ContainsArrayDynamic { X1 dynamic[1]; } contains_array_dynamic;
+struct ContainsPointerDynamic { X1 *dynamic; } contains_pointer_dynamic;
+
void test_warn() {
memset(&x1, 0, sizeof x1); // \
// expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
@@ -33,22 +38,22 @@ void test_warn() {
// expected-note {{explicitly cast the pointer to silence this warning}}
memmove(&x1, 0, sizeof x1); // \
- // expected-warning{{destination for this 'memmove' call is a pointer to dynamic class 'struct X1'; vtable pointer will be overwritten}} \
+ // expected-warning{{destination for this 'memmove' call is a pointer to dynamic class 'X1'; vtable pointer will be overwritten}} \
// expected-note {{explicitly cast the pointer to silence this warning}}
memmove(0, &x1, sizeof x1); // \
- // expected-warning{{source of this 'memmove' call is a pointer to dynamic class 'struct X1'; vtable pointer will be moved}} \
+ // expected-warning{{source of this 'memmove' call is a pointer to dynamic class 'X1'; vtable pointer will be moved}} \
// expected-note {{explicitly cast the pointer to silence this warning}}
memcpy(&x1, 0, sizeof x1); // \
- // expected-warning{{destination for this 'memcpy' call is a pointer to dynamic class 'struct X1'; vtable pointer will be overwritten}} \
+ // expected-warning{{destination for this 'memcpy' call is a pointer to dynamic class 'X1'; vtable pointer will be overwritten}} \
// expected-note {{explicitly cast the pointer to silence this warning}}
memcpy(0, &x1, sizeof x1); // \
- // expected-warning{{source of this 'memcpy' call is a pointer to dynamic class 'struct X1'; vtable pointer will be copied}} \
+ // expected-warning{{source of this 'memcpy' call is a pointer to dynamic class 'X1'; vtable pointer will be copied}} \
// expected-note {{explicitly cast the pointer to silence this warning}}
memcmp(&x1, 0, sizeof x1); // \
- // expected-warning{{first operand of this 'memcmp' call is a pointer to dynamic class 'struct X1'; vtable pointer will be compared}} \
+ // expected-warning{{first operand of this 'memcmp' call is a pointer to dynamic class 'X1'; vtable pointer will be compared}} \
// expected-note {{explicitly cast the pointer to silence this warning}}
memcmp(0, &x1, sizeof x1); // \
- // expected-warning{{second operand of this 'memcmp' call is a pointer to dynamic class 'struct X1'; vtable pointer will be compared}} \
+ // expected-warning{{second operand of this 'memcmp' call is a pointer to dynamic class 'X1'; vtable pointer will be compared}} \
// expected-note {{explicitly cast the pointer to silence this warning}}
__builtin_memset(&x1, 0, sizeof x1); // \
@@ -90,6 +95,16 @@ void test_warn() {
__builtin___memcpy_chk(0, &x1, sizeof x1, sizeof x1); // \
// expected-warning{{source of this '__builtin___memcpy_chk' call is a pointer to dynamic class}} \
// expected-note {{explicitly cast the pointer to silence this warning}}
+
+ // expected-warning@+2 {{destination for this 'memset' call is a pointer to class containing a dynamic class 'X1'}}
+ // expected-note@+1 {{explicitly cast the pointer to silence this warning}}
+ memset(&contains_dynamic, 0, sizeof(contains_dynamic));
+ // expected-warning@+2 {{destination for this 'memset' call is a pointer to class containing a dynamic class 'X1'}}
+ // expected-note@+1 {{explicitly cast the pointer to silence this warning}}
+ memset(&deep_contains_dynamic, 0, sizeof(deep_contains_dynamic));
+ // expected-warning@+2 {{destination for this 'memset' call is a pointer to class containing a dynamic class 'X1'}}
+ // expected-note@+1 {{explicitly cast the pointer to silence this warning}}
+ memset(&contains_array_dynamic, 0, sizeof(contains_array_dynamic));
}
void test_nowarn(void *void_ptr) {
@@ -107,6 +122,8 @@ void test_nowarn(void *void_ptr) {
memset(&s3, 0, sizeof s3);
memset(&c1, 0, sizeof c1);
+ memset(&contains_pointer_dynamic, 0, sizeof(contains_pointer_dynamic));
+
// Unevaluated code shouldn't warn.
(void)sizeof memset(&x1, 0, sizeof x1);
diff --git a/test/SemaCXX/warn-bool-conversion.cpp b/test/SemaCXX/warn-bool-conversion.cpp
index b3d136ecf2b13..b4628947f06e8 100644
--- a/test/SemaCXX/warn-bool-conversion.cpp
+++ b/test/SemaCXX/warn-bool-conversion.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
+namespace BooleanFalse {
int* j = false; // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
void foo(int* i, int *j=(false)) // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
@@ -22,3 +23,98 @@ double f(...);
// isn't flagged.
template <int N> struct S {};
S<sizeof(f(false))> s;
+
+}
+
+namespace Function {
+void f1();
+
+struct S {
+ static void f2();
+};
+
+extern void f3() __attribute__((weak_import));
+
+struct S2 {
+ static void f4() __attribute__((weak_import));
+};
+
+bool f5();
+bool f6(int);
+
+void bar() {
+ bool b;
+
+ b = f1; // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
+ expected-note {{prefix with the address-of operator to silence this warning}}
+ if (f1) {} // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
+ expected-note {{prefix with the address-of operator to silence this warning}}
+ b = S::f2; // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
+ expected-note {{prefix with the address-of operator to silence this warning}}
+ if (S::f2) {} // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
+ expected-note {{prefix with the address-of operator to silence this warning}}
+ b = f5; // expected-warning {{address of function 'f5' will always evaluate to 'true'}} \
+ expected-note {{prefix with the address-of operator to silence this warning}} \
+ expected-note {{suffix with parentheses to turn this into a function call}}
+ b = f6; // expected-warning {{address of function 'f6' will always evaluate to 'true'}} \
+ expected-note {{prefix with the address-of operator to silence this warning}}
+
+ // implicit casts of weakly imported symbols are ok:
+ b = f3;
+ if (f3) {}
+ b = S2::f4;
+ if (S2::f4) {}
+}
+}
+
+namespace Array {
+ #define GetValue(ptr) ((ptr) ? ptr[0] : 0)
+ extern int a[] __attribute__((weak));
+ int b[] = {8,13,21};
+ struct {
+ int x[10];
+ } c;
+ const char str[] = "text";
+ void ignore() {
+ if (a) {}
+ if (a) {}
+ (void)GetValue(b);
+ }
+ void test() {
+ if (b) {}
+ // expected-warning@-1{{address of array 'b' will always evaluate to 'true'}}
+ if (b) {}
+ // expected-warning@-1{{address of array 'b' will always evaluate to 'true'}}
+ if (c.x) {}
+ // expected-warning@-1{{address of array 'c.x' will always evaluate to 'true'}}
+ if (str) {}
+ // expected-warning@-1{{address of array 'str' will always evaluate to 'true'}}
+ }
+}
+
+namespace Pointer {
+ extern int a __attribute__((weak));
+ int b;
+ static int c;
+ class S {
+ public:
+ static int a;
+ int b;
+ };
+ void ignored() {
+ if (&a) {}
+ }
+ void test() {
+ S s;
+ if (&b) {}
+ // expected-warning@-1{{address of 'b' will always evaluate to 'true'}}
+ if (&c) {}
+ // expected-warning@-1{{address of 'c' will always evaluate to 'true'}}
+ if (&s.a) {}
+ // expected-warning@-1{{address of 's.a' will always evaluate to 'true'}}
+ if (&s.b) {}
+ // expected-warning@-1{{address of 's.b' will always evaluate to 'true'}}
+ if (&S::a) {}
+ // expected-warning@-1{{address of 'S::a' will always evaluate to 'true'}}
+ }
+}
diff --git a/test/SemaCXX/warn-consumed-analysis.cpp b/test/SemaCXX/warn-consumed-analysis.cpp
index 2c372c752baf4..977b862a92b50 100644
--- a/test/SemaCXX/warn-consumed-analysis.cpp
+++ b/test/SemaCXX/warn-consumed-analysis.cpp
@@ -51,7 +51,7 @@ public:
class CONSUMABLE(unconsumed) DestructorTester {
public:
- DestructorTester() RETURN_TYPESTATE(unconsumed);
+ DestructorTester();
DestructorTester(int);
void operator*() CALLABLE_WHEN("unconsumed");
@@ -82,11 +82,21 @@ ConsumableClass<int> returnsUnknown() RETURN_TYPESTATE(unknown);
void testInitialization() {
ConsumableClass<int> var0;
ConsumableClass<int> var1 = ConsumableClass<int>();
-
- var0 = ConsumableClass<int>();
-
+ ConsumableClass<int> var2(42);
+ ConsumableClass<int> var3(var2); // copy constructor
+ ConsumableClass<int> var4(var0); // copy consumed value
+
*var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
*var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
+ *var2;
+ *var3;
+ *var4; // expected-warning {{invalid invocation of method 'operator*' on object 'var4' while it is in the 'consumed' state}}
+
+ var0 = ConsumableClass<int>(42);
+ *var0;
+
+ var0 = var1;
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
if (var0.isValid()) {
*var0;
@@ -98,19 +108,16 @@ void testInitialization() {
}
void testDestruction() {
- DestructorTester D0(42), D1(42);
+ DestructorTester D0(42), D1(42), D2;
*D0;
*D1;
-
- DestructorTester D2;
- *D2;
+ *D2; // expected-warning {{invalid invocation of method 'operator*' on object 'D2' while it is in the 'consumed' state}}
D0.~DestructorTester(); // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}}
return; // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}} \
- expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}} \
- expected-warning {{invalid invocation of method '~DestructorTester' on object 'D2' while it is in the 'unconsumed' state}}
+ expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}}
}
void testTempValue() {
@@ -427,6 +434,29 @@ void testParamTypestateCaller() {
testParamTypestateCallee(Var0, Var1); // expected-warning {{argument not in expected state; expected 'consumed', observed 'unconsumed'}}
}
+
+void consumeFunc(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+struct ParamTest {
+ static void consumeFuncStatic(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+ void consumeFuncMeth(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+ void operator<<(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+};
+
+void operator>>(ParamTest& pt, ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+
+
+void testFunctionParams() {
+ // Make sure we handle the different kinds of functions.
+ ConsumableClass<int> P;
+
+ consumeFunc(P); // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+ ParamTest::consumeFuncStatic(P); // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+ ParamTest pt;
+ pt.consumeFuncMeth(P); // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+ pt << P; // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+ pt >> P; // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+}
+
void baf3(ConsumableClass<int> var) {
*var;
}
@@ -645,12 +675,17 @@ void read(bool sf) {
} // end namespace ContinueICETest
-namespace InitializerAssertionFailTest {
+namespace StatusUseCaseTests {
-class CONSUMABLE(unconsumed) Status {
+class CONSUMABLE(unconsumed)
+ __attribute__((consumable_auto_cast_state))
+ __attribute__((consumable_set_state_on_read))
+ Status {
int code;
public:
+ static Status OK;
+
Status() RETURN_TYPESTATE(consumed);
Status(int c) RETURN_TYPESTATE(unconsumed);
@@ -660,6 +695,8 @@ public:
Status& operator=(const Status &other) CALLABLE_WHEN("unknown", "consumed");
Status& operator=(Status &&other) CALLABLE_WHEN("unknown", "consumed");
+ bool operator==(const Status &other) const SET_TYPESTATE(consumed);
+
bool check() const SET_TYPESTATE(consumed);
void ignore() const SET_TYPESTATE(consumed);
// Status& markAsChecked() { return *this; }
@@ -667,13 +704,22 @@ public:
void clear() CALLABLE_WHEN("unknown", "consumed") SET_TYPESTATE(consumed);
~Status() CALLABLE_WHEN("unknown", "consumed");
+
+ operator bool() const; // Will not consume the object.
};
bool cond();
Status doSomething();
void handleStatus(const Status& s RETURN_TYPESTATE(consumed));
-void handleStatusPtr(const Status* s);
+void handleStatusRef(Status& s);
+void handleStatusPtr(Status* s);
+void handleStatusUnmarked(const Status& s);
+
+void log(const char* msg);
+void fail() __attribute__((noreturn));
+void checkStat(const Status& s);
+
void testSimpleTemporaries0() {
doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}}
@@ -691,6 +737,19 @@ void testSimpleTemporaries3() {
Status s = doSomething();
} // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
+void testTemporariesWithControlFlow(bool a) {
+ bool b = false || doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}}
+}
+
+Status testSimpleTemporariesReturn0() {
+ return doSomething();
+}
+
+Status testSimpleTemporariesReturn1() {
+ Status s = doSomething();
+ return s;
+}
+
void testSimpleTemporaries4() {
Status s = doSomething();
s.check();
@@ -702,8 +761,17 @@ void testSimpleTemporaries5() {
}
void testSimpleTemporaries6() {
- Status s = doSomething();
- handleStatus(s);
+ Status s1 = doSomething();
+ handleStatus(s1);
+
+ Status s2 = doSomething();
+ handleStatusRef(s2);
+
+ Status s3 = doSomething();
+ handleStatusPtr(&s3);
+
+ Status s4 = doSomething();
+ handleStatusUnmarked(s4);
}
void testSimpleTemporaries7() {
@@ -745,38 +813,58 @@ void testTemporariesWithConditionals3() {
}
void testTemporariesAndConstructors0() {
- Status s(doSomething());
+ Status s(doSomething()); // Test the copy constructor.
s.check();
}
-void testTemporariesAndConstructors1() {
- // Test the copy constructor.
-
- Status s1 = doSomething();
+void testTemporariesAndConstructors1F() {
+ Status s1 = doSomething(); // Test the copy constructor.
+ Status s2 = s1;
+} // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
+
+void testTemporariesAndConstructors1S() {
+ Status s1 = doSomething(); // Test the copy constructor.
Status s2(s1);
s2.check();
-} // expected-warning {{invalid invocation of method '~Status' on object 's1' while it is in the 'unconsumed' state}}
+}
-void testTemporariesAndConstructors2() {
+void testTemporariesAndConstructors2F() {
// Test the move constructor.
-
Status s1 = doSomething();
- Status s2(static_cast<Status&&>(s1));
+ Status s2 = static_cast<Status&&>(s1);
+} // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
+
+void testTemporariesAndConstructors2S() {
+ // Test the move constructor.
+ Status s1 = doSomething();
+ Status s2 = static_cast<Status&&>(s1);
s2.check();
}
-void testTemporariesAndOperators0() {
+void testTemporariesAndOperators0F() {
+ // Test the assignment operator.
+ Status s1 = doSomething();
+ Status s2;
+ s2 = s1;
+} // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
+
+void testTemporariesAndOperators0S() {
// Test the assignment operator.
-
Status s1 = doSomething();
Status s2;
s2 = s1;
s2.check();
-} // expected-warning {{invalid invocation of method '~Status' on object 's1' while it is in the 'unconsumed' state}}
+}
-void testTemporariesAndOperators1() {
+void testTemporariesAndOperators1F() {
+ // Test the move assignment operator.
+ Status s1 = doSomething();
+ Status s2;
+ s2 = static_cast<Status&&>(s1);
+} // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
+
+void testTemporariesAndOperators1S() {
// Test the move assignment operator.
-
Status s1 = doSomething();
Status s2;
s2 = static_cast<Status&&>(s1);
@@ -791,6 +879,35 @@ void testTemporariesAndOperators2() {
s2.check();
}
+Status testReturnAutocast() {
+ Status s = doSomething();
+ s.check(); // consume s
+ return s; // should autocast back to unconsumed
+}
+
+
+namespace TestParens {
+
+void test3() {
+ checkStat((doSomething()));
+}
+
+void test4() {
+ Status s = (doSomething());
+ s.check();
+}
+
+void test5() {
+ (doSomething()).check();
+}
+
+void test6() {
+ if ((doSomething()) == Status::OK)
+ return;
+}
+
+} // end namespace TestParens
+
} // end namespace InitializerAssertionFailTest
@@ -820,3 +937,4 @@ namespace PR18260 {
std::__1::move(x);
}
} // end namespace PR18260
+
diff --git a/test/SemaCXX/warn-consumed-parsing.cpp b/test/SemaCXX/warn-consumed-parsing.cpp
index 0a91636ea9492..5c0a04fffe36e 100644
--- a/test/SemaCXX/warn-consumed-parsing.cpp
+++ b/test/SemaCXX/warn-consumed-parsing.cpp
@@ -17,9 +17,9 @@ int returnTypestateForUnconsumable() {
}
class AttrTester0 {
- void consumes() __attribute__ ((set_typestate())); // expected-error {{attribute takes one argument}}
- bool testUnconsumed() __attribute__ ((test_typestate())); // expected-error {{attribute takes one argument}}
- void callableWhen() __attribute__ ((callable_when())); // expected-error {{attribute takes at least 1 argument}}
+ void consumes() __attribute__ ((set_typestate())); // expected-error {{'set_typestate' attribute takes one argument}}
+ bool testUnconsumed() __attribute__ ((test_typestate())); // expected-error {{'test_typestate' attribute takes one argument}}
+ void callableWhen() __attribute__ ((callable_when())); // expected-error {{'callable_when' attribute takes at least 1 argument}}
};
int var0 SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to methods}}
@@ -53,3 +53,13 @@ class AttrTester2 {
};
class CONSUMABLE(42) AttrTester3; // expected-error {{'consumable' attribute requires an identifier}}
+
+
+class CONSUMABLE(unconsumed)
+ __attribute__((consumable_auto_cast_state))
+ __attribute__((consumable_set_state_on_read))
+ Status {
+};
+
+
+
diff --git a/test/SemaCXX/warn-exit-time-destructors.cpp b/test/SemaCXX/warn-exit-time-destructors.cpp
index f49134b71c971..124576aa95b6d 100644
--- a/test/SemaCXX/warn-exit-time-destructors.cpp
+++ b/test/SemaCXX/warn-exit-time-destructors.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wexit-time-destructors %s -verify
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wexit-time-destructors %s -verify
namespace test1 {
struct A { ~A(); };
@@ -23,5 +23,23 @@ void f() {
static A &e = b[5];
static A &f = c[5][7];
}
+}
+
+namespace test3 {
+ struct A { ~A() = default; };
+ A a;
+
+ struct B { ~B(); };
+ struct C : B { ~C() = default; };
+ C c; // expected-warning {{exit-time destructor}}
+ class D {
+ friend struct E;
+ ~D() = default;
+ };
+ struct E : D {
+ D d;
+ ~E() = default;
+ };
+ E e;
}
diff --git a/test/SemaCXX/warn-float-conversion.cpp b/test/SemaCXX/warn-float-conversion.cpp
new file mode 100644
index 0000000000000..22c33040b26b8
--- /dev/null
+++ b/test/SemaCXX/warn-float-conversion.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s -Wfloat-conversion
+
+bool ReturnBool(float f) {
+ return f; //expected-warning{{conversion}}
+}
+
+char ReturnChar(float f) {
+ return f; //expected-warning{{conversion}}
+}
+
+int ReturnInt(float f) {
+ return f; //expected-warning{{conversion}}
+}
+
+long ReturnLong(float f) {
+ return f; //expected-warning{{conversion}}
+}
+
+void Convert(float f, double d, long double ld) {
+ bool b;
+ char c;
+ int i;
+ long l;
+
+ b = f; //expected-warning{{conversion}}
+ b = d; //expected-warning{{conversion}}
+ b = ld; //expected-warning{{conversion}}
+ c = f; //expected-warning{{conversion}}
+ c = d; //expected-warning{{conversion}}
+ c = ld; //expected-warning{{conversion}}
+ i = f; //expected-warning{{conversion}}
+ i = d; //expected-warning{{conversion}}
+ i = ld; //expected-warning{{conversion}}
+ l = f; //expected-warning{{conversion}}
+ l = d; //expected-warning{{conversion}}
+ l = ld; //expected-warning{{conversion}}
+}
+
diff --git a/test/SemaCXX/warn-func-as-bool.cpp b/test/SemaCXX/warn-func-as-bool.cpp
deleted file mode 100644
index b5df744f93067..0000000000000
--- a/test/SemaCXX/warn-func-as-bool.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-// RUN: %clang_cc1 -x c++ -verify -fsyntax-only %s
-
-void f1();
-
-struct S {
- static void f2();
-};
-
-extern void f3() __attribute__((weak_import));
-
-struct S2 {
- static void f4() __attribute__((weak_import));
-};
-
-bool f5();
-bool f6(int);
-
-void bar() {
- bool b;
-
- b = f1; // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
- expected-note {{prefix with the address-of operator to silence this warning}}
- if (f1) {} // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
- expected-note {{prefix with the address-of operator to silence this warning}}
- b = S::f2; // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
- expected-note {{prefix with the address-of operator to silence this warning}}
- if (S::f2) {} // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
- expected-note {{prefix with the address-of operator to silence this warning}}
- b = f5; // expected-warning {{address of function 'f5' will always evaluate to 'true'}} \
- expected-note {{prefix with the address-of operator to silence this warning}} \
- expected-note {{suffix with parentheses to turn this into a function call}}
- b = f6; // expected-warning {{address of function 'f6' will always evaluate to 'true'}} \
- expected-note {{prefix with the address-of operator to silence this warning}}
-
- // implicit casts of weakly imported symbols are ok:
- b = f3;
- if (f3) {}
- b = S2::f4;
- if (S2::f4) {}
-}
diff --git a/test/SemaCXX/warn-global-constructors.cpp b/test/SemaCXX/warn-global-constructors.cpp
index f57f0de70812a..90d8558666c3b 100644
--- a/test/SemaCXX/warn-global-constructors.cpp
+++ b/test/SemaCXX/warn-global-constructors.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wglobal-constructors %s -verify
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wglobal-constructors %s -verify
int opaque_int();
@@ -101,3 +101,22 @@ namespace referencemember {
int a;
A b = { a };
}
+
+namespace pr19253 {
+ struct A { ~A() = default; };
+ A a;
+
+ struct B { ~B(); };
+ struct C : B { ~C() = default; };
+ C c; // expected-warning {{global destructor}}
+
+ class D {
+ friend struct E;
+ ~D() = default;
+ };
+ struct E : D {
+ D d;
+ ~E() = default;
+ };
+ E e;
+}
diff --git a/test/SemaCXX/warn-infinite-recursion.cpp b/test/SemaCXX/warn-infinite-recursion.cpp
new file mode 100644
index 0000000000000..e1b7c5412e1f0
--- /dev/null
+++ b/test/SemaCXX/warn-infinite-recursion.cpp
@@ -0,0 +1,152 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -Winfinite-recursion
+
+void a() { // expected-warning{{call itself}}
+ a();
+}
+
+void b(int x) { // expected-warning{{call itself}}
+ if (x)
+ b(x);
+ else
+ b(x+1);
+}
+
+void c(int x) {
+ if (x)
+ c(5);
+}
+
+void d(int x) { // expected-warning{{call itself}}
+ if (x)
+ ++x;
+ return d(x);
+}
+
+// Doesn't warn on mutually recursive functions
+void e();
+void f();
+
+void e() { f(); }
+void f() { e(); }
+
+// Don't warn on infinite loops
+void g() {
+ while (true)
+ g();
+
+ g();
+}
+
+void h(int x) {
+ while (x < 5) {
+ h(x+1);
+ }
+}
+
+void i(int x) { // expected-warning{{call itself}}
+ while (x < 5) {
+ --x;
+ }
+ i(0);
+}
+
+int j() { // expected-warning{{call itself}}
+ return 5 + j();
+}
+
+class S {
+ static void a();
+ void b();
+};
+
+void S::a() { // expected-warning{{call itself}}
+ return a();
+}
+
+void S::b() { // expected-warning{{call itself}}
+ int i = 0;
+ do {
+ ++i;
+ b();
+ } while (i > 5);
+}
+
+template<class member>
+struct T {
+ member m;
+ void a() { return a(); } // expected-warning{{call itself}}
+ static void b() { return b(); } // expected-warning{{call itself}}
+};
+
+void test_T() {
+ T<int> foo;
+ foo.a(); // expected-note{{in instantiation}}
+ foo.b(); // expected-note{{in instantiation}}
+}
+
+class U {
+ U* u;
+ void Fun() { // expected-warning{{call itself}}
+ u->Fun();
+ }
+};
+
+// No warnings on templated functions
+// sum<0>() is instantiated, does recursively call itself, but never runs.
+template <int value>
+int sum() {
+ return value + sum<value/2>();
+}
+
+template<>
+int sum<1>() { return 1; }
+
+template<int x, int y>
+int calculate_value() {
+ if (x != y)
+ return sum<x - y>(); // This instantiates sum<0>() even if never called.
+ else
+ return 0;
+}
+
+int value = calculate_value<1,1>();
+
+void DoSomethingHere();
+
+// DoStuff<0,0>() is instantiated, but never called.
+template<int First, int Last>
+int DoStuff() {
+ if (First + 1 == Last) {
+ // This branch gets removed during <0, 0> instantiation in so CFG for this
+ // function goes straight to the else branch.
+ DoSomethingHere();
+ } else {
+ DoStuff<First, (First + Last)/2>();
+ DoStuff<(First + Last)/2, Last>();
+ }
+ return 0;
+}
+int stuff = DoStuff<0, 1>();
+
+template<int x>
+struct Wrapper {
+ static int run() {
+ // Similar to the above, Wrapper<0>::run() will discard the if statement.
+ if (x == 1)
+ return 0;
+ return Wrapper<x/2>::run();
+ }
+ static int run2() { // expected-warning{{call itself}}
+ return run2();
+ }
+};
+
+template <int x>
+int test_wrapper() {
+ if (x != 0)
+ return Wrapper<x>::run() +
+ Wrapper<x>::run2(); // expected-note{{instantiation}}
+ return 0;
+}
+
+int wrapper_sum = test_wrapper<2>(); // expected-note{{instantiation}}
diff --git a/test/SemaCXX/warn-memsize-comparison.cpp b/test/SemaCXX/warn-memsize-comparison.cpp
new file mode 100644
index 0000000000000..54c410e3dc0b8
--- /dev/null
+++ b/test/SemaCXX/warn-memsize-comparison.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+//
+
+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 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);
+extern "C" char *strncat(char *dst, const char *src, size_t n);
+extern "C" char *strndup(const char *src, size_t n);
+extern "C" size_t strlcpy(char *dst, const char *src, size_t size);
+extern "C" size_t strlcat(char *dst, const char *src, size_t size);
+
+void f() {
+ char b1[80], b2[80];
+ if (memset(b1, 0, sizeof(b1) != 0)) {} // \
+ expected-warning{{size argument in 'memset' call is a comparison}} \
+ expected-note {{did you mean to compare}} \
+ expected-note {{explicitly cast the argument}}
+ if (memset(b1, 0, sizeof(b1)) != 0) {}
+
+ if (memmove(b1, b2, sizeof(b1) == 0)) {} // \
+ expected-warning{{size argument in 'memmove' call is a comparison}} \
+ expected-note {{did you mean to compare}} \
+ expected-note {{explicitly cast the argument}}
+ if (memmove(b1, b2, sizeof(b1)) == 0) {}
+
+ 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 (memcmp(b1, b2, sizeof(b1) <= 0)) {} // \
+ expected-warning{{size argument in 'memcmp' call is a comparison}} \
+ expected-note {{did you mean to compare}} \
+ expected-note {{explicitly cast the argument}}
+ if (memcmp(b1, b2, sizeof(b1)) <= 0) {}
+
+ if (strncmp(b1, b2, sizeof(b1) > 0)) {} // \
+ expected-warning{{size argument in 'strncmp' call is a comparison}} \
+ expected-note {{did you mean to compare}} \
+ expected-note {{explicitly cast the argument}}
+ if (strncmp(b1, b2, sizeof(b1)) > 0) {}
+
+ if (strncasecmp(b1, b2, sizeof(b1) >= 0)) {} // \
+ expected-warning{{size argument in 'strncasecmp' call is a comparison}} \
+ expected-note {{did you mean to compare}} \
+ expected-note {{explicitly cast the argument}}
+ if (strncasecmp(b1, b2, sizeof(b1)) >= 0) {}
+
+ if (strncpy(b1, b2, sizeof(b1) == 0 || true)) {} // \
+ expected-warning{{size argument in 'strncpy' call is a comparison}} \
+ expected-note {{did you mean to compare}} \
+ expected-note {{explicitly cast the argument}}
+ if (strncpy(b1, b2, sizeof(b1)) == 0 || true) {}
+
+ 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 (strndup(b1, sizeof(b1) != 0)) {} // \
+ expected-warning{{size argument in 'strndup' call is a comparison}} \
+ expected-note {{did you mean to compare}} \
+ expected-note {{explicitly cast the argument}}
+ if (strndup(b1, sizeof(b1)) != 0) {}
+
+ if (strlcpy(b1, b2, sizeof(b1) != 0)) {} // \
+ expected-warning{{size argument in 'strlcpy' call is a comparison}} \
+ expected-note {{did you mean to compare}} \
+ expected-note {{explicitly cast the argument}}
+ if (strlcpy(b1, b2, sizeof(b1)) != 0) {}
+
+ if (strlcat(b1, b2, sizeof(b1) != 0)) {} // \
+ expected-warning{{size argument in 'strlcat' call is a comparison}} \
+ expected-note {{did you mean to compare}} \
+ expected-note {{explicitly cast the argument}}
+ if (strlcat(b1, b2, sizeof(b1)) != 0) {}
+
+ if (memset(b1, 0, sizeof(b1) / 2)) {}
+ if (memset(b1, 0, sizeof(b1) >> 2)) {}
+ if (memset(b1, 0, 4 << 2)) {}
+ if (memset(b1, 0, 4 + 2)) {}
+ if (memset(b1, 0, 4 - 2)) {}
+ if (memset(b1, 0, 4 * 2)) {}
+
+ if (memset(b1, 0, (size_t)(sizeof(b1) != 0))) {}
+}
diff --git a/test/SemaCXX/warn-new-overaligned.cpp b/test/SemaCXX/warn-new-overaligned.cpp
index 42a4e3523ad2f..710973ccb32b5 100644
--- a/test/SemaCXX/warn-new-overaligned.cpp
+++ b/test/SemaCXX/warn-new-overaligned.cpp
@@ -38,7 +38,7 @@ struct Test {
} __attribute__((aligned(256)));
void* operator new(unsigned long) {
- return 0;
+ return 0; // expected-warning {{'operator new' should not return a null pointer unless it is declared 'throw()'}}
}
SeparateCacheLines<int> high_contention_data[10];
@@ -59,7 +59,7 @@ struct Test {
} __attribute__((aligned(256)));
void* operator new[](unsigned long) {
- return 0;
+ return 0; // expected-warning {{'operator new[]' should not return a null pointer unless it is declared 'throw()'}}
}
SeparateCacheLines<int> high_contention_data[10];
diff --git a/test/SemaCXX/warn-reinterpret-base-class.cpp b/test/SemaCXX/warn-reinterpret-base-class.cpp
index 36b8fda553062..0231f194ace2d 100644
--- a/test/SemaCXX/warn-reinterpret-base-class.cpp
+++ b/test/SemaCXX/warn-reinterpret-base-class.cpp
@@ -1,5 +1,8 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s
-// RUN: not %clang_cc1 -std=c++11 -fsyntax-only -fdiagnostics-parseable-fixits -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -triple %itanium_abi_triple -verify -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s
+
+// RUN: not %clang_cc1 -std=c++11 -fsyntax-only -triple %itanium_abi_triple -fdiagnostics-parseable-fixits -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -std=c++11 -fsyntax-only -triple %ms_abi_triple -fdiagnostics-parseable-fixits -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s 2>&1 | FileCheck %s
// PR 13824
class A {
@@ -288,6 +291,11 @@ void different_subobject_downcast(E *e, F *f, A *a) {
(void)reinterpret_cast<I *>(f);
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+#ifdef MSABI
+ // In MS ABI mode, A is at non-zero offset in H.
+ // expected-warning@+3 {{'reinterpret_cast' to class 'H *' from its base at non-zero offset 'A *' behaves differently from 'static_cast'}}
+ // expected-note@+2 {{use 'static_cast'}}
+#endif
(void)reinterpret_cast<H *>(a);
// expected-warning@+2 {{'reinterpret_cast' to class 'L' (aka 'const F *volatile') from its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
@@ -309,6 +317,12 @@ void different_subobject_upcast(F *f, G *g, H *h, I *i) {
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
(void)reinterpret_cast<E *>(h);
+
+#ifdef MSABI
+ // In MS ABI mode, A is at non-zero offset in H.
+ // expected-warning@+3 {{'reinterpret_cast' from class 'H *' to its base at non-zero offset 'A *' behaves differently from 'static_cast'}}
+ // expected-note@+2 {{use 'static_cast'}}
+#endif
(void)reinterpret_cast<A *>(h);
// expected-warning@+2 {{'reinterpret_cast' from class 'I *' to its virtual base 'F *' behaves differently from 'static_cast'}}
diff --git a/test/SemaCXX/warn-self-assign.cpp b/test/SemaCXX/warn-self-assign.cpp
index fcdb2ab6bc639..7d558c6a073e8 100644
--- a/test/SemaCXX/warn-self-assign.cpp
+++ b/test/SemaCXX/warn-self-assign.cpp
@@ -8,6 +8,9 @@ void f() {
b = a = b;
a = a = a; // expected-warning{{explicitly assigning}}
a = b = b = a;
+ a &= a; // expected-warning{{explicitly assigning}}
+ a |= a; // expected-warning{{explicitly assigning}}
+ a ^= a;
}
// Dummy type.
diff --git a/test/SemaCXX/warn-shadow.cpp b/test/SemaCXX/warn-shadow.cpp
index 68e9467a937b1..5ad2233d234a0 100644
--- a/test/SemaCXX/warn-shadow.cpp
+++ b/test/SemaCXX/warn-shadow.cpp
@@ -22,7 +22,7 @@ using namespace xx;
using namespace yy;
void foo() {
- int i; // expected-warning {{declaration shadows a variable in namespace '<anonymous>'}}
+ int i; // expected-warning {{declaration shadows a variable in namespace '(anonymous)'}}
int j; // expected-warning {{declaration shadows a variable in namespace 'one::two'}}
int m;
}
diff --git a/test/SemaCXX/warn-sign-conversion.cpp b/test/SemaCXX/warn-sign-conversion.cpp
index ba2bc9b3d026d..746b1242fe1b9 100644
--- a/test/SemaCXX/warn-sign-conversion.cpp
+++ b/test/SemaCXX/warn-sign-conversion.cpp
@@ -25,23 +25,23 @@ namespace test1 {
int c1 = 1 ? i : Foo<bool>::C;
int c2 = 1 ? Foo<bool>::C : i;
- int d1a = 1 ? i : Foo<bool>::D; // expected-warning {{test1::Foo<bool>::<anonymous enum at }}
- int d1b = 1 ? i : Foo<bool>::D; // expected-warning {{warn-sign-conversion.cpp:13:5>' to 'int'}}
- int d2a = 1 ? Foo<bool>::D : i; // expected-warning {{operand of ? changes signedness: 'test1::Foo<bool>::<anonymous enum at }}
- int d2b = 1 ? Foo<bool>::D : i; // expected-warning {{warn-sign-conversion.cpp:13:5>' to 'int'}}
- int d3a = 1 ? B : Foo<bool>::D; // expected-warning {{operand of ? changes signedness: 'test1::Foo<bool>::<anonymous enum at }}
- int d3b = 1 ? B : Foo<bool>::D; // expected-warning {{warn-sign-conversion.cpp:13:5>' to 'int'}}
- int d4a = 1 ? Foo<bool>::D : B; // expected-warning {{operand of ? changes signedness: 'test1::Foo<bool>::<anonymous enum at }}
- int d4b = 1 ? Foo<bool>::D : B; // expected-warning {{warn-sign-conversion.cpp:13:5>' to 'int'}}
+ int d1a = 1 ? i : Foo<bool>::D; // expected-warning {{test1::Foo<bool>::(anonymous enum at }}
+ int d1b = 1 ? i : Foo<bool>::D; // expected-warning {{warn-sign-conversion.cpp:13:5)' to 'int'}}
+ int d2a = 1 ? Foo<bool>::D : i; // expected-warning {{operand of ? changes signedness: 'test1::Foo<bool>::(anonymous enum at }}
+ int d2b = 1 ? Foo<bool>::D : i; // expected-warning {{warn-sign-conversion.cpp:13:5)' to 'int'}}
+ int d3a = 1 ? B : Foo<bool>::D; // expected-warning {{operand of ? changes signedness: 'test1::Foo<bool>::(anonymous enum at }}
+ int d3b = 1 ? B : Foo<bool>::D; // expected-warning {{warn-sign-conversion.cpp:13:5)' to 'int'}}
+ int d4a = 1 ? Foo<bool>::D : B; // expected-warning {{operand of ? changes signedness: 'test1::Foo<bool>::(anonymous enum at }}
+ int d4b = 1 ? Foo<bool>::D : B; // expected-warning {{warn-sign-conversion.cpp:13:5)' to 'int'}}
- int e1a = 1 ? i : E; // expected-warning {{operand of ? changes signedness: 'test1::<anonymous enum at }}
- int e1b = 1 ? i : E; // expected-warning {{warn-sign-conversion.cpp:16:3>' to 'int'}}
- int e2a = 1 ? E : i; // expected-warning {{operand of ? changes signedness: 'test1::<anonymous enum at }}
- int e2b = 1 ? E : i; // expected-warning {{warn-sign-conversion.cpp:16:3>' to 'int'}}
- int e3a = 1 ? E : B; // expected-warning {{operand of ? changes signedness: 'test1::<anonymous enum at }}
- int e3b = 1 ? E : B; // expected-warning {{warn-sign-conversion.cpp:16:3>' to 'int'}}
- int e4a = 1 ? B : E; // expected-warning {{operand of ? changes signedness: 'test1::<anonymous enum at }}
- int e4b = 1 ? B : E; // expected-warning {{warn-sign-conversion.cpp:16:3>' to 'int'}}
+ int e1a = 1 ? i : E; // expected-warning {{operand of ? changes signedness: 'test1::(anonymous enum at }}
+ int e1b = 1 ? i : E; // expected-warning {{warn-sign-conversion.cpp:16:3)' to 'int'}}
+ int e2a = 1 ? E : i; // expected-warning {{operand of ? changes signedness: 'test1::(anonymous enum at }}
+ int e2b = 1 ? E : i; // expected-warning {{warn-sign-conversion.cpp:16:3)' to 'int'}}
+ int e3a = 1 ? E : B; // expected-warning {{operand of ? changes signedness: 'test1::(anonymous enum at }}
+ int e3b = 1 ? E : B; // expected-warning {{warn-sign-conversion.cpp:16:3)' to 'int'}}
+ int e4a = 1 ? B : E; // expected-warning {{operand of ? changes signedness: 'test1::(anonymous enum at }}
+ int e4b = 1 ? B : E; // expected-warning {{warn-sign-conversion.cpp:16:3)' to 'int'}}
}
}
diff --git a/test/SemaCXX/warn-string-conversion.cpp b/test/SemaCXX/warn-string-conversion.cpp
index 23960e48df619..b26126f6c72f4 100644
--- a/test/SemaCXX/warn-string-conversion.cpp
+++ b/test/SemaCXX/warn-string-conversion.cpp
@@ -1,14 +1,20 @@
// RUN: %clang_cc1 -fsyntax-only -Wstring-conversion -verify %s
// Warn on cases where a string literal is converted into a bool.
-// An exception is made for this in logical operators.
+// An exception is made for this in logical and operators.
void assert(bool condition);
void test0() {
bool b0 = "hi"; // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
b0 = ""; // expected-warning{{implicit conversion turns string literal into bool: 'const char [1]' to 'bool'}}
+ b0 = 0 || ""; // expected-warning{{implicit conversion turns string literal into bool: 'const char [1]' to 'bool'}}
+ b0 = "" || 0; // expected-warning{{implicit conversion turns string literal into bool: 'const char [1]' to 'bool'}}
b0 = 0 && "";
+ b0 = "" && 0;
assert("error"); // expected-warning{{implicit conversion turns string literal into bool: 'const char [6]' to 'bool'}}
+ assert(0 || "error"); // expected-warning{{implicit conversion turns string literal into bool: 'const char [6]' to 'bool'}}
+ assert("error" || 0); // expected-warning{{implicit conversion turns string literal into bool: 'const char [6]' to 'bool'}}
assert(0 && "error");
+ assert("error" && 0);
while("hi") {} // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
do {} while("hi"); // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
diff --git a/test/SemaCXX/warn-sysheader-macro.cpp b/test/SemaCXX/warn-sysheader-macro.cpp
new file mode 100644
index 0000000000000..c88461720ad4d
--- /dev/null
+++ b/test/SemaCXX/warn-sysheader-macro.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -verify -fsyntax-only -Wshadow -Wold-style-cast %s
+
+// Test that macro expansions from system headers don't trigger 'syntactic'
+// warnings that are not actionable.
+
+#ifdef IS_SYSHEADER
+#pragma clang system_header
+
+#define SANITY(a) (a / 0)
+
+#define SHADOW(a) __extension__({ int v = a; v; })
+
+#define OLD_STYLE_CAST(a) ((int) (a))
+
+#else
+
+#define IS_SYSHEADER
+#include __FILE__
+
+void testSanity() {
+ // Validate that the test is set up correctly
+ int i = SANITY(0); // expected-warning {{division by zero is undefined}}
+}
+
+void PR16093() {
+ // no -Wshadow in system macro expansion
+ int i = SHADOW(SHADOW(1));
+}
+
+void PR18147() {
+ // no -Wold_style_cast in system macro expansion
+ int i = OLD_STYLE_CAST(0);
+}
+
+#endif
diff --git a/test/SemaCXX/warn-tautological-compare.cpp b/test/SemaCXX/warn-tautological-compare.cpp
new file mode 100644
index 0000000000000..b44f3f9d8fa34
--- /dev/null
+++ b/test/SemaCXX/warn-tautological-compare.cpp
@@ -0,0 +1,138 @@
+// Force x86-64 because some of our heuristics are actually based
+// on integer sizes.
+
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -verify -std=c++11 %s
+
+namespace RuntimeBehavior {
+ // Avoid emitting tautological compare warnings when the code already has
+ // compile time checks on variable sizes.
+
+ const int kintmax = 2147483647;
+ void test0(short x) {
+ if (sizeof(x) < sizeof(int) || x < kintmax) {}
+
+ if (x < kintmax) {}
+ // expected-warning@-1{{comparison of constant 2147483647 with expression of type 'short' is always true}}
+ }
+
+ void test1(short x) {
+ if (x < kintmax) {}
+ // expected-warning@-1{{comparison of constant 2147483647 with expression of type 'short' is always true}}
+
+ if (sizeof(x) < sizeof(int))
+ return;
+
+ if (x < kintmax) {}
+ }
+}
+
+namespace ArrayCompare {
+ #define GetValue(ptr) ((ptr != 0) ? ptr[0] : 0)
+ extern int a[] __attribute__((weak));
+ int b[] = {8,13,21};
+ struct {
+ int x[10];
+ } c;
+ const char str[] = "text";
+ void ignore() {
+ if (a == 0) {}
+ if (a != 0) {}
+ (void)GetValue(b);
+ }
+ void test() {
+ if (b == 0) {}
+ // expected-warning@-1{{comparison of array 'b' equal to a null pointer is always false}}
+ if (b != 0) {}
+ // expected-warning@-1{{comparison of array 'b' not equal to a null pointer is always true}}
+ if (0 == b) {}
+ // expected-warning@-1{{comparison of array 'b' equal to a null pointer is always false}}
+ if (0 != b) {}
+ // expected-warning@-1{{comparison of array 'b' not equal to a null pointer is always true}}
+ if (c.x == 0) {}
+ // expected-warning@-1{{comparison of array 'c.x' equal to a null pointer is always false}}
+ if (c.x != 0) {}
+ // expected-warning@-1{{comparison of array 'c.x' not equal to a null pointer is always true}}
+ if (str == 0) {}
+ // expected-warning@-1{{comparison of array 'str' equal to a null pointer is always false}}
+ if (str != 0) {}
+ // expected-warning@-1{{comparison of array 'str' not equal to a null pointer is always true}}
+ }
+}
+
+namespace FunctionCompare {
+ #define CallFunction(f) ((f != 0) ? f() : 0)
+ extern void a() __attribute__((weak));
+ void fun1();
+ int fun2();
+ int* fun3();
+ int* fun4(int);
+ class S {
+ public:
+ static int foo();
+ };
+ void ignore() {
+ if (a == 0) {}
+ if (0 != a) {}
+ (void)CallFunction(fun2);
+ }
+ void test() {
+ if (fun1 == 0) {}
+ // expected-warning@-1{{comparison of function 'fun1' equal to a null pointer is always false}}
+ // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+ if (fun2 == 0) {}
+ // expected-warning@-1{{comparison of function 'fun2' equal to a null pointer is always false}}
+ // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+ // expected-note@-3{{suffix with parentheses to turn this into a function call}}
+ if (fun3 == 0) {}
+ // expected-warning@-1{{comparison of function 'fun3' equal to a null pointer is always false}}
+ // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+ // expected-note@-3{{suffix with parentheses to turn this into a function call}}
+ if (fun4 == 0) {}
+ // expected-warning@-1{{comparison of function 'fun4' equal to a null pointer is always false}}
+ // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+ if (nullptr != fun1) {}
+ // expected-warning@-1{{comparison of function 'fun1' not equal to a null pointer is always true}}
+ // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+ if (nullptr != fun2) {}
+ // expected-warning@-1{{comparison of function 'fun2' not equal to a null pointer is always true}}
+ // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+ if (nullptr != fun3) {}
+ // expected-warning@-1{{comparison of function 'fun3' not equal to a null pointer is always true}}
+ // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+ // expected-note@-3{{suffix with parentheses to turn this into a function call}}
+ if (nullptr != fun4) {}
+ // expected-warning@-1{{comparison of function 'fun4' not equal to a null pointer is always true}}
+ // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+ if (S::foo == 0) {}
+ // expected-warning@-1{{comparison of function 'S::foo' equal to a null pointer is always false}}
+ // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+ // expected-note@-3{{suffix with parentheses to turn this into a function call}}
+ }
+}
+
+namespace PointerCompare {
+ extern int a __attribute__((weak));
+ int b;
+ static int c;
+ class S {
+ public:
+ static int a;
+ int b;
+ };
+ void ignored() {
+ if (&a == 0) {}
+ }
+ void test() {
+ S s;
+ if (&b == 0) {}
+ // expected-warning@-1{{comparison of address of 'b' equal to a null pointer is always false}}
+ if (&c == 0) {}
+ // expected-warning@-1{{comparison of address of 'c' equal to a null pointer is always false}}
+ if (&s.a == 0) {}
+ // expected-warning@-1{{comparison of address of 's.a' equal to a null pointer is always false}}
+ if (&s.b == 0) {}
+ // expected-warning@-1{{comparison of address of 's.b' equal to a null pointer is always false}}
+ if (&S::a == 0) {}
+ // expected-warning@-1{{comparison of address of 'S::a' equal to a null pointer is always false}}
+ }
+}
diff --git a/test/SemaCXX/warn-tautological-undefined-compare.cpp b/test/SemaCXX/warn-tautological-undefined-compare.cpp
new file mode 100644
index 0000000000000..ce05bfc14d170
--- /dev/null
+++ b/test/SemaCXX/warn-tautological-undefined-compare.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wtautological-undefined-compare %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-tautological-compare -Wtautological-undefined-compare %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wtautological-compare %s
+
+void test1(int &x) {
+ if (x == 1) { }
+ if (&x == 0) { }
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+ if (&x != 0) { }
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+}
+
+class test2 {
+ test2() : x(y) {}
+
+ void foo() {
+ if (this == 0) { }
+ // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+ if (this != 0) { }
+ // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+ }
+
+ void bar() {
+ if (x == 1) { }
+ if (&x == 0) { }
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+ if (&x != 0) { }
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+ }
+
+ int &x;
+ int y;
+};
+
+namespace function_return_reference {
+ int& get_int();
+ // expected-note@-1 4{{'get_int' returns a reference}}
+ class B {
+ public:
+ static int &stat();
+ // expected-note@-1 4{{'stat' returns a reference}}
+ int &get();
+ // expected-note@-1 8{{'get' returns a reference}}
+ };
+
+ void test() {
+ if (&get_int() == 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+ if (&(get_int()) == 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+
+ if (&get_int() != 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+ if (&(get_int()) != 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+
+ if (&B::stat() == 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+ if (&(B::stat()) == 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+
+ if (&B::stat() != 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+ if (&(B::stat()) != 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+
+ B b;
+ if (&b.get() == 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+ if (&(b.get()) == 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+
+ if (&b.get() != 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+ if (&(b.get()) != 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+
+ B* b_ptr = &b;
+ if (&b_ptr->get() == 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+ if (&(b_ptr->get()) == 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+
+ if (&b_ptr->get() != 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+ if (&(b_ptr->get()) != 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+
+ int& (B::*m_ptr)() = &B::get;
+ if (&(b.*m_ptr)() == 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+ if (&((b.*m_ptr)()) == 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+
+ if (&(b.*m_ptr)() != 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+ if (&((b.*m_ptr)()) != 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+
+ int& (*f_ptr)() = &get_int;
+ if (&(*f_ptr)() == 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+ if (&((*f_ptr)()) == 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+
+ if (&(*f_ptr)() != 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+ if (&((*f_ptr)()) != 0) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+ }
+}
diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp
index ce6250d6da905..34a33aab42d26 100644
--- a/test/SemaCXX/warn-thread-safety-analysis.cpp
+++ b/test/SemaCXX/warn-thread-safety-analysis.cpp
@@ -208,33 +208,33 @@ void sls_fun_good_8() {
void sls_fun_bad_1() {
sls_mu.Unlock(); // \
- // expected-warning{{unlocking 'sls_mu' that was not locked}}
+ // expected-warning{{releasing mutex 'sls_mu' that was not held}}
}
void sls_fun_bad_2() {
sls_mu.Lock();
sls_mu.Lock(); // \
- // expected-warning{{locking 'sls_mu' that is already locked}}
+ // expected-warning{{acquiring mutex 'sls_mu' that is already held}}
sls_mu.Unlock();
}
void sls_fun_bad_3() {
sls_mu.Lock(); // expected-note {{mutex acquired here}}
-} // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
+} // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
void sls_fun_bad_4() {
if (getBool())
sls_mu.Lock(); // expected-note{{mutex acquired here}}
else
sls_mu2.Lock(); // expected-note{{mutex acquired here}}
-} // expected-warning{{mutex 'sls_mu' is not locked on every path through here}} \
- // expected-warning{{mutex 'sls_mu2' is not locked on every path through here}}
+} // expected-warning{{mutex 'sls_mu' is not held on every path through here}} \
+ // expected-warning{{mutex 'sls_mu2' is not held on every path through here}}
void sls_fun_bad_5() {
sls_mu.Lock(); // expected-note {{mutex acquired here}}
if (getBool())
sls_mu.Unlock();
-} // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
+} // expected-warning{{mutex 'sls_mu' is not held on every path through here}}
void sls_fun_bad_6() {
if (getBool()) {
@@ -247,8 +247,8 @@ void sls_fun_bad_6() {
}
}
sls_mu.Unlock(); // \
- expected-warning{{mutex 'sls_mu' is not locked on every path through here}}\
- expected-warning{{unlocking 'sls_mu' that was not locked}}
+ expected-warning{{mutex 'sls_mu' is not held on every path through here}}\
+ expected-warning{{releasing mutex 'sls_mu' that was not held}}
}
void sls_fun_bad_7() {
@@ -258,7 +258,7 @@ void sls_fun_bad_7() {
if (getBool()) {
if (getBool()) {
continue; // \
- expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+ expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
}
}
sls_mu.Lock(); // expected-note {{mutex acquired here}}
@@ -270,14 +270,14 @@ void sls_fun_bad_8() {
sls_mu.Lock(); // expected-note{{mutex acquired here}}
do {
- sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+ sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
} while (getBool());
}
void sls_fun_bad_9() {
do {
sls_mu.Lock(); // \
- // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} \
+ // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}} \
// expected-note{{mutex acquired here}}
} while (getBool());
sls_mu.Unlock();
@@ -285,18 +285,18 @@ void sls_fun_bad_9() {
void sls_fun_bad_10() {
sls_mu.Lock(); // expected-note 2{{mutex acquired here}}
- while(getBool()) { // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+ while(getBool()) { // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
sls_mu.Unlock();
}
-} // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
+} // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
void sls_fun_bad_11() {
while (getBool()) { // \
- expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+ expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
sls_mu.Lock(); // expected-note {{mutex acquired here}}
}
sls_mu.Unlock(); // \
- // expected-warning{{unlocking 'sls_mu' that was not locked}}
+ // expected-warning{{releasing mutex 'sls_mu' that was not held}}
}
void sls_fun_bad_12() {
@@ -305,7 +305,7 @@ void sls_fun_bad_12() {
sls_mu.Unlock();
if (getBool()) {
if (getBool()) {
- break; // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
+ break; // expected-warning{{mutex 'sls_mu' is not held on every path through here}}
}
}
sls_mu.Lock();
@@ -334,19 +334,19 @@ void aa_fun_1() {
void aa_fun_bad_1() {
glock.globalUnlock(); // \
- // expected-warning{{unlocking 'aa_mu' that was not locked}}
+ // expected-warning{{releasing mutex 'aa_mu' that was not held}}
}
void aa_fun_bad_2() {
glock.globalLock();
glock.globalLock(); // \
- // expected-warning{{locking 'aa_mu' that is already locked}}
+ // expected-warning{{acquiring mutex 'aa_mu' that is already held}}
glock.globalUnlock();
}
void aa_fun_bad_3() {
glock.globalLock(); // expected-note{{mutex acquired here}}
-} // expected-warning{{mutex 'aa_mu' is still locked at the end of function}}
+} // expected-warning{{mutex 'aa_mu' is still held at the end of function}}
//--------------------------------------------------//
// Regression tests for unusual method names
@@ -359,17 +359,17 @@ class WeirdMethods {
// FIXME: can't currently check inside constructors and destructors.
WeirdMethods() {
wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
- } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}}
+ } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}
~WeirdMethods() {
wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
- } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}}
+ } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}
void operator++() {
wmu.Lock(); // expected-note {{mutex acquired here}}
- } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
+ } // expected-warning {{mutex 'wmu' is still held at the end of function}}
operator int*() {
wmu.Lock(); // expected-note {{mutex acquired here}}
return 0;
- } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
+ } // expected-warning {{mutex 'wmu' is still held at the end of function}}
};
//-----------------------------------------------//
@@ -386,13 +386,13 @@ class PGBFoo {
__attribute__((pt_guarded_by(sls_mu)));
void testFoo() {
pgb_field = &x; // \
- // expected-warning {{writing variable 'pgb_field' requires locking 'sls_mu2' exclusively}}
- *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
- // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
- x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
- // expected-warning {{reading the value pointed to by 'pgb_field' requires locking 'sls_mu'}}
- (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
- // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
+ // expected-warning {{writing variable 'pgb_field' requires holding mutex 'sls_mu2' exclusively}}
+ *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
+ // expected-warning {{writing the value pointed to by 'pgb_field' requires holding mutex 'sls_mu' exclusively}}
+ x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
+ // expected-warning {{reading the value pointed to by 'pgb_field' requires holding mutex 'sls_mu'}}
+ (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
+ // expected-warning {{writing the value pointed to by 'pgb_field' requires holding mutex 'sls_mu' exclusively}}
}
};
@@ -402,7 +402,7 @@ class GBFoo {
void testFoo() {
gb_field = 0; // \
- // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu' exclusively}}
+ // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu' exclusively}}
}
void testNoAnal() __attribute__((no_thread_safety_analysis)) {
@@ -435,59 +435,59 @@ void gb_fun_3() {
void gb_bad_0() {
sls_guard_var = 1; // \
- // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
+ // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
}
void gb_bad_1() {
int x = sls_guard_var; // \
- // expected-warning{{reading variable 'sls_guard_var' requires locking any mutex}}
+ // expected-warning{{reading variable 'sls_guard_var' requires holding any mutex}}
}
void gb_bad_2() {
sls_guardby_var = 1; // \
- // expected-warning {{writing variable 'sls_guardby_var' requires locking 'sls_mu' exclusively}}
+ // expected-warning {{writing variable 'sls_guardby_var' requires holding mutex 'sls_mu' exclusively}}
}
void gb_bad_3() {
int x = sls_guardby_var; // \
- // expected-warning {{reading variable 'sls_guardby_var' requires locking 'sls_mu'}}
+ // expected-warning {{reading variable 'sls_guardby_var' requires holding mutex 'sls_mu'}}
}
void gb_bad_4() {
*pgb_gvar = 1; // \
- // expected-warning {{writing the value pointed to by 'pgb_gvar' requires locking any mutex exclusively}}
+ // expected-warning {{writing the value pointed to by 'pgb_gvar' requires holding any mutex exclusively}}
}
void gb_bad_5() {
int x = *pgb_gvar; // \
- // expected-warning {{reading the value pointed to by 'pgb_gvar' requires locking any mutex}}
+ // expected-warning {{reading the value pointed to by 'pgb_gvar' requires holding any mutex}}
}
void gb_bad_6() {
*pgb_var = 1; // \
- // expected-warning {{writing the value pointed to by 'pgb_var' requires locking 'sls_mu' exclusively}}
+ // expected-warning {{writing the value pointed to by 'pgb_var' requires holding mutex 'sls_mu' exclusively}}
}
void gb_bad_7() {
int x = *pgb_var; // \
- // expected-warning {{reading the value pointed to by 'pgb_var' requires locking 'sls_mu'}}
+ // expected-warning {{reading the value pointed to by 'pgb_var' requires holding mutex 'sls_mu'}}
}
void gb_bad_8() {
GBFoo G;
G.gb_field = 0; // \
- // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu'}}
+ // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu'}}
}
void gb_bad_9() {
sls_guard_var++; // \
- // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
+ // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
sls_guard_var--; // \
- // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
+ // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
++sls_guard_var; // \
- // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
+ // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
--sls_guard_var;// \
- // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
+ // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
}
//-----------------------------------------------//
@@ -503,11 +503,11 @@ public:
void test() {
a = 0; // \
- // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
+ // expected-warning{{writing variable 'a' requires holding mutex 'mu' exclusively}}
b = a; // \
- // expected-warning {{reading variable 'a' requires locking 'mu'}}
+ // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
c = 0; // \
- // expected-warning {{writing variable 'c' requires locking 'mu' exclusively}}
+ // expected-warning {{writing variable 'c' requires holding mutex 'mu' exclusively}}
}
int c __attribute__((guarded_by(mu)));
@@ -549,7 +549,7 @@ void late_bad_0() {
LateFoo fooB;
fooA.mu.Lock();
fooB.a = 5; // \
- // expected-warning{{writing variable 'a' requires locking 'fooB.mu' exclusively}} \
+ // expected-warning{{writing variable 'a' requires holding mutex 'fooB.mu' exclusively}} \
// expected-note{{found near match 'fooA.mu'}}
fooA.mu.Unlock();
}
@@ -560,7 +560,7 @@ void late_bad_1() {
b1.mu1_.Lock();
int res = b1.a_ + b3->b_;
b3->b_ = *b1.q; // \
- // expected-warning{{reading the value pointed to by 'q' requires locking 'b1.mu'}}
+ // expected-warning{{reading the value pointed to by 'q' requires holding mutex 'b1.mu'}}
b1.mu1_.Unlock();
b1.b_ = res;
mu.Unlock();
@@ -570,7 +570,7 @@ void late_bad_2() {
LateBar BarA;
BarA.FooPointer->mu.Lock();
BarA.Foo.a = 2; // \
- // expected-warning{{writing variable 'a' requires locking 'BarA.Foo.mu' exclusively}} \
+ // expected-warning{{writing variable 'a' requires holding mutex 'BarA.Foo.mu' exclusively}} \
// expected-note{{found near match 'BarA.FooPointer->mu'}}
BarA.FooPointer->mu.Unlock();
}
@@ -579,7 +579,7 @@ void late_bad_3() {
LateBar BarA;
BarA.Foo.mu.Lock();
BarA.FooPointer->a = 2; // \
- // expected-warning{{writing variable 'a' requires locking 'BarA.FooPointer->mu' exclusively}} \
+ // expected-warning{{writing variable 'a' requires holding mutex 'BarA.FooPointer->mu' exclusively}} \
// expected-note{{found near match 'BarA.Foo.mu'}}
BarA.Foo.mu.Unlock();
}
@@ -588,7 +588,7 @@ void late_bad_4() {
LateBar BarA;
BarA.Foo.mu.Lock();
BarA.Foo2.a = 2; // \
- // expected-warning{{writing variable 'a' requires locking 'BarA.Foo2.mu' exclusively}} \
+ // expected-warning{{writing variable 'a' requires holding mutex 'BarA.Foo2.mu' exclusively}} \
// expected-note{{found near match 'BarA.Foo.mu'}}
BarA.Foo.mu.Unlock();
}
@@ -608,11 +608,11 @@ void shared_fun_0() {
void shared_fun_1() {
sls_mu.ReaderLock(); // \
- // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
+ // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
do {
sls_mu.Unlock();
sls_mu.Lock(); // \
- // expected-note {{the other lock of mutex 'sls_mu' is here}}
+ // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
} while (getBool());
sls_mu.Unlock();
}
@@ -638,20 +638,20 @@ void shared_fun_4() {
void shared_fun_8() {
if (getBool())
sls_mu.Lock(); // \
- // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
+ // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
else
sls_mu.ReaderLock(); // \
- // expected-note {{the other lock of mutex 'sls_mu' is here}}
+ // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
sls_mu.Unlock();
}
void shared_bad_0() {
sls_mu.Lock(); // \
- // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
+ // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
do {
sls_mu.Unlock();
sls_mu.ReaderLock(); // \
- // expected-note {{the other lock of mutex 'sls_mu' is here}}
+ // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
} while (getBool());
sls_mu.Unlock();
}
@@ -659,10 +659,10 @@ void shared_bad_0() {
void shared_bad_1() {
if (getBool())
sls_mu.Lock(); // \
- // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
+ // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
else
sls_mu.ReaderLock(); // \
- // expected-note {{the other lock of mutex 'sls_mu' is here}}
+ // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
*pgb_var = 1;
sls_mu.Unlock();
}
@@ -670,10 +670,10 @@ void shared_bad_1() {
void shared_bad_2() {
if (getBool())
sls_mu.ReaderLock(); // \
- // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
+ // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
else
sls_mu.Lock(); // \
- // expected-note {{the other lock of mutex 'sls_mu' is here}}
+ // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
*pgb_var = 1;
sls_mu.Unlock();
}
@@ -762,49 +762,49 @@ void es_fun_10() {
void es_bad_0() {
Bar.aa_elr_fun(); // \
- // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
+ // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}
}
void es_bad_1() {
aa_mu.ReaderLock();
Bar.aa_elr_fun(); // \
- // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
+ // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}
aa_mu.Unlock();
}
void es_bad_2() {
Bar.aa_elr_fun_s(); // \
- // expected-warning {{calling function 'aa_elr_fun_s' requires shared lock on 'aa_mu'}}
+ // expected-warning {{calling function 'aa_elr_fun_s' requires holding mutex 'aa_mu'}}
}
void es_bad_3() {
MyLRFoo.test(); // \
- // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
+ // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}
}
void es_bad_4() {
MyLRFoo.testShared(); // \
- // expected-warning {{calling function 'testShared' requires shared lock on 'sls_mu2'}}
+ // expected-warning {{calling function 'testShared' requires holding mutex 'sls_mu2'}}
}
void es_bad_5() {
sls_mu.ReaderLock();
MyLRFoo.test(); // \
- // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
+ // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}
sls_mu.Unlock();
}
void es_bad_6() {
sls_mu.Lock();
Bar.le_fun(); // \
- // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
+ // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}
sls_mu.Unlock();
}
void es_bad_7() {
sls_mu.ReaderLock();
Bar.le_fun(); // \
- // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
+ // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}
sls_mu.Unlock();
}
@@ -1209,7 +1209,7 @@ void Foo::bar()
{
int x;
mu_.Lock();
- x = foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'mu2'}}
+ x = foo(); // expected-warning {{calling function 'foo' requires holding mutex 'mu2' exclusively}}
a_ = x + 1;
mu_.Unlock();
if (x > 5) {
@@ -1223,13 +1223,13 @@ void main()
{
Foo f1, *f2;
f1.mu_.Lock();
- f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is locked}}
+ f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is held}}
mu2.Lock();
f1.foo();
mu2.Unlock();
f1.mu_.Unlock();
f2->mu_.Lock();
- f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is locked}}
+ f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is held}}
f2->mu_.Unlock();
mu2.Lock();
w = 2;
@@ -1258,7 +1258,7 @@ void func()
b1->MyLock();
b1->a_ = 5;
b2->a_ = 3; // \
- // expected-warning {{writing variable 'a_' requires locking 'b2->mu1_' exclusively}} \
+ // expected-warning {{writing variable 'a_' requires holding mutex 'b2->mu1_' exclusively}} \
// expected-note {{found near match 'b1->mu1_'}}
b2->MyLock();
b2->MyUnlock();
@@ -1288,18 +1288,18 @@ int func(int i)
{
int x;
b3->mu1_.Lock();
- res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking 'b1.mu1_'}} \
- // expected-warning {{writing variable 'res' requires locking 'mu' exclusively}} \
+ res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires holding mutex 'b1.mu1_'}} \
+ // expected-warning {{writing variable 'res' requires holding mutex 'mu' exclusively}} \
// expected-note {{found near match 'b3->mu1_'}}
- *p = i; // expected-warning {{reading variable 'p' requires locking 'mu'}} \
- // expected-warning {{writing the value pointed to by 'p' requires locking 'mu' exclusively}}
- b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires locking 'mu'}} \
- // expected-warning {{writing variable 'a_' requires locking 'b1.mu1_' exclusively}} \
+ *p = i; // expected-warning {{reading variable 'p' requires holding mutex 'mu'}} \
+ // expected-warning {{writing the value pointed to by 'p' requires holding mutex 'mu' exclusively}}
+ b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}} \
+ // expected-warning {{writing variable 'a_' requires holding mutex 'b1.mu1_' exclusively}} \
// expected-note {{found near match 'b3->mu1_'}}
- b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires locking 'mu'}}
+ b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires holding mutex 'mu'}}
b3->mu1_.Unlock();
- b1.b_ = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
- x = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
+ b1.b_ = res; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}}
+ x = res; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}}
return x;
}
} // end namespace thread_annot_lock_21
@@ -1321,10 +1321,10 @@ class Foo {
child->Func(new_foo); // There shouldn't be any warning here as the
// acquired lock is not in child.
child->bar(7); // \
- // expected-warning {{calling function 'bar' requires exclusive lock on 'child->lock_'}} \
+ // expected-warning {{calling function 'bar' requires holding mutex 'child->lock_' exclusively}} \
// expected-note {{found near match 'lock_'}}
child->a_ = 5; // \
- // expected-warning {{writing variable 'a_' requires locking 'child->lock_' exclusively}} \
+ // expected-warning {{writing variable 'a_' requires holding mutex 'child->lock_' exclusively}} \
// expected-note {{found near match 'lock_'}}
lock_.Unlock();
}
@@ -1362,7 +1362,7 @@ void Foo::Func(Foo* child) {
lock_.Lock();
child->lock_.Lock();
- child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is locked}}
+ child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is held}}
child->bar(7);
child->a_ = 5;
child->lock_.Unlock();
@@ -1401,8 +1401,8 @@ class Foo {
public:
void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
x = 5;
- f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is locked}} \
- // expected-warning {{cannot call function 'f2' while mutex 'mu2' is locked}}
+ f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is held}} \
+ // expected-warning {{cannot call function 'f2' while mutex 'mu2' is held}}
}
};
@@ -1410,8 +1410,8 @@ Foo *foo;
void func()
{
- foo->f1(); // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu2'}} \
- // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu1'}}
+ foo->f1(); // expected-warning {{calling function 'f1' requires holding mutex 'foo->mu2' exclusively}} \
+ // expected-warning {{calling function 'f1' requires holding mutex 'foo->mu1' exclusively}}
}
} // end namespace thread_annot_lock_42
@@ -1434,14 +1434,14 @@ void main() {
Child *c;
Base *b = c;
- b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'b->mu_'}}
+ b->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'b->mu_' exclusively}}
b->mu_.Lock();
- b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is locked}}
+ b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is held}}
b->mu_.Unlock();
- c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'c->mu_'}}
+ c->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'c->mu_' exclusively}}
c->mu_.Lock();
- c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is locked}}
+ c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is held}}
c->mu_.Unlock();
}
} // end namespace thread_annot_lock_46
@@ -1468,10 +1468,10 @@ int Foo::method1(int i) {
void main()
{
Foo a;
- a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on 'a.mu1'}} \
- // expected-warning {{calling function 'method1' requires shared lock on 'mu'}} \
- // expected-warning {{calling function 'method1' requires shared lock on 'a.mu2'}} \
- // expected-warning {{calling function 'method1' requires shared lock on 'mu3'}}
+ a.method1(1); // expected-warning {{calling function 'method1' requires holding mutex 'a.mu1'}} \
+ // expected-warning {{calling function 'method1' requires holding mutex 'mu'}} \
+ // expected-warning {{calling function 'method1' requires holding mutex 'a.mu2'}} \
+ // expected-warning {{calling function 'method1' requires holding mutex 'mu3'}}
}
} // end namespace thread_annot_lock_67_modified
@@ -1516,14 +1516,14 @@ namespace substitution_test {
DataLocker dlr;
dlr.lockData(d1); // expected-note {{mutex acquired here}}
dlr.unlockData(d2); // \
- // expected-warning {{unlocking 'd2->mu' that was not locked}}
- } // expected-warning {{mutex 'd1->mu' is still locked at the end of function}}
+ // expected-warning {{releasing mutex 'd2->mu' that was not held}}
+ } // expected-warning {{mutex 'd1->mu' is still held at the end of function}}
void bar4(MyData* d1, MyData* d2) {
DataLocker dlr;
dlr.lockData(d1);
foo(d2); // \
- // expected-warning {{calling function 'foo' requires exclusive lock on 'd2->mu'}} \
+ // expected-warning {{calling function 'foo' requires holding mutex 'd2->mu' exclusively}} \
// expected-note {{found near match 'd1->mu'}}
dlr.unlockData(d1);
}
@@ -1566,8 +1566,8 @@ namespace template_member_test {
template<typename U>
struct IndirectLock {
int DoNaughtyThings(T *t) {
- u->n = 0; // expected-warning {{reading variable 'u' requires locking 'm'}}
- return t->s->n; // expected-warning {{reading variable 's' requires locking 't->m'}}
+ u->n = 0; // expected-warning {{reading variable 'u' requires holding mutex 'm'}}
+ return t->s->n; // expected-warning {{reading variable 's' requires holding mutex 't->m'}}
}
};
@@ -1583,7 +1583,7 @@ namespace template_member_test {
template<typename U> struct W {
V v;
void f(U u) {
- v.p->f(u); // expected-warning {{reading variable 'p' requires locking 'v.m'}}
+ v.p->f(u); // expected-warning {{reading variable 'p' requires holding mutex 'v.m'}}
}
};
template struct W<int>; // expected-note {{here}}
@@ -1620,7 +1620,7 @@ struct TestScopedLockable {
void foo3() {
MutexLock mulock_a(&mu1);
MutexLock mulock_b(&mu1); // \
- // expected-warning {{locking 'mu1' that is already locked}}
+ // expected-warning {{acquiring mutex 'mu1' that is already held}}
}
void foo4() {
@@ -1646,7 +1646,7 @@ Foo fooObj;
void foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_);
void bar() {
- foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'fooObj.mu_'}}
+ foo(); // expected-warning {{calling function 'foo' requires holding mutex 'fooObj.mu_' exclusively}}
fooObj.mu_.Lock();
foo();
fooObj.mu_.Unlock();
@@ -1722,7 +1722,7 @@ struct TestTryLock {
if (cond)
b = true;
if (b) { // b should be unknown at this point, because of the join point
- a = 8; // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
+ a = 8; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
}
if (b2) { // b2 should be known at this point.
a = 8;
@@ -1748,7 +1748,7 @@ struct TestTryLock {
while (cond) {
if (b) { // b should be uknown at this point b/c of the loop
- a = 10; // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
+ a = 10; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
}
b = !b;
}
@@ -1876,7 +1876,7 @@ void test() {
f1.mu_.Unlock();
bt.barTD(&f1); // \
- // expected-warning {{calling function 'barTD' requires exclusive lock on 'f1.mu_'}} \
+ // expected-warning {{calling function 'barTD' requires holding mutex 'f1.mu_' exclusively}} \
// expected-note {{found near match 'bt.fooBase.mu_'}}
bt.fooBase.mu_.Unlock();
@@ -1885,7 +1885,7 @@ void test() {
Cell<int> cell;
cell.data = 0; // \
- // expected-warning {{writing variable 'data' requires locking 'cell.mu_' exclusively}}
+ // expected-warning {{writing variable 'data' requires holding mutex 'cell.mu_' exclusively}}
cell.foo();
cell.mu_.Lock();
cell.fooEx();
@@ -1954,7 +1954,7 @@ void Foo::foo1(Foo *f_defined) {
void test() {
Foo myfoo;
myfoo.foo1(&myfoo); // \
- // expected-warning {{calling function 'foo1' requires exclusive lock on 'myfoo.mu_'}}
+ // expected-warning {{calling function 'foo1' requires holding mutex 'myfoo.mu_' exclusively}}
myfoo.mu_.Lock();
myfoo.foo1(&myfoo);
myfoo.mu_.Unlock();
@@ -1980,7 +1980,7 @@ namespace GoingNative {
if (bar()) {
// ...
if (foo())
- continue; // expected-warning {{expecting mutex 'm' to be locked at start of each loop}}
+ continue; // expected-warning {{expecting mutex 'm' to be held at start of each loop}}
//...
}
// ...
@@ -2069,21 +2069,21 @@ void test() {
Foo myFoo;
myFoo.foo2(); // \
- // expected-warning {{calling function 'foo2' requires exclusive lock on 'myFoo.mu_'}}
+ // expected-warning {{calling function 'foo2' requires holding mutex 'myFoo.mu_' exclusively}}
myFoo.foo3(&myFoo); // \
- // expected-warning {{calling function 'foo3' requires exclusive lock on 'myFoo.mu_'}}
+ // expected-warning {{calling function 'foo3' requires holding mutex 'myFoo.mu_' exclusively}}
myFoo.fooT1(dummy); // \
- // expected-warning {{calling function 'fooT1' requires exclusive lock on 'myFoo.mu_'}}
+ // expected-warning {{calling function 'fooT1' requires holding mutex 'myFoo.mu_' exclusively}}
myFoo.fooT2(dummy); // \
- // expected-warning {{calling function 'fooT2' requires exclusive lock on 'myFoo.mu_'}}
+ // expected-warning {{calling function 'fooT2' requires holding mutex 'myFoo.mu_' exclusively}}
fooF1(&myFoo); // \
- // expected-warning {{calling function 'fooF1' requires exclusive lock on 'myFoo.mu_'}}
+ // expected-warning {{calling function 'fooF1' requires holding mutex 'myFoo.mu_' exclusively}}
fooF2(&myFoo); // \
- // expected-warning {{calling function 'fooF2' requires exclusive lock on 'myFoo.mu_'}}
+ // expected-warning {{calling function 'fooF2' requires holding mutex 'myFoo.mu_' exclusively}}
fooF3(&myFoo); // \
- // expected-warning {{calling function 'fooF3' requires exclusive lock on 'myFoo.mu_'}}
+ // expected-warning {{calling function 'fooF3' requires holding mutex 'myFoo.mu_' exclusively}}
myFoo.mu_.Lock();
myFoo.foo2();
@@ -2099,7 +2099,7 @@ void test() {
FooT<int> myFooT;
myFooT.foo(); // \
- // expected-warning {{calling function 'foo' requires exclusive lock on 'myFooT.mu_'}}
+ // expected-warning {{calling function 'foo' requires holding mutex 'myFooT.mu_' exclusively}}
}
} // end namespace FunctionDefinitionTest
@@ -2127,7 +2127,7 @@ public:
void test() {
foo = 2; // \
- // expected-warning {{writing variable 'foo' requires locking 'this' exclusively}}
+ // expected-warning {{writing variable 'foo' requires holding mutex 'this' exclusively}}
}
};
@@ -2192,11 +2192,11 @@ public:
void foo() {
a = 0; // \
- // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
b = 0; // \
- // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
+ // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
c = 0; // \
- // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}}
+ // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
}
private:
@@ -2283,31 +2283,31 @@ void test() {
bar.getFoo().mu_.Lock();
bar.getFooey().a = 0; // \
- // expected-warning {{writing variable 'a' requires locking 'bar.getFooey().mu_' exclusively}} \
+ // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFooey().mu_' exclusively}} \
// expected-note {{found near match 'bar.getFoo().mu_'}}
bar.getFoo().mu_.Unlock();
bar.getFoo2(a).mu_.Lock();
bar.getFoo2(b).a = 0; // \
- // expected-warning {{writing variable 'a' requires locking 'bar.getFoo2(b).mu_' exclusively}} \
+ // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFoo2(b).mu_' exclusively}} \
// expected-note {{found near match 'bar.getFoo2(a).mu_'}}
bar.getFoo2(a).mu_.Unlock();
bar.getFoo3(a, b).mu_.Lock();
bar.getFoo3(a, c).a = 0; // \
- // expected-warning {{writing variable 'a' requires locking 'bar.getFoo3(a,c).mu_' exclusively}} \
+ // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFoo3(a,c).mu_' exclusively}} \
// expected-note {{'bar.getFoo3(a,b).mu_'}}
bar.getFoo3(a, b).mu_.Unlock();
getBarFoo(bar, a).mu_.Lock();
getBarFoo(bar, b).a = 0; // \
- // expected-warning {{writing variable 'a' requires locking 'getBarFoo(bar,b).mu_' exclusively}} \
+ // expected-warning {{writing variable 'a' requires holding mutex 'getBarFoo(bar,b).mu_' exclusively}} \
// expected-note {{'getBarFoo(bar,a).mu_'}}
getBarFoo(bar, a).mu_.Unlock();
(a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
(a > 0 ? fooArray[b] : fooArray[c]).a = 0; // \
- // expected-warning {{writing variable 'a' requires locking '((a#_)#_#fooArray[b]).mu_' exclusively}} \
+ // expected-warning {{writing variable 'a' requires holding mutex '((a#_)#_#fooArray[b]).mu_' exclusively}} \
// expected-note {{'((a#_)#_#fooArray[_]).mu_'}}
(a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
}
@@ -2356,19 +2356,19 @@ public:
// Calls getMu() directly to lock and unlock
void test1(Foo* f1, Foo* f2) {
- f1->a = 0; // expected-warning {{writing variable 'a' requires locking 'f1->mu_' exclusively}}
- f1->foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'f1->mu_'}}
+ f1->a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'f1->mu_' exclusively}}
+ f1->foo(); // expected-warning {{calling function 'foo' requires holding mutex 'f1->mu_' exclusively}}
- f1->foo2(f2); // expected-warning {{calling function 'foo2' requires exclusive lock on 'f1->mu_'}} \
- // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}}
- Foo::sfoo(f1); // expected-warning {{calling function 'sfoo' requires exclusive lock on 'f1->mu_'}}
+ f1->foo2(f2); // expected-warning {{calling function 'foo2' requires holding mutex 'f1->mu_' exclusively}} \
+ // expected-warning {{calling function 'foo2' requires holding mutex 'f2->mu_' exclusively}}
+ Foo::sfoo(f1); // expected-warning {{calling function 'sfoo' requires holding mutex 'f1->mu_' exclusively}}
f1->getMu()->Lock();
f1->a = 0;
f1->foo();
f1->foo2(f2); // \
- // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}} \
+ // expected-warning {{calling function 'foo2' requires holding mutex 'f2->mu_' exclusively}} \
// expected-note {{found near match 'f1->mu_'}}
Foo::getMu(f2)->Lock();
@@ -2398,19 +2398,19 @@ public:
// Use getMu() within other attributes.
// This requires at lest levels of substitution, more in the case of
void test2(Bar* b1, Bar* b2) {
- b1->b = 0; // expected-warning {{writing variable 'b' requires locking 'b1->mu_' exclusively}}
- b1->bar(); // expected-warning {{calling function 'bar' requires exclusive lock on 'b1->mu_'}}
- b1->bar2(b2); // expected-warning {{calling function 'bar2' requires exclusive lock on 'b1->mu_'}} \
- // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}}
- Bar::sbar(b1); // expected-warning {{calling function 'sbar' requires exclusive lock on 'b1->mu_'}}
- Bar::sbar2(b1); // expected-warning {{calling function 'sbar2' requires exclusive lock on 'b1->mu_'}}
+ b1->b = 0; // expected-warning {{writing variable 'b' requires holding mutex 'b1->mu_' exclusively}}
+ b1->bar(); // expected-warning {{calling function 'bar' requires holding mutex 'b1->mu_' exclusively}}
+ b1->bar2(b2); // expected-warning {{calling function 'bar2' requires holding mutex 'b1->mu_' exclusively}} \
+ // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}}
+ Bar::sbar(b1); // expected-warning {{calling function 'sbar' requires holding mutex 'b1->mu_' exclusively}}
+ Bar::sbar2(b1); // expected-warning {{calling function 'sbar2' requires holding mutex 'b1->mu_' exclusively}}
b1->getMu()->Lock();
b1->b = 0;
b1->bar();
b1->bar2(b2); // \
- // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}} \
+ // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}} \
// // expected-note {{found near match 'b1->mu_'}}
b2->getMu()->Lock();
@@ -2476,13 +2476,13 @@ void Foo::test3() {
ReleasableMutexLock rlock(&mu_);
a = 0;
rlock.Release();
- a = 1; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ a = 1; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
}
void Foo::test4() {
ReleasableMutexLock rlock(&mu_);
rlock.Release();
- rlock.Release(); // expected-warning {{unlocking 'mu_' that was not locked}}
+ rlock.Release(); // expected-warning {{releasing mutex 'mu_' that was not held}}
}
void Foo::test5() {
@@ -2491,7 +2491,7 @@ void Foo::test5() {
rlock.Release();
}
// no warning on join point for managed lock.
- rlock.Release(); // expected-warning {{unlocking 'mu_' that was not locked}}
+ rlock.Release(); // expected-warning {{releasing mutex 'mu_' that was not held}}
}
@@ -2560,12 +2560,12 @@ public:
void foo1() EXCLUSIVE_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}}
mutex_.Unlock();
- } // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}}
+ } // expected-warning {{expecting mutex 'mutex_' to be held at the end of function}}
void foo2() SHARED_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}}
mutex_.Unlock();
- } // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}}
+ } // expected-warning {{expecting mutex 'mutex_' to be held at the end of function}}
};
} // end namespace UnlockBug
@@ -2599,7 +2599,7 @@ class Foo {
void test2() {
WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
- } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+ } // expected-warning {{mutex 'mu_' is still held at the end of function}}
void test3() {
if (c) {
@@ -2622,7 +2622,7 @@ class Foo {
if (c) {
WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
}
- } // expected-warning {{mutex 'mu_' is not locked on every path through here}}
+ } // expected-warning {{mutex 'mu_' is not held on every path through here}}
void test6() {
if (c) {
@@ -2631,7 +2631,7 @@ class Foo {
else {
WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
}
- } // expected-warning {{mutex 'mu_' is not locked on every path through here}}
+ } // expected-warning {{mutex 'mu_' is not held on every path through here}}
};
@@ -2655,7 +2655,7 @@ void Foo::test() {
ReaderMutexLock lock(getMutexPtr().get());
int b = a;
}
- int b = a; // expected-warning {{reading variable 'a' requires locking 'getMutexPtr()'}}
+ int b = a; // expected-warning {{reading variable 'a' requires holding mutex 'getMutexPtr()'}}
}
} // end namespace TemporaryCleanupExpr
@@ -2686,9 +2686,9 @@ public:
};
void Foo::test0() {
- a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
- b = 0; // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
- c = 0; // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}}
+ a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
+ b = 0; // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
+ c = 0; // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
}
void Foo::test1() {
@@ -2772,10 +2772,10 @@ void Foo::test7() {
void Foo::test8() {
mu_->Lock();
- mu_.get()->Lock(); // expected-warning {{locking 'mu_' that is already locked}}
- (*mu_).Lock(); // expected-warning {{locking 'mu_' that is already locked}}
+ mu_.get()->Lock(); // expected-warning {{acquiring mutex 'mu_' that is already held}}
+ (*mu_).Lock(); // expected-warning {{acquiring mutex 'mu_' that is already held}}
mu_.get()->Unlock();
- Unlock(); // expected-warning {{unlocking 'mu_' that was not locked}}
+ Unlock(); // expected-warning {{releasing mutex 'mu_' that was not held}}
}
@@ -2790,9 +2790,9 @@ class Bar {
void Bar::test0() {
- foo->a = 0; // expected-warning {{writing variable 'a' requires locking 'foo->mu_' exclusively}}
- (*foo).b = 0; // expected-warning {{writing variable 'b' requires locking 'foo->mu_' exclusively}}
- foo.get()->c = 0; // expected-warning {{writing variable 'c' requires locking 'foo->mu_' exclusively}}
+ foo->a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'foo->mu_' exclusively}}
+ (*foo).b = 0; // expected-warning {{writing variable 'b' requires holding mutex 'foo->mu_' exclusively}}
+ foo.get()->c = 0; // expected-warning {{writing variable 'c' requires holding mutex 'foo->mu_' exclusively}}
}
@@ -2906,9 +2906,9 @@ void test0() {
foo.unlock();
foo.lock();
- foo.lock(); // expected-warning {{locking 'foo' that is already locked}}
+ foo.lock(); // expected-warning {{acquiring mutex 'foo' that is already held}}
foo.unlock();
- foo.unlock(); // expected-warning {{unlocking 'foo' that was not locked}}
+ foo.unlock(); // expected-warning {{releasing mutex 'foo' that was not held}}
}
@@ -2919,10 +2919,10 @@ void test1() {
foo.unlock1();
foo.lock1();
- foo.lock1(); // expected-warning {{locking 'foo.mu1_' that is already locked}}
+ foo.lock1(); // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
foo.a = 0;
foo.unlock1();
- foo.unlock1(); // expected-warning {{unlocking 'foo.mu1_' that was not locked}}
+ foo.unlock1(); // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
}
@@ -2933,10 +2933,10 @@ int test2() {
foo.unlock1();
foo.slock1();
- foo.slock1(); // expected-warning {{locking 'foo.mu1_' that is already locked}}
+ foo.slock1(); // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
int d2 = foo.a;
foo.unlock1();
- foo.unlock1(); // expected-warning {{unlocking 'foo.mu1_' that was not locked}}
+ foo.unlock1(); // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
return d1 + d2;
}
@@ -2951,17 +2951,17 @@ void test3() {
foo.lock3();
foo.lock3(); // \
- // expected-warning {{locking 'foo.mu1_' that is already locked}} \
- // expected-warning {{locking 'foo.mu2_' that is already locked}} \
- // expected-warning {{locking 'foo.mu3_' that is already locked}}
+ // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
+ // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
+ // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}
foo.a = 0;
foo.b = 0;
foo.c = 0;
foo.unlock3();
foo.unlock3(); // \
- // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \
- // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \
- // expected-warning {{unlocking 'foo.mu3_' that was not locked}}
+ // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \
+ // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \
+ // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}
}
@@ -2975,17 +2975,17 @@ void testlots() {
foo.locklots();
foo.locklots(); // \
- // expected-warning {{locking 'foo.mu1_' that is already locked}} \
- // expected-warning {{locking 'foo.mu2_' that is already locked}} \
- // expected-warning {{locking 'foo.mu3_' that is already locked}}
+ // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
+ // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
+ // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}
foo.a = 0;
foo.b = 0;
foo.c = 0;
foo.unlocklots();
foo.unlocklots(); // \
- // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \
- // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \
- // expected-warning {{unlocking 'foo.mu3_' that was not locked}}
+ // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \
+ // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \
+ // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}
}
} // end namespace DuplicateAttributeTest
@@ -3010,7 +3010,7 @@ class Foo {
void Foo::test1() {
if (tryLockMutexP() == 0) {
- a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
return;
}
a = 0;
@@ -3032,14 +3032,14 @@ void Foo::test1() {
}
if (tryLockMutexI() == 0) {
- a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
return;
}
a = 0;
unlock();
if (0 == tryLockMutexI()) {
- a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
return;
}
a = 0;
@@ -3051,7 +3051,7 @@ void Foo::test1() {
}
if (mu_.TryLock() == false) {
- a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
return;
}
a = 0;
@@ -3062,12 +3062,12 @@ void Foo::test1() {
unlock();
}
else {
- a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
}
#if __has_feature(cxx_nullptr)
if (tryLockMutexP() == nullptr) {
- a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
return;
}
a = 0;
@@ -3103,26 +3103,26 @@ void test() {
Graph g2;
Node n1;
- n1.a = 0; // expected-warning {{writing variable 'a' requires locking '&ExistentialPatternMatching::Graph::mu_' exclusively}}
- n1.foo(); // expected-warning {{calling function 'foo' requires exclusive lock on '&ExistentialPatternMatching::Graph::mu_'}}
+ n1.a = 0; // expected-warning {{writing variable 'a' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}
+ n1.foo(); // expected-warning {{calling function 'foo' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}
n1.foo2();
g1.mu_.Lock();
n1.a = 0;
n1.foo();
- n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
+ n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
g1.mu_.Unlock();
g2.mu_.Lock();
n1.a = 0;
n1.foo();
- n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
+ n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
g2.mu_.Unlock();
LockAllGraphs();
n1.a = 0;
n1.foo();
- n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
+ n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
UnlockAllGraphs();
LockAllGraphs();
@@ -3132,7 +3132,7 @@ void test() {
g2.mu_.Unlock();
LockAllGraphs();
- g1.mu_.Lock(); // expected-warning {{locking 'g1.mu_' that is already locked}}
+ g1.mu_.Lock(); // expected-warning {{acquiring mutex 'g1.mu_' that is already held}}
g1.mu_.Unlock();
}
@@ -3260,9 +3260,9 @@ class Foo {
beginNoWarnOnWrites();
}
a = 0; // \
- // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
endNoWarnOnWrites(); // \
- // expected-warning {{unlocking '*' that was not locked}}
+ // expected-warning {{releasing mutex '*' that was not held}}
}
@@ -3390,17 +3390,17 @@ public:
void test1() {
- Foo f; // expected-warning {{calling function 'Foo' requires exclusive lock on 'mu_'}}
- int a = f[0]; // expected-warning {{calling function 'operator[]' requires exclusive lock on 'mu_'}}
-} // expected-warning {{calling function '~Foo' requires exclusive lock on 'mu_'}}
+ Foo f; // expected-warning {{calling function 'Foo' requires holding mutex 'mu_' exclusively}}
+ int a = f[0]; // expected-warning {{calling function 'operator[]' requires holding mutex 'mu_' exclusively}}
+} // expected-warning {{calling function '~Foo' requires holding mutex 'mu_' exclusively}}
void test2() {
Bar::mu_.Lock();
{
- Bar b; // expected-warning {{cannot call function 'Bar' while mutex 'mu_' is locked}}
- int a = b[0]; // expected-warning {{cannot call function 'operator[]' while mutex 'mu_' is locked}}
- } // expected-warning {{cannot call function '~Bar' while mutex 'mu_' is locked}}
+ Bar b; // expected-warning {{cannot call function 'Bar' while mutex 'mu_' is held}}
+ int a = b[0]; // expected-warning {{cannot call function 'operator[]' while mutex 'mu_' is held}}
+ } // expected-warning {{cannot call function '~Bar' while mutex 'mu_' is held}}
Bar::mu_.Unlock();
}
@@ -3499,7 +3499,7 @@ void Foo::elr(Cell<T>* c1) { }
void Foo::test() {
Cell<int> cell;
elr(&cell); // \
- // expected-warning {{calling function 'elr' requires exclusive lock on 'cell.mu_'}}
+ // expected-warning {{calling function 'elr' requires holding mutex 'cell.mu_' exclusively}}
}
@@ -3512,7 +3512,7 @@ void globalELR(Cell<T>* c1) { }
void globalTest() {
Cell<int> cell;
globalELR(&cell); // \
- // expected-warning {{calling function 'globalELR' requires exclusive lock on 'cell.mu_'}}
+ // expected-warning {{calling function 'globalELR' requires holding mutex 'cell.mu_' exclusively}}
}
@@ -3533,7 +3533,7 @@ void globalELR2(Cell<T>* c4);
void globalTest2() {
Cell<int> cell;
globalELR2(&cell); // \
- // expected-warning {{calling function 'globalELR2' requires exclusive lock on 'cell.mu_'}}
+ // expected-warning {{calling function 'globalELR2' requires holding mutex 'cell.mu_' exclusively}}
}
@@ -3550,7 +3550,7 @@ void testFooT() {
Cell<int> cell;
FooT<int> foo;
foo.elr(&cell); // \
- // expected-warning {{calling function 'elr' requires exclusive lock on 'cell.mu_'}}
+ // expected-warning {{calling function 'elr' requires holding mutex 'cell.mu_' exclusively}}
}
} // end namespace TemplateFunctionParamRemapTest
@@ -3616,8 +3616,14 @@ class Foo {
EXCLUSIVE_TRYLOCK_FUNCTION(true, mu2_);
bool readertrylock() SHARED_TRYLOCK_FUNCTION(true, mu1_)
SHARED_TRYLOCK_FUNCTION(true, mu2_);
+ void assertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_)
+ ASSERT_EXCLUSIVE_LOCK(mu2_);
+ void assertShared() ASSERT_SHARED_LOCK(mu1_)
+ ASSERT_SHARED_LOCK(mu2_);
void test();
+ void testAssert();
+ void testAssertShared();
};
@@ -3676,6 +3682,21 @@ void Foo::test() {
}
}
+// Force duplication of attributes
+void Foo::assertBoth() { }
+void Foo::assertShared() { }
+
+void Foo::testAssert() {
+ assertBoth();
+ a = 0;
+ b = 0;
+}
+
+void Foo::testAssertShared() {
+ assertShared();
+ int zz = a + b;
+}
+
} // end namespace MultipleAttributeTest
@@ -3717,24 +3738,24 @@ public:
// method call tests
void test() {
data_.setValue(0); // FIXME -- should be writing \
- // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
+ // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
int a = data_.getValue(); // \
- // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
+ // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
datap1_->setValue(0); // FIXME -- should be writing \
- // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}}
+ // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
a = datap1_->getValue(); // \
- // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}}
+ // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
datap2_->setValue(0); // FIXME -- should be writing \
- // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+ // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
a = datap2_->getValue(); // \
- // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+ // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
(*datap2_).setValue(0); // FIXME -- should be writing \
- // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+ // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
a = (*datap2_).getValue(); // \
- // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+ // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
mu_.Lock();
data_.setValue(1);
@@ -3752,31 +3773,31 @@ public:
// operator tests
void test2() {
- data_ = Data(1); // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}}
- *datap1_ = data_; // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}} \
- // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
- *datap2_ = data_; // expected-warning {{writing the value pointed to by 'datap2_' requires locking 'mu_' exclusively}} \
- // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
- data_ = *datap1_; // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}} \
- // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}}
- data_ = *datap2_; // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}} \
- // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+ data_ = Data(1); // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
+ *datap1_ = data_; // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}} \
+ // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
+ *datap2_ = data_; // expected-warning {{writing the value pointed to by 'datap2_' requires holding mutex 'mu_' exclusively}} \
+ // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
+ data_ = *datap1_; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \
+ // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
+ data_ = *datap2_; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \
+ // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
- data_[0] = 0; // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
- (*datap2_)[0] = 0; // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+ data_[0] = 0; // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
+ (*datap2_)[0] = 0; // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
- data_(); // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
+ data_(); // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
}
// const operator tests
void test3() const {
- Data mydat(data_); // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
+ Data mydat(data_); // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
//FIXME
- //showDataCell(data_); // xpected-warning {{reading variable 'data_' requires locking 'mu_'}}
- //showDataCell(*datap2_); // xpected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+ //showDataCell(data_); // xpected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
+ //showDataCell(*datap2_); // xpected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
- int a = data_[0]; // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
+ int a = data_[0]; // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
}
private:
@@ -3820,31 +3841,31 @@ private:
Foo* foop PT_GUARDED_BY(mu_);
void test() {
- foo.myMethod(); // expected-warning {{reading variable 'foo' requires locking 'mu_'}}
+ foo.myMethod(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}
- int fa = foo.a; // expected-warning {{reading variable 'foo' requires locking 'mu_'}}
- foo.a = fa; // expected-warning {{writing variable 'foo' requires locking 'mu_' exclusively}}
+ int fa = foo.a; // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}
+ foo.a = fa; // expected-warning {{writing variable 'foo' requires holding mutex 'mu_' exclusively}}
- fa = foop->a; // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}}
- foop->a = fa; // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_' exclusively}}
+ fa = foop->a; // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}
+ foop->a = fa; // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}
- fa = (*foop).a; // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}}
- (*foop).a = fa; // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_' exclusively}}
+ fa = (*foop).a; // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}
+ (*foop).a = fa; // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}
- foo.c = Cell(0); // expected-warning {{writing variable 'foo' requires locking 'mu_'}} \
- // expected-warning {{writing variable 'c' requires locking 'foo.cell_mu_' exclusively}}
- foo.c.cellMethod(); // expected-warning {{reading variable 'foo' requires locking 'mu_'}} \
- // expected-warning {{reading variable 'c' requires locking 'foo.cell_mu_'}}
+ foo.c = Cell(0); // expected-warning {{writing variable 'foo' requires holding mutex 'mu_'}} \
+ // expected-warning {{writing variable 'c' requires holding mutex 'foo.cell_mu_' exclusively}}
+ foo.c.cellMethod(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}} \
+ // expected-warning {{reading variable 'c' requires holding mutex 'foo.cell_mu_'}}
- foop->c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_'}} \
- // expected-warning {{writing variable 'c' requires locking 'foop->cell_mu_' exclusively}}
- foop->c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}} \
- // expected-warning {{reading variable 'c' requires locking 'foop->cell_mu_'}}
+ foop->c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \
+ // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}
+ foop->c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \
+ // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}
- (*foop).c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_'}} \
- // expected-warning {{writing variable 'c' requires locking 'foop->cell_mu_' exclusively}}
- (*foop).c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}} \
- // expected-warning {{reading variable 'c' requires locking 'foop->cell_mu_'}}
+ (*foop).c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \
+ // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}
+ (*foop).c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \
+ // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}
};
};
@@ -3917,34 +3938,34 @@ public:
void lockBad() EXCLUSIVE_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
mu2_.Lock();
mu2_.Unlock();
- } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}}
+ } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}
void readerLockBad() SHARED_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
mu2_.Lock();
mu2_.Unlock();
- } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}}
+ } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}
void unlockBad() UNLOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
mu2_.Lock();
mu2_.Unlock();
- } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+ } // expected-warning {{mutex 'mu_' is still held at the end of function}}
// Check locking the wrong thing.
void lockBad2() EXCLUSIVE_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
mu2_.Lock(); // expected-note {{mutex acquired here}}
- } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}} \
- // expected-warning {{mutex 'mu2_' is still locked at the end of function}}
+ } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \
+ // expected-warning {{mutex 'mu2_' is still held at the end of function}}
void readerLockBad2() SHARED_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
mu2_.ReaderLock(); // expected-note {{mutex acquired here}}
- } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}} \
- // expected-warning {{mutex 'mu2_' is still locked at the end of function}}
+ } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \
+ // expected-warning {{mutex 'mu2_' is still held at the end of function}}
void unlockBad2() UNLOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
- mu2_.Unlock(); // expected-warning {{unlocking 'mu2_' that was not locked}}
- } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+ mu2_.Unlock(); // expected-warning {{releasing mutex 'mu2_' that was not held}}
+ } // expected-warning {{mutex 'mu_' is still held at the end of function}}
private:
Mutex mu_;
@@ -3971,7 +3992,7 @@ public:
void test2() {
mu_.AssertReaderHeld();
int b = a;
- a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
}
void test3() {
@@ -4032,7 +4053,7 @@ public:
else {
mu_.Lock(); // expected-note {{mutex acquired here}}
}
- } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+ } // expected-warning {{mutex 'mu_' is still held at the end of function}}
void test10() {
if (c) {
@@ -4041,7 +4062,7 @@ public:
else {
mu_.AssertHeld();
}
- } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+ } // expected-warning {{mutex 'mu_' is still held at the end of function}}
void assertMu() ASSERT_EXCLUSIVE_LOCK(mu_);
@@ -4178,52 +4199,52 @@ class PtGuardedBySanityTest {
void test2() {
mu1.ReaderLock();
- if (*a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires locking 'mu2'}}
- *a = 0; // expected-warning {{writing the value pointed to by 'a' requires locking 'mu2' exclusively}}
+ if (*a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}
+ *a = 0; // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}
- if (c->a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires locking 'mu2'}}
- c->a = 0; // expected-warning {{writing the value pointed to by 'c' requires locking 'mu2' exclusively}}
+ if (c->a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
+ c->a = 0; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
- if ((*c).a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires locking 'mu2'}}
- (*c).a = 0; // expected-warning {{writing the value pointed to by 'c' requires locking 'mu2' exclusively}}
+ if ((*c).a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
+ (*c).a = 0; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
- if (a[0] == 42) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires locking 'mu2'}}
- a[0] = 57; // expected-warning {{writing the value pointed to by 'a' requires locking 'mu2' exclusively}}
- if (c[0].a == 42) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires locking 'mu2'}}
- c[0].a = 57; // expected-warning {{writing the value pointed to by 'c' requires locking 'mu2' exclusively}}
+ if (a[0] == 42) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}
+ a[0] = 57; // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}
+ if (c[0].a == 42) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
+ c[0].a = 57; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
mu1.Unlock();
}
void test3() {
mu2.Lock();
- if (*a == 0) doSomething(); // expected-warning {{reading variable 'a' requires locking 'mu1'}}
- *a = 0; // expected-warning {{reading variable 'a' requires locking 'mu1'}}
+ if (*a == 0) doSomething(); // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
+ *a = 0; // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
- if (c->a == 0) doSomething(); // expected-warning {{reading variable 'c' requires locking 'mu1'}}
- c->a = 0; // expected-warning {{reading variable 'c' requires locking 'mu1'}}
+ if (c->a == 0) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
+ c->a = 0; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
- if ((*c).a == 0) doSomething(); // expected-warning {{reading variable 'c' requires locking 'mu1'}}
- (*c).a = 0; // expected-warning {{reading variable 'c' requires locking 'mu1'}}
+ if ((*c).a == 0) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
+ (*c).a = 0; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
- if (a[0] == 42) doSomething(); // expected-warning {{reading variable 'a' requires locking 'mu1'}}
- a[0] = 57; // expected-warning {{reading variable 'a' requires locking 'mu1'}}
- if (c[0].a == 42) doSomething(); // expected-warning {{reading variable 'c' requires locking 'mu1'}}
- c[0].a = 57; // expected-warning {{reading variable 'c' requires locking 'mu1'}}
+ if (a[0] == 42) doSomething(); // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
+ a[0] = 57; // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
+ if (c[0].a == 42) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
+ c[0].a = 57; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
mu2.Unlock();
}
void test4() { // Literal arrays
- if (sa[0] == 42) doSomething(); // expected-warning {{reading variable 'sa' requires locking 'mu1'}}
- sa[0] = 57; // expected-warning {{writing variable 'sa' requires locking 'mu1' exclusively}}
- if (sc[0].a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires locking 'mu1'}}
- sc[0].a = 57; // expected-warning {{writing variable 'sc' requires locking 'mu1' exclusively}}
+ if (sa[0] == 42) doSomething(); // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}
+ sa[0] = 57; // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}
+ if (sc[0].a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
+ sc[0].a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
- if (*sa == 42) doSomething(); // expected-warning {{reading variable 'sa' requires locking 'mu1'}}
- *sa = 57; // expected-warning {{writing variable 'sa' requires locking 'mu1' exclusively}}
- if ((*sc).a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires locking 'mu1'}}
- (*sc).a = 57; // expected-warning {{writing variable 'sc' requires locking 'mu1' exclusively}}
- if (sc->a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires locking 'mu1'}}
- sc->a = 57; // expected-warning {{writing variable 'sc' requires locking 'mu1' exclusively}}
+ if (*sa == 42) doSomething(); // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}
+ *sa = 57; // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}
+ if ((*sc).a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
+ (*sc).a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
+ if (sc->a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
+ sc->a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
}
void test5() {
@@ -4268,15 +4289,15 @@ class SmartPtr_PtGuardedBy_Test {
void test2() {
mu2.Lock();
- sp.get(); // expected-warning {{reading variable 'sp' requires locking 'mu1'}}
- if (*sp == 0) doSomething(); // expected-warning {{reading variable 'sp' requires locking 'mu1'}}
- *sp = 0; // expected-warning {{reading variable 'sp' requires locking 'mu1'}}
- sq->a = 0; // expected-warning {{reading variable 'sq' requires locking 'mu1'}}
+ sp.get(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
+ if (*sp == 0) doSomething(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
+ *sp = 0; // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
+ sq->a = 0; // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
- if (sp[0] == 0) doSomething(); // expected-warning {{reading variable 'sp' requires locking 'mu1'}}
- sp[0] = 0; // expected-warning {{reading variable 'sp' requires locking 'mu1'}}
- if (sq[0].a == 0) doSomething(); // expected-warning {{reading variable 'sq' requires locking 'mu1'}}
- sq[0].a = 0; // expected-warning {{reading variable 'sq' requires locking 'mu1'}}
+ if (sp[0] == 0) doSomething(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
+ sp[0] = 0; // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
+ if (sq[0].a == 0) doSomething(); // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
+ sq[0].a = 0; // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
mu2.Unlock();
}
@@ -4285,14 +4306,14 @@ class SmartPtr_PtGuardedBy_Test {
mu1.Lock();
sp.get();
- if (*sp == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires locking 'mu2'}}
- *sp = 0; // expected-warning {{reading the value pointed to by 'sp' requires locking 'mu2'}}
- sq->a = 0; // expected-warning {{reading the value pointed to by 'sq' requires locking 'mu2'}}
+ if (*sp == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
+ *sp = 0; // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
+ sq->a = 0; // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
- if (sp[0] == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires locking 'mu2'}}
- sp[0] = 0; // expected-warning {{reading the value pointed to by 'sp' requires locking 'mu2'}}
- if (sq[0].a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sq' requires locking 'mu2'}}
- sq[0].a = 0; // expected-warning {{reading the value pointed to by 'sq' requires locking 'mu2'}}
+ if (sp[0] == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
+ sp[0] = 0; // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
+ if (sq[0].a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
+ sq[0].a = 0; // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
mu1.Unlock();
}
@@ -4305,7 +4326,7 @@ namespace NonMemberCalleeICETest {
class A {
void Run() {
- (RunHelper)(); // expected-warning {{calling function 'RunHelper' requires exclusive lock on 'M'}}
+ (RunHelper)(); // expected-warning {{calling function 'RunHelper' requires holding mutex 'M' exclusively}}
}
void RunHelper() __attribute__((exclusive_locks_required(M)));
@@ -4314,3 +4335,46 @@ class A {
} // end namespace NonMemberCalleeICETest
+
+namespace pt_guard_attribute_type {
+ int i PT_GUARDED_BY(sls_mu); // expected-warning {{'pt_guarded_by' only applies to pointer types; type here is 'int'}}
+ int j PT_GUARDED_VAR; // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
+
+ void test() {
+ int i PT_GUARDED_BY(sls_mu); // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
+ int j PT_GUARDED_VAR; // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
+
+ typedef int PT_GUARDED_BY(sls_mu) bad1; // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
+ typedef int PT_GUARDED_VAR bad2; // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
+ }
+} // end namespace pt_guard_attribute_type
+
+
+namespace ThreadAttributesOnLambdas {
+
+class Foo {
+ Mutex mu_;
+
+ void LockedFunction() EXCLUSIVE_LOCKS_REQUIRED(mu_);
+
+ void test() {
+ auto func1 = [this]() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
+ LockedFunction();
+ };
+
+ auto func2 = [this]() NO_THREAD_SAFETY_ANALYSIS {
+ LockedFunction();
+ };
+
+ auto func3 = [this]() EXCLUSIVE_LOCK_FUNCTION(mu_) {
+ mu_.Lock();
+ };
+
+ func1(); // expected-warning {{calling function 'operator()' requires holding mutex 'mu_' exclusively}}
+ func2();
+ func3();
+ mu_.Unlock();
+ }
+};
+
+} // end namespace ThreadAttributesOnLambdas
diff --git a/test/SemaCXX/warn-thread-safety-parsing.cpp b/test/SemaCXX/warn-thread-safety-parsing.cpp
index 1bd4e439b7b0a..6f9e7de4176de 100644
--- a/test/SemaCXX/warn-thread-safety-parsing.cpp
+++ b/test/SemaCXX/warn-thread-safety-parsing.cpp
@@ -109,26 +109,26 @@ int noanal_testfn(int y) NO_THREAD_SAFETY_ANALYSIS;
int noanal_testfn(int y) {
int x NO_THREAD_SAFETY_ANALYSIS = y; // \
- // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
+ // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions}}
return x;
};
int noanal_test_var NO_THREAD_SAFETY_ANALYSIS; // \
- // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
+ // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions}}
class NoanalFoo {
private:
int test_field NO_THREAD_SAFETY_ANALYSIS; // \
- // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
+ // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions}}
void test_method() NO_THREAD_SAFETY_ANALYSIS;
};
class NO_THREAD_SAFETY_ANALYSIS NoanalTestClass { // \
- // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
+ // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions}}
};
void noanal_fun_params(int lvar NO_THREAD_SAFETY_ANALYSIS); // \
- // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
+ // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions}}
//-----------------------------------------//
@@ -229,28 +229,28 @@ class __attribute__((lockable (1))) LTestClass_args { // \
};
void l_test_function() LOCKABLE; // \
- // expected-warning {{'lockable' attribute only applies to classes}}
+ // expected-warning {{'lockable' attribute only applies to struct, union or class}}
int l_testfn(int y) {
int x LOCKABLE = y; // \
- // expected-warning {{'lockable' attribute only applies to classes}}
+ // expected-warning {{'lockable' attribute only applies to struct, union or class}}
return x;
}
int l_test_var LOCKABLE; // \
- // expected-warning {{'lockable' attribute only applies to classes}}
+ // expected-warning {{'lockable' attribute only applies to struct, union or class}}
class LFoo {
private:
int test_field LOCKABLE; // \
- // expected-warning {{'lockable' attribute only applies to classes}}
+ // expected-warning {{'lockable' attribute only applies to struct, union or class}}
void test_method() LOCKABLE; // \
- // expected-warning {{'lockable' attribute only applies to classes}}
+ // expected-warning {{'lockable' attribute only applies to struct, union or class}}
};
void l_function_params(int lvar LOCKABLE); // \
- // expected-warning {{'lockable' attribute only applies to classes}}
+ // expected-warning {{'lockable' attribute only applies to struct, union or class}}
//-----------------------------------------//
@@ -269,28 +269,28 @@ class __attribute__((scoped_lockable (1))) SLTestClass_args { // \
};
void sl_test_function() SCOPED_LOCKABLE; // \
- // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+ // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
int sl_testfn(int y) {
int x SCOPED_LOCKABLE = y; // \
- // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+ // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
return x;
}
int sl_test_var SCOPED_LOCKABLE; // \
- // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+ // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
class SLFoo {
private:
int test_field SCOPED_LOCKABLE; // \
- // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+ // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
void test_method() SCOPED_LOCKABLE; // \
- // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+ // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
};
void sl_function_params(int lvar SCOPED_LOCKABLE); // \
- // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+ // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
//-----------------------------------------//
@@ -353,13 +353,13 @@ int gb_var_arg_8 GUARDED_BY(muPointer);
// illegal attribute arguments
int gb_var_arg_bad_1 GUARDED_BY(1); // \
- // expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'int'}}
+ // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
int gb_var_arg_bad_2 GUARDED_BY("mu"); // \
// expected-warning {{ignoring 'guarded_by' attribute because its argument is invalid}}
int gb_var_arg_bad_3 GUARDED_BY(muDoublePointer); // \
- // expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'class Mutex **'}}
+ // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int gb_var_arg_bad_4 GUARDED_BY(umu); // \
- // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute; type here is 'class UnlockableMu'}}
+ // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'UnlockableMu'}}
//3.
// Thread Safety analysis tests
@@ -424,13 +424,13 @@ int * pgb_var_arg_8 PT_GUARDED_BY(muPointer);
// illegal attribute arguments
int * pgb_var_arg_bad_1 PT_GUARDED_BY(1); // \
- // expected-warning {{'pt_guarded_by' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
int * pgb_var_arg_bad_2 PT_GUARDED_BY("mu"); // \
// expected-warning {{ignoring 'pt_guarded_by' attribute because its argument is invalid}}
int * pgb_var_arg_bad_3 PT_GUARDED_BY(muDoublePointer); // \
- // expected-warning {{'pt_guarded_by' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int * pgb_var_arg_bad_4 PT_GUARDED_BY(umu); // \
- // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute}}
//-----------------------------------------//
@@ -446,12 +446,12 @@ int * pgb_var_arg_bad_4 PT_GUARDED_BY(umu); // \
Mutex mu_aa ACQUIRED_AFTER(mu1);
Mutex aa_var_noargs __attribute__((acquired_after)); // \
- // expected-error {{attribute takes at least 1 argument}}
+ // expected-error {{'acquired_after' attribute takes at least 1 argument}}
class AAFoo {
private:
Mutex aa_field_noargs __attribute__((acquired_after)); // \
- // expected-error {{attribute takes at least 1 argument}}
+ // expected-error {{'acquired_after' attribute takes at least 1 argument}}
Mutex aa_field_args ACQUIRED_AFTER(mu1);
};
@@ -485,15 +485,15 @@ Mutex aa_var_arg_8 ACQUIRED_AFTER(muPointer);
// illegal attribute arguments
Mutex aa_var_arg_bad_1 ACQUIRED_AFTER(1); // \
- // expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
Mutex aa_var_arg_bad_2 ACQUIRED_AFTER("mu"); // \
// expected-warning {{ignoring 'acquired_after' attribute because its argument is invalid}}
Mutex aa_var_arg_bad_3 ACQUIRED_AFTER(muDoublePointer); // \
- // expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
Mutex aa_var_arg_bad_4 ACQUIRED_AFTER(umu); // \
- // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'capability' attribute}}
UnlockableMu aa_var_arg_bad_5 ACQUIRED_AFTER(mu_aa); // \
- // expected-warning {{'acquired_after' attribute can only be applied in a context annotated with 'lockable' attribute}}
+ // expected-warning {{'acquired_after' attribute can only be applied in a context annotated with 'capability("mutex")' attribute}}
//-----------------------------------------//
// Acquired Before (ab)
@@ -506,12 +506,12 @@ UnlockableMu aa_var_arg_bad_5 ACQUIRED_AFTER(mu_aa); // \
Mutex mu_ab ACQUIRED_BEFORE(mu1);
Mutex ab_var_noargs __attribute__((acquired_before)); // \
- // expected-error {{attribute takes at least 1 argument}}
+ // expected-error {{'acquired_before' attribute takes at least 1 argument}}
class ABFoo {
private:
Mutex ab_field_noargs __attribute__((acquired_before)); // \
- // expected-error {{attribute takes at least 1 argument}}
+ // expected-error {{'acquired_before' attribute takes at least 1 argument}}
Mutex ab_field_args ACQUIRED_BEFORE(mu1);
};
@@ -548,15 +548,15 @@ Mutex ab_var_arg_8 ACQUIRED_BEFORE(muPointer);
// illegal attribute arguments
Mutex ab_var_arg_bad_1 ACQUIRED_BEFORE(1); // \
- // expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
Mutex ab_var_arg_bad_2 ACQUIRED_BEFORE("mu"); // \
// expected-warning {{ignoring 'acquired_before' attribute because its argument is invalid}}
Mutex ab_var_arg_bad_3 ACQUIRED_BEFORE(muDoublePointer); // \
- // expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
Mutex ab_var_arg_bad_4 ACQUIRED_BEFORE(umu); // \
- // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'capability' attribute}}
UnlockableMu ab_var_arg_bad_5 ACQUIRED_BEFORE(mu_ab); // \
- // expected-warning {{'acquired_before' attribute can only be applied in a context annotated with 'lockable' attribute}}
+ // expected-warning {{'acquired_before' attribute can only be applied in a context annotated with 'capability("mutex")' attribute}}
//-----------------------------------------//
@@ -577,26 +577,26 @@ int elf_testfn(int y) EXCLUSIVE_LOCK_FUNCTION();
int elf_testfn(int y) {
int x EXCLUSIVE_LOCK_FUNCTION() = y; // \
- // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'exclusive_lock_function' attribute only applies to functions}}
return x;
};
int elf_test_var EXCLUSIVE_LOCK_FUNCTION(); // \
- // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'exclusive_lock_function' attribute only applies to functions}}
class ElfFoo {
private:
int test_field EXCLUSIVE_LOCK_FUNCTION(); // \
- // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'exclusive_lock_function' attribute only applies to functions}}
void test_method() EXCLUSIVE_LOCK_FUNCTION();
};
class EXCLUSIVE_LOCK_FUNCTION() ElfTestClass { // \
- // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'exclusive_lock_function' attribute only applies to functions}}
};
void elf_fun_params(int lvar EXCLUSIVE_LOCK_FUNCTION()); // \
- // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'exclusive_lock_function' attribute only applies to functions}}
// Check argument parsing.
@@ -617,9 +617,9 @@ int elf_function_9(Mutex x, Mutex y) EXCLUSIVE_LOCK_FUNCTION(1,2);
int elf_function_bad_2() EXCLUSIVE_LOCK_FUNCTION("mu"); // \
// expected-warning {{ignoring 'exclusive_lock_function' attribute because its argument is invalid}}
int elf_function_bad_3() EXCLUSIVE_LOCK_FUNCTION(muDoublePointer); // \
- // expected-warning {{'exclusive_lock_function' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'exclusive_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int elf_function_bad_4() EXCLUSIVE_LOCK_FUNCTION(umu); // \
- // expected-warning {{'exclusive_lock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'exclusive_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}
int elf_function_bad_1() EXCLUSIVE_LOCK_FUNCTION(1); // \
// expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
@@ -649,25 +649,25 @@ int slf_testfn(int y) SHARED_LOCK_FUNCTION();
int slf_testfn(int y) {
int x SHARED_LOCK_FUNCTION() = y; // \
- // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'shared_lock_function' attribute only applies to functions}}
return x;
};
int slf_test_var SHARED_LOCK_FUNCTION(); // \
- // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'shared_lock_function' attribute only applies to functions}}
void slf_fun_params(int lvar SHARED_LOCK_FUNCTION()); // \
- // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'shared_lock_function' attribute only applies to functions}}
class SlfFoo {
private:
int test_field SHARED_LOCK_FUNCTION(); // \
- // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'shared_lock_function' attribute only applies to functions}}
void test_method() SHARED_LOCK_FUNCTION();
};
class SHARED_LOCK_FUNCTION() SlfTestClass { // \
- // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'shared_lock_function' attribute only applies to functions}}
};
// Check argument parsing.
@@ -689,9 +689,9 @@ int slf_function_9(Mutex x, Mutex y) SHARED_LOCK_FUNCTION(1,2);
int slf_function_bad_2() SHARED_LOCK_FUNCTION("mu"); // \
// expected-warning {{ignoring 'shared_lock_function' attribute because its argument is invalid}}
int slf_function_bad_3() SHARED_LOCK_FUNCTION(muDoublePointer); // \
- // expected-warning {{'shared_lock_function' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'shared_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int slf_function_bad_4() SHARED_LOCK_FUNCTION(umu); // \
- // expected-warning {{'shared_lock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'shared_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}
int slf_function_bad_1() SHARED_LOCK_FUNCTION(1); // \
// expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
@@ -715,7 +715,7 @@ int slf_function_bad_7() SHARED_LOCK_FUNCTION(0); // \
// plus an optional list of locks (vars/fields)
void etf_function() __attribute__((exclusive_trylock_function)); // \
- // expected-error {{attribute takes at least 1 argument}}
+ // expected-error {{'exclusive_trylock_function' attribute takes at least 1 argument}}
void etf_function_args() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu2);
@@ -725,26 +725,26 @@ int etf_testfn(int y) EXCLUSIVE_TRYLOCK_FUNCTION(1);
int etf_testfn(int y) {
int x EXCLUSIVE_TRYLOCK_FUNCTION(1) = y; // \
- // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'exclusive_trylock_function' attribute only applies to functions}}
return x;
};
int etf_test_var EXCLUSIVE_TRYLOCK_FUNCTION(1); // \
- // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'exclusive_trylock_function' attribute only applies to functions}}
class EtfFoo {
private:
int test_field EXCLUSIVE_TRYLOCK_FUNCTION(1); // \
- // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'exclusive_trylock_function' attribute only applies to functions}}
void test_method() EXCLUSIVE_TRYLOCK_FUNCTION(1);
};
class EXCLUSIVE_TRYLOCK_FUNCTION(1) EtfTestClass { // \
- // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'exclusive_trylock_function' attribute only applies to functions}}
};
void etf_fun_params(int lvar EXCLUSIVE_TRYLOCK_FUNCTION(1)); // \
- // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'exclusive_trylock_function' attribute only applies to functions}}
// Check argument parsing.
@@ -771,9 +771,9 @@ int etf_function_bad_3() EXCLUSIVE_TRYLOCK_FUNCTION(muDoublePointer); // \
int etf_function_bad_4() EXCLUSIVE_TRYLOCK_FUNCTION(1, "mu"); // \
// expected-warning {{ignoring 'exclusive_trylock_function' attribute because its argument is invalid}}
int etf_function_bad_5() EXCLUSIVE_TRYLOCK_FUNCTION(1, muDoublePointer); // \
- // expected-warning {{'exclusive_trylock_function' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'exclusive_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int etf_function_bad_6() EXCLUSIVE_TRYLOCK_FUNCTION(1, umu); // \
- // expected-warning {{'exclusive_trylock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'exclusive_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}
//-----------------------------------------//
@@ -788,7 +788,7 @@ int etf_function_bad_6() EXCLUSIVE_TRYLOCK_FUNCTION(1, umu); // \
// plus an optional list of locks (vars/fields)
void stf_function() __attribute__((shared_trylock_function)); // \
- // expected-error {{attribute takes at least 1 argument}}
+ // expected-error {{'shared_trylock_function' attribute takes at least 1 argument}}
void stf_function_args() SHARED_TRYLOCK_FUNCTION(1, mu2);
@@ -798,26 +798,26 @@ int stf_testfn(int y) SHARED_TRYLOCK_FUNCTION(1);
int stf_testfn(int y) {
int x SHARED_TRYLOCK_FUNCTION(1) = y; // \
- // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'shared_trylock_function' attribute only applies to functions}}
return x;
};
int stf_test_var SHARED_TRYLOCK_FUNCTION(1); // \
- // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'shared_trylock_function' attribute only applies to functions}}
void stf_fun_params(int lvar SHARED_TRYLOCK_FUNCTION(1)); // \
- // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'shared_trylock_function' attribute only applies to functions}}
class StfFoo {
private:
int test_field SHARED_TRYLOCK_FUNCTION(1); // \
- // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'shared_trylock_function' attribute only applies to functions}}
void test_method() SHARED_TRYLOCK_FUNCTION(1);
};
class SHARED_TRYLOCK_FUNCTION(1) StfTestClass { // \
- // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'shared_trylock_function' attribute only applies to functions}}
};
// Check argument parsing.
@@ -845,9 +845,9 @@ int stf_function_bad_3() SHARED_TRYLOCK_FUNCTION(muDoublePointer); // \
int stf_function_bad_4() SHARED_TRYLOCK_FUNCTION(1, "mu"); // \
// expected-warning {{ignoring 'shared_trylock_function' attribute because its argument is invalid}}
int stf_function_bad_5() SHARED_TRYLOCK_FUNCTION(1, muDoublePointer); // \
- // expected-warning {{'shared_trylock_function' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'shared_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int stf_function_bad_6() SHARED_TRYLOCK_FUNCTION(1, umu); // \
- // expected-warning {{'shared_trylock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'shared_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}
//-----------------------------------------//
@@ -868,26 +868,26 @@ int uf_testfn(int y) UNLOCK_FUNCTION();
int uf_testfn(int y) {
int x UNLOCK_FUNCTION() = y; // \
- // expected-warning {{'unlock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'unlock_function' attribute only applies to functions}}
return x;
};
int uf_test_var UNLOCK_FUNCTION(); // \
- // expected-warning {{'unlock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'unlock_function' attribute only applies to functions}}
class UfFoo {
private:
int test_field UNLOCK_FUNCTION(); // \
- // expected-warning {{'unlock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'unlock_function' attribute only applies to functions}}
void test_method() UNLOCK_FUNCTION();
};
class NO_THREAD_SAFETY_ANALYSIS UfTestClass { // \
- // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
+ // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions}}
};
void uf_fun_params(int lvar UNLOCK_FUNCTION()); // \
- // expected-warning {{'unlock_function' attribute only applies to functions and methods}}
+ // expected-warning {{'unlock_function' attribute only applies to functions}}
// Check argument parsing.
@@ -908,9 +908,9 @@ int uf_function_9(Mutex x, Mutex y) UNLOCK_FUNCTION(1,2);
int uf_function_bad_2() UNLOCK_FUNCTION("mu"); // \
// expected-warning {{ignoring 'unlock_function' attribute because its argument is invalid}}
int uf_function_bad_3() UNLOCK_FUNCTION(muDoublePointer); // \
- // expected-warning {{'unlock_function' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int uf_function_bad_4() UNLOCK_FUNCTION(umu); // \
- // expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}
int uf_function_bad_1() UNLOCK_FUNCTION(1); // \
// expected-error {{'unlock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
@@ -944,25 +944,25 @@ int lr_testfn(int y) LOCK_RETURNED(mu1);
int lr_testfn(int y) {
int x LOCK_RETURNED(mu1) = y; // \
- // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
+ // expected-warning {{'lock_returned' attribute only applies to functions}}
return x;
};
int lr_test_var LOCK_RETURNED(mu1); // \
- // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
+ // expected-warning {{'lock_returned' attribute only applies to functions}}
void lr_fun_params(int lvar LOCK_RETURNED(mu1)); // \
- // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
+ // expected-warning {{'lock_returned' attribute only applies to functions}}
class LrFoo {
private:
int test_field LOCK_RETURNED(mu1); // \
- // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
+ // expected-warning {{'lock_returned' attribute only applies to functions}}
void test_method() LOCK_RETURNED(mu1);
};
class LOCK_RETURNED(mu1) LrTestClass { // \
- // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
+ // expected-warning {{'lock_returned' attribute only applies to functions}}
};
// Check argument parsing.
@@ -980,13 +980,13 @@ int lr_function_8() LOCK_RETURNED(muPointer);
// illegal attribute arguments
int lr_function_bad_1() LOCK_RETURNED(1); // \
- // expected-warning {{'lock_returned' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
int lr_function_bad_2() LOCK_RETURNED("mu"); // \
// expected-warning {{ignoring 'lock_returned' attribute because its argument is invalid}}
int lr_function_bad_3() LOCK_RETURNED(muDoublePointer); // \
- // expected-warning {{'lock_returned' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int lr_function_bad_4() LOCK_RETURNED(umu); // \
- // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'capability' attribute}}
@@ -1001,7 +1001,7 @@ int lr_function_bad_4() LOCK_RETURNED(umu); // \
// takes one or more arguments, all locks (vars/fields)
void le_function() __attribute__((locks_excluded)); // \
- // expected-error {{attribute takes at least 1 argument}}
+ // expected-error {{'locks_excluded' attribute takes at least 1 argument}}
void le_function_arg() LOCKS_EXCLUDED(mu1);
@@ -1011,25 +1011,25 @@ int le_testfn(int y) LOCKS_EXCLUDED(mu1);
int le_testfn(int y) {
int x LOCKS_EXCLUDED(mu1) = y; // \
- // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
+ // expected-warning {{'locks_excluded' attribute only applies to functions}}
return x;
};
int le_test_var LOCKS_EXCLUDED(mu1); // \
- // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
+ // expected-warning {{'locks_excluded' attribute only applies to functions}}
void le_fun_params(int lvar LOCKS_EXCLUDED(mu1)); // \
- // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
+ // expected-warning {{'locks_excluded' attribute only applies to functions}}
class LeFoo {
private:
int test_field LOCKS_EXCLUDED(mu1); // \
- // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
+ // expected-warning {{'locks_excluded' attribute only applies to functions}}
void test_method() LOCKS_EXCLUDED(mu1);
};
class LOCKS_EXCLUDED(mu1) LeTestClass { // \
- // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
+ // expected-warning {{'locks_excluded' attribute only applies to functions}}
};
// Check argument parsing.
@@ -1047,13 +1047,13 @@ int le_function_8() LOCKS_EXCLUDED(muPointer);
// illegal attribute arguments
int le_function_bad_1() LOCKS_EXCLUDED(1); // \
- // expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
int le_function_bad_2() LOCKS_EXCLUDED("mu"); // \
// expected-warning {{ignoring 'locks_excluded' attribute because its argument is invalid}}
int le_function_bad_3() LOCKS_EXCLUDED(muDoublePointer); // \
- // expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int le_function_bad_4() LOCKS_EXCLUDED(umu); // \
- // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute}}
@@ -1068,7 +1068,7 @@ int le_function_bad_4() LOCKS_EXCLUDED(umu); // \
// takes one or more arguments, all locks (vars/fields)
void elr_function() __attribute__((exclusive_locks_required)); // \
- // expected-error {{attribute takes at least 1 argument}}
+ // expected-error {{'exclusive_locks_required' attribute takes at least 1 argument}}
void elr_function_arg() EXCLUSIVE_LOCKS_REQUIRED(mu1);
@@ -1078,25 +1078,25 @@ int elr_testfn(int y) EXCLUSIVE_LOCKS_REQUIRED(mu1);
int elr_testfn(int y) {
int x EXCLUSIVE_LOCKS_REQUIRED(mu1) = y; // \
- // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
+ // expected-warning {{'exclusive_locks_required' attribute only applies to functions}}
return x;
};
int elr_test_var EXCLUSIVE_LOCKS_REQUIRED(mu1); // \
- // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
+ // expected-warning {{'exclusive_locks_required' attribute only applies to functions}}
void elr_fun_params(int lvar EXCLUSIVE_LOCKS_REQUIRED(mu1)); // \
- // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
+ // expected-warning {{'exclusive_locks_required' attribute only applies to functions}}
class ElrFoo {
private:
int test_field EXCLUSIVE_LOCKS_REQUIRED(mu1); // \
- // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
+ // expected-warning {{'exclusive_locks_required' attribute only applies to functions}}
void test_method() EXCLUSIVE_LOCKS_REQUIRED(mu1);
};
class EXCLUSIVE_LOCKS_REQUIRED(mu1) ElrTestClass { // \
- // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
+ // expected-warning {{'exclusive_locks_required' attribute only applies to functions}}
};
// Check argument parsing.
@@ -1114,13 +1114,13 @@ int elr_function_8() EXCLUSIVE_LOCKS_REQUIRED(muPointer);
// illegal attribute arguments
int elr_function_bad_1() EXCLUSIVE_LOCKS_REQUIRED(1); // \
- // expected-warning {{'exclusive_locks_required' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
int elr_function_bad_2() EXCLUSIVE_LOCKS_REQUIRED("mu"); // \
// expected-warning {{ignoring 'exclusive_locks_required' attribute because its argument is invalid}}
int elr_function_bad_3() EXCLUSIVE_LOCKS_REQUIRED(muDoublePointer); // \
- // expected-warning {{'exclusive_locks_required' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int elr_function_bad_4() EXCLUSIVE_LOCKS_REQUIRED(umu); // \
- // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute}}
@@ -1136,7 +1136,7 @@ int elr_function_bad_4() EXCLUSIVE_LOCKS_REQUIRED(umu); // \
// takes one or more arguments, all locks (vars/fields)
void slr_function() __attribute__((shared_locks_required)); // \
- // expected-error {{attribute takes at least 1 argument}}
+ // expected-error {{'shared_locks_required' attribute takes at least 1 argument}}
void slr_function_arg() SHARED_LOCKS_REQUIRED(mu1);
@@ -1146,25 +1146,25 @@ int slr_testfn(int y) SHARED_LOCKS_REQUIRED(mu1);
int slr_testfn(int y) {
int x SHARED_LOCKS_REQUIRED(mu1) = y; // \
- // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
+ // expected-warning {{'shared_locks_required' attribute only applies to functions}}
return x;
};
int slr_test_var SHARED_LOCKS_REQUIRED(mu1); // \
- // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
+ // expected-warning {{'shared_locks_required' attribute only applies to functions}}
void slr_fun_params(int lvar SHARED_LOCKS_REQUIRED(mu1)); // \
- // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
+ // expected-warning {{'shared_locks_required' attribute only applies to functions}}
class SlrFoo {
private:
int test_field SHARED_LOCKS_REQUIRED(mu1); // \
- // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
+ // expected-warning {{'shared_locks_required' attribute only applies to functions}}
void test_method() SHARED_LOCKS_REQUIRED(mu1);
};
class SHARED_LOCKS_REQUIRED(mu1) SlrTestClass { // \
- // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
+ // expected-warning {{'shared_locks_required' attribute only applies to functions}}
};
// Check argument parsing.
@@ -1182,13 +1182,13 @@ int slr_function_8() SHARED_LOCKS_REQUIRED(muPointer);
// illegal attribute arguments
int slr_function_bad_1() SHARED_LOCKS_REQUIRED(1); // \
- // expected-warning {{'shared_locks_required' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
int slr_function_bad_2() SHARED_LOCKS_REQUIRED("mu"); // \
// expected-warning {{ignoring 'shared_locks_required' attribute because its argument is invalid}}
int slr_function_bad_3() SHARED_LOCKS_REQUIRED(muDoublePointer); // \
- // expected-warning {{'shared_locks_required' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int slr_function_bad_4() SHARED_LOCKS_REQUIRED(umu); // \
- // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute}}
//-----------------------------------------//
@@ -1430,7 +1430,7 @@ class Foo {
int a GUARDED_BY(mu1_);
int b GUARDED_BY(mu2_);
int c GUARDED_BY(mu3_); // \
- // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute; type here is 'class InheritanceTest::Derived3'}}
+ // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'InheritanceTest::Derived3'}}
void foo() EXCLUSIVE_LOCKS_REQUIRED(mu1_, mu2_) {
a = 0;
diff --git a/test/SemaCXX/warn-undefined-bool-conversion.cpp b/test/SemaCXX/warn-undefined-bool-conversion.cpp
new file mode 100644
index 0000000000000..1f8baa0e8d8ab
--- /dev/null
+++ b/test/SemaCXX/warn-undefined-bool-conversion.cpp
@@ -0,0 +1,97 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wundefined-bool-conversion %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-bool-conversion -Wundefined-bool-conversion %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wbool-conversion %s
+
+void test1(int &x) {
+ if (x == 1) { }
+ if (&x) { }
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+ if (!&x) { }
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+}
+
+class test2 {
+ test2() : x(y) {}
+
+ void foo() {
+ if (this) { }
+ // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+ if (!this) { }
+ // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; pointer may be assumed to always convert to true}}
+ }
+
+ void bar() {
+ if (x == 1) { }
+ if (&x) { }
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+ if (!&x) { }
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+ }
+
+ int &x;
+ int y;
+};
+
+namespace function_return_reference {
+ int& get_int();
+ // expected-note@-1 3{{'get_int' returns a reference}}
+ class B {
+ public:
+ static int &stat();
+ // expected-note@-1 3{{'stat' returns a reference}}
+ int &get();
+ // expected-note@-1 6{{'get' returns a reference}}
+ };
+
+ void test() {
+ if (&get_int()) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+ if (&(get_int())) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+ if (!&get_int()) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+ if (&B::stat()) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+ if (&(B::stat())) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+ if (!&B::stat()) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+ B b;
+ if (&b.get()) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+ if (&(b.get())) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+ if (!&b.get()) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+ B* b_ptr = &b;
+ if (&b_ptr->get()) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+ if (&(b_ptr->get())) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+ if (!&b_ptr->get()) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+ int& (B::*m_ptr)() = &B::get;
+ if (&(b.*m_ptr)()) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+ if (&((b.*m_ptr)())) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+ if (!&(b.*m_ptr)()) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+ int& (*f_ptr)() = &get_int;
+ if (&(*f_ptr)()) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+ if (&((*f_ptr)())) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+ if (!&(*f_ptr)()) {}
+ // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+ }
+}
diff --git a/test/SemaCXX/warn-unreachable.cpp b/test/SemaCXX/warn-unreachable.cpp
index dd071258e29d1..b08467ab51e63 100644
--- a/test/SemaCXX/warn-unreachable.cpp
+++ b/test/SemaCXX/warn-unreachable.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fcxx-exceptions -fexceptions -fsyntax-only -verify -fblocks -Wunreachable-code -Wno-unused-value
+// RUN: %clang_cc1 %s -fcxx-exceptions -fexceptions -fsyntax-only -verify -fblocks -std=c++11 -Wunreachable-code-aggressive -Wno-unused-value -Wno-tautological-compare
int &halt() __attribute__((noreturn));
int &live();
@@ -107,3 +107,303 @@ template <> void funcToSpecialize<int>() {
dead(); // expected-warning {{will never be executed}}
}
+// Handle 'try' code dominating a dead return.
+enum PR19040_test_return_t
+{ PR19040_TEST_FAILURE };
+namespace PR19040_libtest
+{
+ class A {
+ public:
+ ~A ();
+ };
+}
+PR19040_test_return_t PR19040_fn1 ()
+{
+ try
+ {
+ throw PR19040_libtest::A ();
+ } catch (...)
+ {
+ return PR19040_TEST_FAILURE;
+ }
+ return PR19040_TEST_FAILURE; // expected-warning {{will never be executed}}
+}
+
+__attribute__((noreturn))
+void raze();
+
+namespace std {
+template<typename T> struct basic_string {
+ basic_string(const T* x) {}
+ ~basic_string() {};
+};
+typedef basic_string<char> string;
+}
+
+std::string testStr() {
+ raze();
+ return ""; // expected-warning {{'return' will never be executed}}
+}
+
+std::string testStrWarn(const char *s) {
+ raze();
+ return s; // expected-warning {{will never be executed}}
+}
+
+bool testBool() {
+ raze();
+ return true; // expected-warning {{'return' will never be executed}}
+}
+
+static const bool ConditionVar = 1;
+int test_global_as_conditionVariable() {
+ if (ConditionVar)
+ return 1;
+ return 0; // no-warning
+}
+
+// Handle unreachable temporary destructors.
+class A {
+public:
+ A();
+ ~A();
+};
+
+__attribute__((noreturn))
+void raze(const A& x);
+
+void test_with_unreachable_tmp_dtors(int x) {
+ raze(x ? A() : A()); // no-warning
+}
+
+// Test sizeof - sizeof in enum declaration.
+enum { BrownCow = sizeof(long) - sizeof(char) };
+enum { CowBrown = 8 - 1 };
+
+
+int test_enum_sizeof_arithmetic() {
+ if (BrownCow)
+ return 1;
+ return 2;
+}
+
+int test_enum_arithmetic() {
+ if (CowBrown)
+ return 1;
+ return 2; // expected-warning {{never be executed}}
+}
+
+int test_arithmetic() {
+ if (8 -1)
+ return 1;
+ return 2; // expected-warning {{never be executed}}
+}
+
+int test_treat_const_bool_local_as_config_value() {
+ const bool controlValue = false;
+ if (!controlValue)
+ return 1;
+ test_treat_const_bool_local_as_config_value(); // no-warning
+ return 0;
+}
+
+int test_treat_non_const_bool_local_as_non_config_value() {
+ bool controlValue = false;
+ if (!controlValue)
+ return 1;
+ // There is no warning here because 'controlValue' isn't really
+ // a control value at all. The CFG will not treat this
+ // branch as unreachable.
+ test_treat_non_const_bool_local_as_non_config_value(); // no-warning
+ return 0;
+}
+
+void test_do_while(int x) {
+ // Handle trivial expressions with
+ // implicit casts to bool.
+ do {
+ break;
+ } while (0); // no-warning
+}
+
+class Frobozz {
+public:
+ Frobozz(int x);
+ ~Frobozz();
+};
+
+Frobozz test_return_object(int flag) {
+ return Frobozz(flag);
+ return Frobozz(42); // expected-warning {{'return' will never be executed}}
+}
+
+Frobozz test_return_object_control_flow(int flag) {
+ return Frobozz(flag);
+ return Frobozz(flag ? 42 : 24); // expected-warning {{code will never be executed}}
+}
+
+void somethingToCall();
+
+static constexpr bool isConstExprConfigValue() { return true; }
+
+int test_const_expr_config_value() {
+ if (isConstExprConfigValue()) {
+ somethingToCall();
+ return 0;
+ }
+ somethingToCall(); // no-warning
+ return 1;
+}
+int test_const_expr_config_value_2() {
+ if (!isConstExprConfigValue()) {
+ somethingToCall(); // no-warning
+ return 0;
+ }
+ somethingToCall();
+ return 1;
+}
+
+class Frodo {
+public:
+ static const bool aHobbit = true;
+};
+
+void test_static_class_var() {
+ if (Frodo::aHobbit)
+ somethingToCall();
+ else
+ somethingToCall(); // no-warning
+}
+
+void test_static_class_var(Frodo &F) {
+ if (F.aHobbit)
+ somethingToCall();
+ else
+ somethingToCall(); // no-warning
+}
+
+void test_unreachable_for_null_increment() {
+ for (unsigned i = 0; i < 10 ; ) // no-warning
+ break;
+}
+
+void test_unreachable_forrange_increment() {
+ int x[10] = { 0 };
+ for (auto i : x) { // expected-warning {{loop will run at most once (loop increment never executed)}}
+ break;
+ }
+}
+
+void calledFun() {}
+
+// Test "silencing" with parentheses.
+void test_with_paren_silencing(int x) {
+ if (false) calledFun(); // expected-warning {{will never be executed}} expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+ if ((false)) calledFun(); // no-warning
+
+ if (true) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+ calledFun();
+ else
+ calledFun(); // expected-warning {{will never be executed}}
+
+ if ((true))
+ calledFun();
+ else
+ calledFun(); // no-warning
+
+ if (!true) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+ calledFun(); // expected-warning {{code will never be executed}}
+ else
+ calledFun();
+
+ if ((!true))
+ calledFun(); // no-warning
+ else
+ calledFun();
+
+ if (!(true))
+ calledFun(); // no-warning
+ else
+ calledFun();
+}
+
+void test_with_paren_silencing_impcast(int x) {
+ if (0) calledFun(); // expected-warning {{will never be executed}} expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+ if ((0)) calledFun(); // no-warning
+
+ if (1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+ calledFun();
+ else
+ calledFun(); // expected-warning {{will never be executed}}
+
+ if ((1))
+ calledFun();
+ else
+ calledFun(); // no-warning
+
+ if (!1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+ calledFun(); // expected-warning {{code will never be executed}}
+ else
+ calledFun();
+
+ if ((!1))
+ calledFun(); // no-warning
+ else
+ calledFun();
+
+ if (!(1))
+ calledFun(); // no-warning
+ else
+ calledFun();
+}
+
+void tautological_compare(bool x, int y) {
+ if (x > 10) // expected-note {{silence}}
+ calledFun(); // expected-warning {{will never be executed}}
+ if (10 < x) // expected-note {{silence}}
+ calledFun(); // expected-warning {{will never be executed}}
+ if (x == 10) // expected-note {{silence}}
+ calledFun(); // expected-warning {{will never be executed}}
+
+ if (x < 10) // expected-note {{silence}}
+ calledFun();
+ else
+ calledFun(); // expected-warning {{will never be executed}}
+ if (10 > x) // expected-note {{silence}}
+ calledFun();
+ else
+ calledFun(); // expected-warning {{will never be executed}}
+ if (x != 10) // expected-note {{silence}}
+ calledFun();
+ else
+ calledFun(); // expected-warning {{will never be executed}}
+
+ if (y != 5 && y == 5) // expected-note {{silence}}
+ calledFun(); // expected-warning {{will never be executed}}
+
+ if (y > 5 && y < 4) // expected-note {{silence}}
+ calledFun(); // expected-warning {{will never be executed}}
+
+ if (y < 10 || y > 5) // expected-note {{silence}}
+ calledFun();
+ else
+ calledFun(); // expected-warning {{will never be executed}}
+
+ // TODO: Extend warning to the following code:
+ if (x < -1)
+ calledFun();
+ if (x == -1)
+ calledFun();
+
+ if (x != -1)
+ calledFun();
+ else
+ calledFun();
+ if (-1 > x)
+ calledFun();
+ else
+ calledFun();
+
+ if (y == -1 && y != -1)
+ calledFun();
+}
diff --git a/test/SemaCXX/warn-unused-attribute.cpp b/test/SemaCXX/warn-unused-attribute.cpp
index 72f96eea0b319..f52de3b931b0c 100644
--- a/test/SemaCXX/warn-unused-attribute.cpp
+++ b/test/SemaCXX/warn-unused-attribute.cpp
@@ -1,20 +1,20 @@
// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -verify %s
-struct __attribute__((warn_unused)) Test
-{
- Test();
- ~Test();
- void use();
+struct __attribute__((warn_unused)) Test {
+ Test();
+ ~Test();
+ void use();
};
-struct TestNormal
-{
- TestNormal();
+struct TestNormal {
+ TestNormal();
};
-int main()
-{
- Test unused; // expected-warning {{unused variable 'unused'}}
- Test used;
- TestNormal normal;
- used.use();
+int main(void) {
+ Test unused; // expected-warning {{unused variable 'unused'}}
+ Test used;
+ TestNormal normal;
+ used.use();
+
+ int i __attribute__((warn_unused)) = 12; // expected-warning {{'warn_unused' attribute only applies to struct, union or class}}
+ return i;
}
diff --git a/test/SemaCXX/warn-unused-comparison.cpp b/test/SemaCXX/warn-unused-comparison.cpp
index 0153f213ba1fc..3afad585b6689 100644
--- a/test/SemaCXX/warn-unused-comparison.cpp
+++ b/test/SemaCXX/warn-unused-comparison.cpp
@@ -3,6 +3,10 @@
struct A {
bool operator==(const A&);
bool operator!=(const A&);
+ bool operator<(const A&);
+ bool operator>(const A&);
+ bool operator<=(const A&);
+ bool operator>=(const A&);
A operator|=(const A&);
operator bool();
};
@@ -15,6 +19,11 @@ void test() {
// expected-note {{use '=' to turn this equality comparison into an assignment}}
x != 7; // expected-warning {{inequality comparison result unused}} \
// expected-note {{use '|=' to turn this inequality comparison into an or-assignment}}
+ x < 7; // expected-warning {{relational comparison result unused}}
+ x > 7; // expected-warning {{relational comparison result unused}}
+ x <= 7; // expected-warning {{relational comparison result unused}}
+ x >= 7; // expected-warning {{relational comparison result unused}}
+
7 == x; // expected-warning {{equality comparison result unused}}
p == p; // expected-warning {{equality comparison result unused}} \
// expected-note {{use '=' to turn this equality comparison into an assignment}} \
@@ -25,6 +34,11 @@ void test() {
// expected-note {{use '=' to turn this equality comparison into an assignment}}
a != b; // expected-warning {{inequality comparison result unused}} \
// expected-note {{use '|=' to turn this inequality comparison into an or-assignment}}
+ a < b; // expected-warning {{relational comparison result unused}}
+ a > b; // expected-warning {{relational comparison result unused}}
+ a <= b; // expected-warning {{relational comparison result unused}}
+ a >= b; // expected-warning {{relational comparison result unused}}
+
A() == b; // expected-warning {{equality comparison result unused}}
if (42) x == 7; // expected-warning {{equality comparison result unused}} \
// expected-note {{use '=' to turn this equality comparison into an assignment}}
@@ -92,3 +106,30 @@ namespace PR10291 {
X<int> x;
}
+
+namespace PR19724 {
+class stream {
+} cout, cin;
+
+stream &operator<(stream &s, int);
+bool operator<(stream &s, stream &s2);
+
+void test() {
+ cout < 5; // no warning, operator returns a reference
+ cout < cin; // expected-warning {{relational comparison result unused}}
+}
+}
+
+namespace PR19791 {
+struct S {
+ void operator!=(int);
+ int operator==(int);
+};
+
+void test() {
+ S s;
+ s != 1;
+ s == 1; // expected-warning{{equality comparison result unused}}
+ // expected-note@-1{{use '=' to turn this equality comparison into an assignment}}
+}
+}
diff --git a/test/SemaCXX/warn-unused-filescoped.cpp b/test/SemaCXX/warn-unused-filescoped.cpp
index b0af5b3322706..df4c47e71787d 100644
--- a/test/SemaCXX/warn-unused-filescoped.cpp
+++ b/test/SemaCXX/warn-unused-filescoped.cpp
@@ -32,6 +32,13 @@ namespace test7
inline void bar(int, int) { }
};
+namespace pr19713 {
+#if __cplusplus >= 201103L
+ static constexpr int constexpr1() { return 1; }
+ constexpr int constexpr2() { return 2; }
+#endif
+}
+
#else
#define HEADER
#include "warn-unused-filescoped.cpp"
@@ -193,4 +200,12 @@ void bar() { void func() __attribute__((used)); }
static void func() {}
}
+namespace pr19713 {
+#if __cplusplus >= 201103L
+ // FIXME: We should warn on both of these.
+ static constexpr int constexpr3() { return 1; } // expected-warning {{unused}}
+ constexpr int constexpr4() { return 2; }
+#endif
+}
+
#endif
diff --git a/test/SemaCXX/warn-unused-label-error.cpp b/test/SemaCXX/warn-unused-label-error.cpp
new file mode 100644
index 0000000000000..66b616f3cf284
--- /dev/null
+++ b/test/SemaCXX/warn-unused-label-error.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -verify %s
+
+static int unused_local_static;
+
+namespace PR8455 {
+ void f() {
+ A: // expected-warning {{unused label 'A'}}
+ __attribute__((unused)) int i; // attribute applies to variable
+ B: // attribute applies to label
+ __attribute__((unused)); int j; // expected-warning {{unused variable 'j'}}
+ }
+
+ void g() {
+ C: // unused label 'C' will not appear here because an error has occurred
+ __attribute__((unused))
+ #pragma weak unused_local_static // expected-error {{expected ';' after __attribute__}}
+ ;
+ }
+
+ void h() {
+ D: // expected-warning {{unused label 'D'}}
+ #pragma weak unused_local_static
+ __attribute__((unused)) // expected-warning {{declaration does not declare anything}}
+ ;
+ }
+}
diff --git a/test/SemaCXX/warn-unused-value.cpp b/test/SemaCXX/warn-unused-value.cpp
index 5e43d3ec04222..4e1347cc307a5 100644
--- a/test/SemaCXX/warn-unused-value.cpp
+++ b/test/SemaCXX/warn-unused-value.cpp
@@ -32,7 +32,7 @@ void b(Foo f1, Foo f2) {
}
namespace test2 {
- extern "C" {
+ extern "C++" {
namespace std {
template<typename T> struct basic_string {
struct X {};
diff --git a/test/SemaCXX/warn-unused-variables.cpp b/test/SemaCXX/warn-unused-variables.cpp
index 93d2f6f9563b6..8dcbe7271d69d 100644
--- a/test/SemaCXX/warn-unused-variables.cpp
+++ b/test/SemaCXX/warn-unused-variables.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -Wno-c++1y-extensions -verify %s
template<typename T> void f() {
T t;
t = 17;
@@ -115,6 +115,28 @@ namespace PR11550 {
}
}
+namespace PR19305 {
+ template<typename T> int n = 0; // no warning
+ int a = n<int>;
+
+ template<typename T> const int l = 0; // no warning
+ int b = l<int>;
+
+ // PR19558
+ template<typename T> const int o = 0; // no warning
+ template<typename T> const int o<T*> = 0; // no warning
+ int c = o<int*>;
+
+ template<> int o<void> = 0; // no warning
+ int d = o<void>;
+
+ // FIXME: It'd be nice to warn here.
+ template<typename T> int m = 0;
+ template<typename T> int m<T*> = 0;
+
+ template<> const int m<void> = 0; // expected-warning {{unused variable}}
+}
+
namespace ctor_with_cleanups {
struct S1 {
~S1();
@@ -128,26 +150,3 @@ namespace ctor_with_cleanups {
}
#include "Inputs/warn-unused-variables.h"
-
-namespace PR8455 {
- void f() {
- A: // expected-warning {{unused label 'A'}}
- __attribute__((unused)) int i; // attribute applies to variable
- B: // attribute applies to label
- __attribute__((unused)); int j; // expected-warning {{unused variable 'j'}}
- }
-
- void g() {
- C: // unused label 'C' will not appear here because an error occurs
- __attribute__((unused))
- #pragma weak unused_local_static // expected-error {{expected ';' after __attribute__}}
- ;
- }
-
- void h() {
- D: // expected-warning {{unused label 'D'}}
- #pragma weak unused_local_static
- __attribute__((unused)) // expected-warning {{declaration does not declare anything}}
- ;
- }
-}
diff --git a/test/SemaCXX/warn-weak-vtables.cpp b/test/SemaCXX/warn-weak-vtables.cpp
index 135e0342596c4..671ff297cfa15 100644
--- a/test/SemaCXX/warn-weak-vtables.cpp
+++ b/test/SemaCXX/warn-weak-vtables.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -Wweak-vtables -Wweak-template-vtables
+// 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
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() { }
diff --git a/test/SemaCXX/windows-arm-valist.cpp b/test/SemaCXX/windows-arm-valist.cpp
new file mode 100644
index 0000000000000..d12be65e4f9f0
--- /dev/null
+++ b/test/SemaCXX/windows-arm-valist.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple thumbv7--windows-msvc -std=c++11 -verify -fsyntax-only %s
+// expected-no-diagnostics
+
+#include <stdarg.h>
+
+template <typename lhs_, typename rhs_>
+struct is_same { enum { value = 0 }; };
+
+template <typename type_>
+struct is_same<type_, type_> { enum { value = 1 }; };
+
+void check() {
+ va_list va;
+ char *cp;
+ static_assert(is_same<decltype(va), decltype(cp)>::value,
+ "type mismatch for va_list");
+}
diff --git a/test/SemaCXX/writable-strings-deprecated.cpp b/test/SemaCXX/writable-strings-deprecated.cpp
index b8f605b63d66a..f9258334980b8 100644
--- a/test/SemaCXX/writable-strings-deprecated.cpp
+++ b/test/SemaCXX/writable-strings-deprecated.cpp
@@ -1,14 +1,25 @@
// RUN: %clang_cc1 -fsyntax-only -Wno-deprecated-writable-strings -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-deprecated -Wdeprecated-increment-bool -verify %s
// RUN: %clang_cc1 -fsyntax-only -fwritable-strings -verify %s
// RUN: %clang_cc1 -fsyntax-only -Wno-write-strings -verify %s
// RUN: %clang_cc1 -fsyntax-only -Werror=c++11-compat -verify %s -DERROR
+// RUN: %clang_cc1 -fsyntax-only -Werror=deprecated -Wno-error=deprecated-increment-bool -verify %s -DERROR
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s -Wno-deprecated -Wdeprecated-increment-bool
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s -pedantic-errors -DERROR
// rdar://8827606
char *fun(void)
{
return "foo";
+#if __cplusplus >= 201103L
#ifdef ERROR
- // expected-error@-2 {{deprecated}}
+ // expected-error@-3 {{ISO C++11 does not allow conversion from string literal to 'char *'}}
+#else
+ // expected-warning@-5 {{ISO C++11 does not allow conversion from string literal to 'char *'}}
+#endif
+#elif defined(ERROR)
+ // expected-error@-8 {{deprecated}}
#endif
}