summaryrefslogtreecommitdiffstats
path: root/test/SemaCXX
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2013-12-22 00:07:40 +0000
committerdim <dim@FreeBSD.org>2013-12-22 00:07:40 +0000
commit952eddef9aff85b1e92626e89baaf7a360e2ac85 (patch)
treedf8df0b0067b381eab470a3b8f28d14a552a6340 /test/SemaCXX
parentea266cad53e3d49771fa38103913d3ec7a166694 (diff)
downloadFreeBSD-src-952eddef9aff85b1e92626e89baaf7a360e2ac85.zip
FreeBSD-src-952eddef9aff85b1e92626e89baaf7a360e2ac85.tar.gz
Vendor import of clang release_34 branch r197841 (effectively, 3.4 RC3):
https://llvm.org/svn/llvm-project/cfe/branches/release_34@197841
Diffstat (limited to 'test/SemaCXX')
-rw-r--r--test/SemaCXX/Inputs/lit.local.cfg1
-rw-r--r--test/SemaCXX/Inputs/register.h5
-rw-r--r--test/SemaCXX/Inputs/warn-unused-variables.h2
-rw-r--r--test/SemaCXX/MicrosoftCompatibility.cpp16
-rw-r--r--test/SemaCXX/MicrosoftExtensions.cpp79
-rw-r--r--test/SemaCXX/PR10447.cpp4
-rw-r--r--test/SemaCXX/PR12778.cpp7
-rw-r--r--test/SemaCXX/PR9572.cpp2
-rw-r--r--test/SemaCXX/__try.cpp20
-rw-r--r--test/SemaCXX/abstract.cpp36
-rw-r--r--test/SemaCXX/access.cpp34
-rw-r--r--test/SemaCXX/addr-of-overloaded-function-casting.cpp8
-rw-r--r--test/SemaCXX/addr-of-overloaded-function.cpp37
-rw-r--r--test/SemaCXX/alignment-of-derived-class.cpp41
-rw-r--r--test/SemaCXX/alignof-sizeof-reference.cpp4
-rw-r--r--test/SemaCXX/alignof.cpp14
-rw-r--r--test/SemaCXX/ambiguous-conversion-show-overload.cpp2
-rw-r--r--test/SemaCXX/anonymous-union.cpp9
-rw-r--r--test/SemaCXX/ast-print.cpp16
-rw-r--r--test/SemaCXX/attr-aligned.cpp16
-rw-r--r--test/SemaCXX/attr-cleanup-gcc.cpp16
-rw-r--r--test/SemaCXX/attr-cleanup.cpp29
-rw-r--r--test/SemaCXX/attr-common.cpp3
-rw-r--r--test/SemaCXX/attr-cxx0x.cpp4
-rw-r--r--test/SemaCXX/attr-deprecated.cpp6
-rw-r--r--test/SemaCXX/attr-no-sanitize-address.cpp2
-rw-r--r--test/SemaCXX/attr-no-sanitize-memory.cpp2
-rw-r--r--test/SemaCXX/attr-no-sanitize-thread.cpp2
-rw-r--r--test/SemaCXX/attr-print.cpp6
-rw-r--r--test/SemaCXX/attr-selectany.cpp33
-rw-r--r--test/SemaCXX/attr-used.cpp5
-rw-r--r--test/SemaCXX/attr-weakref.cpp2
-rw-r--r--test/SemaCXX/blocks-1.cpp18
-rw-r--r--test/SemaCXX/bool.cpp2
-rw-r--r--test/SemaCXX/builtins.cpp22
-rw-r--r--test/SemaCXX/c99.cpp2
-rw-r--r--test/SemaCXX/calling-conv-compat.cpp387
-rw-r--r--test/SemaCXX/captured-statements.cpp7
-rw-r--r--test/SemaCXX/cast-conversion.cpp18
-rw-r--r--test/SemaCXX/class-base-member-init.cpp10
-rw-r--r--test/SemaCXX/class-layout.cpp469
-rw-r--r--test/SemaCXX/class.cpp6
-rw-r--r--test/SemaCXX/compare.cpp67
-rw-r--r--test/SemaCXX/complex-overload.cpp12
-rw-r--r--test/SemaCXX/compound-literal.cpp10
-rw-r--r--test/SemaCXX/conditional-expr.cpp2
-rw-r--r--test/SemaCXX/const-cast.cpp2
-rw-r--r--test/SemaCXX/constant-expression-cxx11.cpp388
-rw-r--r--test/SemaCXX/constant-expression-cxx1y.cpp468
-rw-r--r--test/SemaCXX/constexpr-backtrace-limit.cpp8
-rw-r--r--test/SemaCXX/constexpr-duffs-device.cpp32
-rw-r--r--test/SemaCXX/constexpr-steps.cpp17
-rw-r--r--test/SemaCXX/constexpr-turing.cpp16
-rw-r--r--test/SemaCXX/constexpr-value-init.cpp2
-rw-r--r--test/SemaCXX/conversion-delete-expr.cpp24
-rw-r--r--test/SemaCXX/conversion-function.cpp4
-rw-r--r--test/SemaCXX/conversion-incomplete-type.cpp23
-rw-r--r--test/SemaCXX/crashes.cpp47
-rw-r--r--test/SemaCXX/cxx0x-class.cpp2
-rw-r--r--test/SemaCXX/cxx0x-compat.cpp9
-rw-r--r--test/SemaCXX/cxx0x-initializer-aggregates.cpp27
-rw-r--r--test/SemaCXX/cxx0x-initializer-references.cpp25
-rw-r--r--test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp24
-rw-r--r--test/SemaCXX/cxx0x-nontrivial-union.cpp22
-rw-r--r--test/SemaCXX/cxx11-attr-print.cpp5
-rw-r--r--test/SemaCXX/cxx11-crashes.cpp4
-rw-r--r--test/SemaCXX/cxx11-gnu-attrs.cpp5
-rw-r--r--test/SemaCXX/cxx11-thread-local-print.cpp6
-rw-r--r--test/SemaCXX/cxx1y-array-runtime-bound.cpp68
-rw-r--r--test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp177
-rw-r--r--test/SemaCXX/cxx1y-deduced-return-type.cpp152
-rw-r--r--test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp1363
-rw-r--r--test/SemaCXX/cxx1y-generic-lambdas.cpp908
-rw-r--r--test/SemaCXX/cxx1y-init-captures.cpp169
-rw-r--r--test/SemaCXX/cxx1y-sized-deallocation.cpp17
-rw-r--r--test/SemaCXX/cxx1y-user-defined-literals.cpp44
-rw-r--r--test/SemaCXX/cxx1y-variable-templates_in_class.cpp299
-rw-r--r--test/SemaCXX/cxx1y-variable-templates_top_level.cpp434
-rw-r--r--test/SemaCXX/cxx98-compat-pedantic.cpp18
-rw-r--r--test/SemaCXX/cxx98-compat.cpp86
-rw-r--r--test/SemaCXX/dcl_ambig_res.cpp4
-rw-r--r--test/SemaCXX/decl-expr-ambiguity.cpp1
-rw-r--r--test/SemaCXX/decl-init-ref.cpp11
-rw-r--r--test/SemaCXX/decl-microsoft-call-conv.cpp143
-rw-r--r--test/SemaCXX/decltype.cpp8
-rw-r--r--test/SemaCXX/default-assignment-operator.cpp8
-rw-r--r--test/SemaCXX/default1.cpp11
-rw-r--r--test/SemaCXX/deprecated.cpp67
-rw-r--r--test/SemaCXX/destructor.cpp4
-rw-r--r--test/SemaCXX/dynamic-cast.cpp2
-rw-r--r--test/SemaCXX/enum-increment.cpp16
-rw-r--r--test/SemaCXX/enum-scoped.cpp30
-rw-r--r--test/SemaCXX/enum-unscoped-nonexistent.cpp4
-rw-r--r--test/SemaCXX/err_init_conversion_failed.cpp45
-rw-r--r--test/SemaCXX/explicit.cpp91
-rw-r--r--test/SemaCXX/expression-traits.cpp4
-rw-r--r--test/SemaCXX/extern-c.cpp174
-rw-r--r--test/SemaCXX/flexible-array-test.cpp4
-rw-r--r--test/SemaCXX/for-range-examples.cpp31
-rw-r--r--test/SemaCXX/format-strings-0x.cpp4
-rw-r--r--test/SemaCXX/friend.cpp138
-rw-r--r--test/SemaCXX/function-pointer-arguments.cpp52
-rw-r--r--test/SemaCXX/function-redecl.cpp18
-rw-r--r--test/SemaCXX/function-type-qual.cpp8
-rw-r--r--test/SemaCXX/gnu-flags.cpp76
-rw-r--r--test/SemaCXX/i-c-e-cxx.cpp2
-rw-r--r--test/SemaCXX/implicit-virtual-member-functions.cpp6
-rw-r--r--test/SemaCXX/inherit.cpp3
-rw-r--r--test/SemaCXX/init-priority-attr.cpp4
-rw-r--r--test/SemaCXX/lambda-expressions.cpp65
-rw-r--r--test/SemaCXX/libstdcxx_pointer_return_false_hack.cpp34
-rw-r--r--test/SemaCXX/linkage-spec.cpp61
-rw-r--r--test/SemaCXX/linkage2.cpp55
-rw-r--r--test/SemaCXX/member-expr.cpp54
-rw-r--r--test/SemaCXX/member-init.cpp11
-rw-r--r--test/SemaCXX/member-pointer-ms.cpp5
-rw-r--r--test/SemaCXX/microsoft-dtor-lookup.cpp87
-rw-r--r--test/SemaCXX/microsoft-new-delete.cpp12
-rw-r--r--test/SemaCXX/missing-members.cpp10
-rw-r--r--test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp8
-rw-r--r--test/SemaCXX/ms-overload-entry-point.cpp21
-rw-r--r--test/SemaCXX/ms-wchar.cpp12
-rw-r--r--test/SemaCXX/ms_struct.cpp18
-rw-r--r--test/SemaCXX/ms_wide_bitfield.cpp9
-rw-r--r--test/SemaCXX/neon-vector-types.cpp2
-rw-r--r--test/SemaCXX/nested-name-spec.cpp22
-rw-r--r--test/SemaCXX/new-delete-0x.cpp4
-rw-r--r--test/SemaCXX/new-delete.cpp15
-rw-r--r--test/SemaCXX/no-rtti.cpp19
-rw-r--r--test/SemaCXX/no-warn-unused-const-variables.cpp6
-rw-r--r--test/SemaCXX/nullptr.cpp3
-rw-r--r--test/SemaCXX/offsetof.cpp10
-rw-r--r--test/SemaCXX/operator-arrow-depth.cpp26
-rw-r--r--test/SemaCXX/overload-decl.cpp8
-rw-r--r--test/SemaCXX/overloaded-operator.cpp20
-rw-r--r--test/SemaCXX/parentheses.cpp8
-rw-r--r--test/SemaCXX/pr13394-crash-on-invalid.cpp17
-rw-r--r--test/SemaCXX/predefined-expr.cpp103
-rw-r--r--test/SemaCXX/qualified-id-lookup.cpp6
-rw-r--r--test/SemaCXX/references.cpp7
-rw-r--r--test/SemaCXX/scope-check.cpp21
-rw-r--r--test/SemaCXX/self-comparison.cpp23
-rw-r--r--test/SemaCXX/static-data-member.cpp17
-rw-r--r--test/SemaCXX/storage-class.cpp2
-rw-r--r--test/SemaCXX/string-init.cpp40
-rw-r--r--test/SemaCXX/string-plus-char.cpp32
-rw-r--r--test/SemaCXX/struct-class-redecl.cpp2
-rw-r--r--test/SemaCXX/switch.cpp15
-rw-r--r--test/SemaCXX/trailing-return-0x.cpp8
-rw-r--r--test/SemaCXX/type-traits.cpp65
-rw-r--r--test/SemaCXX/typo-correction-pt2.cpp201
-rw-r--r--test/SemaCXX/typo-correction.cpp96
-rw-r--r--test/SemaCXX/uninitialized.cpp211
-rw-r--r--test/SemaCXX/unknown-type-name.cpp4
-rw-r--r--test/SemaCXX/using-decl-1.cpp42
-rw-r--r--test/SemaCXX/using-decl-templates.cpp14
-rw-r--r--test/SemaCXX/vararg-non-pod.cpp50
-rw-r--r--test/SemaCXX/vector.cpp19
-rw-r--r--test/SemaCXX/virtual-base-used.cpp8
-rw-r--r--test/SemaCXX/virtual-member-functions-key-function.cpp4
-rw-r--r--test/SemaCXX/virtual-override-x86.cpp4
-rw-r--r--test/SemaCXX/virtuals.cpp6
-rw-r--r--test/SemaCXX/warn-consumed-analysis.cpp795
-rw-r--r--test/SemaCXX/warn-consumed-parsing.cpp55
-rw-r--r--test/SemaCXX/warn-dangling-field.cpp16
-rw-r--r--test/SemaCXX/warn-div-or-rem-by-zero.cpp21
-rw-r--r--test/SemaCXX/warn-empty-body.cpp5
-rw-r--r--test/SemaCXX/warn-func-not-needed.cpp9
-rw-r--r--test/SemaCXX/warn-global-constructors.cpp6
-rw-r--r--test/SemaCXX/warn-logical-not-compare.cpp194
-rw-r--r--test/SemaCXX/warn-loop-analysis.cpp108
-rw-r--r--test/SemaCXX/warn-member-not-needed.cpp11
-rw-r--r--test/SemaCXX/warn-missing-variable-declarations.cpp6
-rw-r--r--test/SemaCXX/warn-reinterpret-base-class.cpp2
-rw-r--r--test/SemaCXX/warn-thread-safety-analysis.cpp413
-rw-r--r--test/SemaCXX/warn-thread-safety-parsing.cpp60
-rw-r--r--test/SemaCXX/warn-unreachable.cpp4
-rw-r--r--test/SemaCXX/warn-unsequenced.cpp14
-rw-r--r--test/SemaCXX/warn-unused-attribute.cpp20
-rw-r--r--test/SemaCXX/warn-unused-filescoped.cpp81
-rw-r--r--test/SemaCXX/warn-unused-private-field.cpp2
-rw-r--r--test/SemaCXX/warn-unused-result.cpp16
-rw-r--r--test/SemaCXX/warn-unused-value.cpp20
-rw-r--r--test/SemaCXX/warn-unused-variables.cpp25
-rw-r--r--test/SemaCXX/warn-using-namespace-in-header.cpp9
-rw-r--r--test/SemaCXX/writable-strings-deprecated.cpp4
186 files changed, 10403 insertions, 474 deletions
diff --git a/test/SemaCXX/Inputs/lit.local.cfg b/test/SemaCXX/Inputs/lit.local.cfg
deleted file mode 100644
index e6f55ee..0000000
--- a/test/SemaCXX/Inputs/lit.local.cfg
+++ /dev/null
@@ -1 +0,0 @@
-config.suffixes = []
diff --git a/test/SemaCXX/Inputs/register.h b/test/SemaCXX/Inputs/register.h
new file mode 100644
index 0000000..3c412ee
--- /dev/null
+++ b/test/SemaCXX/Inputs/register.h
@@ -0,0 +1,5 @@
+#pragma GCC system_header
+#pragma once
+
+inline void f() { register int k; }
+#define to_int(x) ({ register int n = (x); n; })
diff --git a/test/SemaCXX/Inputs/warn-unused-variables.h b/test/SemaCXX/Inputs/warn-unused-variables.h
index 5fac459..56990e0 100644
--- a/test/SemaCXX/Inputs/warn-unused-variables.h
+++ b/test/SemaCXX/Inputs/warn-unused-variables.h
@@ -7,5 +7,7 @@ class A {};
class B {
static A a;
+ static A b;
+ static const int x = sizeof(b);
};
}
diff --git a/test/SemaCXX/MicrosoftCompatibility.cpp b/test/SemaCXX/MicrosoftCompatibility.cpp
index 6a48f36..05037ac 100644
--- a/test/SemaCXX/MicrosoftCompatibility.cpp
+++ b/test/SemaCXX/MicrosoftCompatibility.cpp
@@ -178,3 +178,19 @@ namespace PR11791 {
del((void*)a); // expected-note {{in instantiation of function template specialization}}
}
}
+
+namespace IntToNullPtrConv {
+ struct Foo {
+ static const int ZERO = 0;
+ typedef void (Foo::*MemberFcnPtr)();
+ };
+
+ struct Bar {
+ const Foo::MemberFcnPtr pB;
+ };
+
+ Bar g_bar = { (Foo::MemberFcnPtr)Foo::ZERO };
+
+ template<int N> int *get_n() { return N; } // expected-warning {{expression which evaluates to zero treated as a null pointer constant}}
+ int *g_nullptr = get_n<0>(); // expected-note {{in instantiation of function template specialization}}
+}
diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp
index ab3ff69..c5b45a2 100644
--- a/test/SemaCXX/MicrosoftExtensions.cpp
+++ b/test/SemaCXX/MicrosoftExtensions.cpp
@@ -167,8 +167,14 @@ void pointer_to_integral_type_conv(char* ptr) {
short sh = (short)ptr;
ch = (char)ptr;
sh = (short)ptr;
-}
+ // These are valid C++.
+ bool b = (bool)ptr;
+ b = static_cast<bool>(ptr);
+
+ // This is bad.
+ b = reinterpret_cast<bool>(ptr); // expected-error {{cast from pointer to smaller type 'bool' loses information}}
+}
namespace friend_as_a_forward_decl {
@@ -333,3 +339,74 @@ void TestSP9() {
c3.g(); // Overloaded incdec op operand
c3.h(); // Overloaded unary op operand
}
+
+union u {
+ int *i1;
+ int &i2; // expected-warning {{union member 'i2' has reference type 'int &', which is a Microsoft extension}}
+};
+
+// Property getter using reference.
+struct SP11 {
+ __declspec(property(get=GetV)) int V;
+ int _v;
+ int& GetV() { return _v; }
+ void UseV();
+ void TakePtr(int *) {}
+ void TakeRef(int &) {}
+ void TakeVal(int) {}
+};
+
+void SP11::UseV() {
+ TakePtr(&V);
+ TakeRef(V);
+ TakeVal(V);
+}
+
+struct StructWithUnnamedMember {
+ __declspec(property(get=GetV)) int : 10; // expected-error {{anonymous property is not supported}}
+};
+
+namespace rdar14250378 {
+ class Bar {};
+
+ namespace NyNamespace {
+ class Foo {
+ public:
+ Bar* EnsureBar();
+ };
+
+ class Baz : public Foo {
+ public:
+ friend class Bar;
+ };
+
+ Bar* Foo::EnsureBar() {
+ return 0;
+ }
+ }
+}
+
+// expected-error@+1 {{'sealed' keyword not permitted with interface types}}
+__interface InterfaceWithSealed sealed {
+};
+
+struct SomeBase {
+ virtual void OverrideMe();
+
+ // expected-note@+2 {{overridden virtual function is here}}
+ // expected-warning@+1 {{'sealed' keyword is a Microsoft extension}}
+ virtual void SealedFunction() sealed;
+};
+
+// expected-note@+2 {{'SealedType' declared here}}
+// expected-warning@+1 {{'sealed' keyword is a Microsoft extension}}
+struct SealedType sealed : SomeBase {
+ // expected-error@+1 {{declaration of 'SealedFunction' overrides a 'sealed' function}}
+ virtual void SealedFunction();
+
+ // expected-warning@+1 {{'override' keyword is a C++11 extension}}
+ virtual void OverrideMe() override;
+};
+
+// expected-error@+1 {{base 'SealedType' is marked 'sealed'}}
+struct InheritFromSealed : SealedType {};
diff --git a/test/SemaCXX/PR10447.cpp b/test/SemaCXX/PR10447.cpp
index 5ba74aa..0c57177 100644
--- a/test/SemaCXX/PR10447.cpp
+++ b/test/SemaCXX/PR10447.cpp
@@ -4,7 +4,7 @@
// PR12223
namespace test1 {
namespace N {
- extern "C" void f(struct S*);
+ extern "C" void f_test1(struct S*);
void g(S*);
}
namespace N {
@@ -17,7 +17,7 @@ namespace test1 {
// PR10447
namespace test2 {
extern "C" {
- void f(struct Bar*) { }
+ void f_test2(struct Bar*) { }
test2::Bar *ptr;
}
}
diff --git a/test/SemaCXX/PR12778.cpp b/test/SemaCXX/PR12778.cpp
new file mode 100644
index 0000000..f4d25f3
--- /dev/null
+++ b/test/SemaCXX/PR12778.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void operator delete() throw(void*); // expected-error{{'operator delete' must have at least one parameter}}
+void* allocate(int __n) {
+ return ::operator new(__n);
+}
+
diff --git a/test/SemaCXX/PR9572.cpp b/test/SemaCXX/PR9572.cpp
index b475b57..d6dc2e0 100644
--- a/test/SemaCXX/PR9572.cpp
+++ b/test/SemaCXX/PR9572.cpp
@@ -7,7 +7,7 @@ struct Foo : public Base { // expected-error {{base class 'Base' has private des
Foo();
};
struct Bar : public Foo {
- Bar() { } // expected-note {{implicit default destructor for 'Foo' first required here}}
+ Bar() { } // expected-note {{implicit destructor for 'Foo' first required here}}
};
struct Baz {
Foo f;
diff --git a/test/SemaCXX/__try.cpp b/test/SemaCXX/__try.cpp
index a0f503a..1c45581 100644
--- a/test/SemaCXX/__try.cpp
+++ b/test/SemaCXX/__try.cpp
@@ -57,3 +57,23 @@ int main()
}
return e;
}
+
+namespace PR17584 {
+template <typename>
+void Except() {
+ __try {
+ } __except(true) {
+ }
+}
+
+template <typename>
+void Finally() {
+ __try {
+ } __finally {
+ }
+}
+
+template void Except<void>();
+template void Finally<void>();
+
+}
diff --git a/test/SemaCXX/abstract.cpp b/test/SemaCXX/abstract.cpp
index e20a890..d7e2d0a 100644
--- a/test/SemaCXX/abstract.cpp
+++ b/test/SemaCXX/abstract.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wabstract-vbase-init
#ifndef __GXX_EXPERIMENTAL_CXX0X__
#define __CONCAT(__X, __Y) __CONCAT1(__X, __Y)
@@ -250,6 +250,13 @@ namespace test4 {
};
}
+namespace test5 {
+ struct A { A(int); virtual ~A() = 0; }; // expected-note {{pure virtual method}}
+ const A &a = 0; // expected-error {{abstract class}}
+ void f(const A &a = 0); // expected-error {{abstract class}}
+ void g() { f(0); } // expected-error {{abstract class}}
+}
+
// PR9247: Crash on invalid in clang::Sema::ActOnFinishCXXMemberSpecification
namespace pr9247 {
struct A {
@@ -273,3 +280,30 @@ namespace pr12658 {
foo(C(99)); // expected-error {{allocating an object of abstract class type 'pr12658::C'}}
}
}
+
+namespace pr16659 {
+ struct A {
+ A(int);
+ virtual void x() = 0; // expected-note {{unimplemented pure virtual method 'x' in 'RedundantInit'}}
+ };
+ struct B : virtual A {};
+ struct C : B {
+ C() : A(37) {}
+ void x() override {}
+ };
+
+ struct X {
+ friend class Z;
+ private:
+ X &operator=(const X&);
+ };
+ struct Y : virtual X { // expected-note {{::X' has an inaccessible copy assignment}}
+ virtual ~Y() = 0;
+ };
+ struct Z : Y {}; // expected-note {{::Y' has a deleted copy assignment}}
+ void f(Z &a, const Z &b) { a = b; } // expected-error {{copy assignment operator is implicitly deleted}}
+
+ struct RedundantInit : virtual A {
+ RedundantInit() : A(0) {} // expected-warning {{initializer for virtual base class 'pr16659::A' of abstract class 'RedundantInit' will never be used}}
+ };
+}
diff --git a/test/SemaCXX/access.cpp b/test/SemaCXX/access.cpp
index 50f2eff..5ccd418 100644
--- a/test/SemaCXX/access.cpp
+++ b/test/SemaCXX/access.cpp
@@ -26,9 +26,11 @@ private:
namespace test1 {
class A {
private:
- class X; // expected-note {{previously declared 'private' here}}
+ class X; // expected-note {{previously declared 'private' here}} \
+ // expected-note {{previous declaration is here}}
public:
- class X; // expected-error {{'X' redeclared with 'public' access}}
+ class X; // expected-error {{'X' redeclared with 'public' access}} \
+ // expected-warning {{class member cannot be redeclared}}
class X {};
};
}
@@ -106,3 +108,31 @@ namespace PR15209 {
}
}
}
+
+namespace PR7434 {
+ namespace comment0 {
+ template <typename T> struct X;
+ namespace N {
+ class Y {
+ template<typename T> friend struct X;
+ int t; // expected-note {{here}}
+ };
+ }
+ template<typename T> struct X {
+ X() { (void)N::Y().t; } // expected-error {{private}}
+ };
+ X<char> x;
+ }
+ namespace comment2 {
+ struct X;
+ namespace N {
+ class Y {
+ friend struct X;
+ int t; // expected-note {{here}}
+ };
+ }
+ struct X {
+ X() { (void)N::Y().t; } // expected-error {{private}}
+ };
+ }
+}
diff --git a/test/SemaCXX/addr-of-overloaded-function-casting.cpp b/test/SemaCXX/addr-of-overloaded-function-casting.cpp
index cfd55ee..784c8a0 100644
--- a/test/SemaCXX/addr-of-overloaded-function-casting.cpp
+++ b/test/SemaCXX/addr-of-overloaded-function-casting.cpp
@@ -4,8 +4,12 @@ void g();
void f(); // expected-note 9{{candidate function}}
void f(int); // expected-note 9{{candidate function}}
-template<class T> void t(T); // expected-note 6{{candidate function}}
-template<class T> void t(T*); // expected-note 6{{candidate function}}
+template <class T>
+void t(T); // expected-note 3{{candidate function}} \
+ // expected-note 3{{candidate template ignored: could not match 'void' against 'int'}}
+template <class T>
+void t(T *); // expected-note 3{{candidate function}} \
+ // expected-note 3{{candidate template ignored: could not match 'void' against 'int'}}
template<class T> void u(T);
diff --git a/test/SemaCXX/addr-of-overloaded-function.cpp b/test/SemaCXX/addr-of-overloaded-function.cpp
index 096f748..230a1eb 100644
--- a/test/SemaCXX/addr-of-overloaded-function.cpp
+++ b/test/SemaCXX/addr-of-overloaded-function.cpp
@@ -57,11 +57,12 @@ struct B
struct C {
C &getC() {
- return makeAC; // expected-error{{reference to non-static member function must be called}}
+ return makeAC; // expected-error{{reference to non-static member function must be called; did you mean to call it with no arguments?}}
}
- C &makeAC();
- const C &makeAC() const;
+ // FIXME: filter by const so we can unambiguously suggest '()' & point to just the one candidate, probably
+ C &makeAC(); // expected-note{{possible target for call}}
+ const C &makeAC() const; // expected-note{{possible target for call}}
static void f(); // expected-note{{candidate function}}
static void f(int); // expected-note{{candidate function}}
@@ -69,6 +70,32 @@ struct C {
void g() {
int (&fp)() = f; // expected-error{{address of overloaded function 'f' does not match required type 'int ()'}}
}
+
+ template<typename T>
+ void q1(int); // expected-note{{possible target for call}}
+ template<typename T>
+ void q2(T t = T()); // expected-note{{possible target for call}}
+ template<typename T>
+ void q3(); // expected-note{{possible target for call}}
+ template<typename T1, typename T2>
+ void q4(); // expected-note{{possible target for call}}
+ template<typename T1 = int> // expected-warning{{default template arguments for a function template are a C++11 extension}}
+ void q5(); // expected-note{{possible target for call}}
+
+ 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$}}
+ // 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?}}
+ // Suggest '()' since no arguments are required & the type argument is
+ // 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$}}
+ // 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?}}
+ }
};
// PR6886
@@ -208,3 +235,7 @@ namespace test1 {
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')}}
}
+
+template <typename T> class PR16561 {
+ virtual bool f() { if (f) {} return false; } // expected-error {{reference to non-static member function must be called}}
+};
diff --git a/test/SemaCXX/alignment-of-derived-class.cpp b/test/SemaCXX/alignment-of-derived-class.cpp
new file mode 100644
index 0000000..28c1fa9
--- /dev/null
+++ b/test/SemaCXX/alignment-of-derived-class.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// expected-no-diagnostics
+
+// Test that the alignment of a empty direct base class is correctly
+// inherited by the derived class.
+
+struct A {
+} __attribute__ ((aligned(16)));
+
+static_assert(__alignof(A) == 16, "A should be aligned to 16 bytes");
+
+struct B1 : public A {
+};
+
+static_assert(__alignof(B1) == 16, "B1 should be aligned to 16 bytes");
+
+struct B2 : public A {
+} __attribute__ ((aligned(2)));
+
+static_assert(__alignof(B2) == 16, "B2 should be aligned to 16 bytes");
+
+struct B3 : public A {
+} __attribute__ ((aligned(4)));
+
+static_assert(__alignof(B3) == 16, "B3 should be aligned to 16 bytes");
+
+struct B4 : public A {
+} __attribute__ ((aligned(8)));
+
+static_assert(__alignof(B4) == 16, "B4 should be aligned to 16 bytes");
+
+struct B5 : public A {
+} __attribute__ ((aligned(16)));
+
+static_assert(__alignof(B5) == 16, "B5 should be aligned to 16 bytes");
+
+struct B6 : public A {
+} __attribute__ ((aligned(32)));
+
+static_assert(__alignof(B6) == 32, "B6 should be aligned to 32 bytes");
+
diff --git a/test/SemaCXX/alignof-sizeof-reference.cpp b/test/SemaCXX/alignof-sizeof-reference.cpp
index d76fcf5..3e37d61 100644
--- a/test/SemaCXX/alignof-sizeof-reference.cpp
+++ b/test/SemaCXX/alignof-sizeof-reference.cpp
@@ -10,8 +10,8 @@ void test() {
static_assert(sizeof(char&) == 1, "bad size");
}
-void f(); // expected-note{{possible target for call}}
-void f(int); // expected-note{{possible target for call}}
+int f(); // expected-note{{possible target for call}}
+int f(int); // expected-note{{possible target for call}}
void g() {
sizeof(&f); // expected-error{{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} \
// expected-warning{{expression result unused}}
diff --git a/test/SemaCXX/alignof.cpp b/test/SemaCXX/alignof.cpp
index a9de1ad..f0b89ee 100644
--- a/test/SemaCXX/alignof.cpp
+++ b/test/SemaCXX/alignof.cpp
@@ -9,7 +9,7 @@ struct S0 {
auto test2() -> char(&)[__alignof__(x)]; // expected-error {{invalid application of 'alignof' to a field of a class still being defined}}
};
-struct S1; // expected-note 5 {{forward declaration}}
+struct S1; // expected-note 6 {{forward declaration}}
extern S1 s1;
const int test3 = __alignof__(s1); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}}
@@ -50,3 +50,15 @@ struct S4 {
static const int test1 = __alignof__(S0::x);
auto test2() -> char(&)[__alignof__(x)];
};
+
+// Regression test for asking for the alignment of a field within an invalid
+// record.
+struct S5 {
+ S1 s; // expected-error {{incomplete type}}
+ int x;
+};
+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}}
diff --git a/test/SemaCXX/ambiguous-conversion-show-overload.cpp b/test/SemaCXX/ambiguous-conversion-show-overload.cpp
index 6429651..5cd26fc 100644
--- a/test/SemaCXX/ambiguous-conversion-show-overload.cpp
+++ b/test/SemaCXX/ambiguous-conversion-show-overload.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fshow-overloads=best -fno-caret-diagnostics %s 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -fsyntax-only -fshow-overloads=best -fno-caret-diagnostics %s 2>&1 | FileCheck %s
struct S {
S(void*);
S(char*);
diff --git a/test/SemaCXX/anonymous-union.cpp b/test/SemaCXX/anonymous-union.cpp
index 9c2cf24..fde27b0 100644
--- a/test/SemaCXX/anonymous-union.cpp
+++ b/test/SemaCXX/anonymous-union.cpp
@@ -197,3 +197,12 @@ namespace PR8326 {
Foo<int> baz;
}
+
+namespace PR16630 {
+ struct A { union { int x; float y; }; }; // expected-note {{member is declared here}}
+ struct B : private A { using A::x; } b; // expected-note 2 {{private}}
+ void foo () {
+ b.x = 10;
+ b.y = 0; // expected-error {{cannot cast 'struct B' to its private base class 'PR16630::A'}} expected-error {{'y' is a private member of 'PR16630::A'}}
+ }
+}
diff --git a/test/SemaCXX/ast-print.cpp b/test/SemaCXX/ast-print.cpp
index 921f7d8..a1975b4 100644
--- a/test/SemaCXX/ast-print.cpp
+++ b/test/SemaCXX/ast-print.cpp
@@ -103,6 +103,7 @@ int test11() {
struct DefaultArgClass
{
DefaultArgClass(int a = 1) {}
+ DefaultArgClass(int a, int b, int c = 1) {}
};
struct NoArgClass
@@ -124,6 +125,8 @@ struct ConstrWithCleanupsClass
// CHECK: test12
// CHECK-NEXT: DefaultArgClass useDefaultArg;
// CHECK-NEXT: DefaultArgClass overrideDefaultArg(1);
+// CHECK-NEXT: DefaultArgClass(1, 2);
+// CHECK-NEXT: DefaultArgClass(1, 2, 3);
// CHECK-NEXT: NoArgClass noArg;
// CHECK-NEXT: ConstrWithCleanupsClass cwcNoArg;
// CHECK-NEXT: ConstrWithCleanupsClass cwcOverrideArg(48);
@@ -131,6 +134,8 @@ struct ConstrWithCleanupsClass
void test12() {
DefaultArgClass useDefaultArg;
DefaultArgClass overrideDefaultArg(1);
+ DefaultArgClass tempWithDefaultArg = DefaultArgClass(1, 2);
+ DefaultArgClass tempWithExplictArg = DefaultArgClass(1, 2, 3);
NoArgClass noArg;
ConstrWithCleanupsClass cwcNoArg;
ConstrWithCleanupsClass cwcOverrideArg(48);
@@ -148,3 +153,14 @@ void test13() {
__c11_atomic_load(&i, 0);
}
+
+// CHECK: void test14() {
+// CHECK: struct X {
+// CHECK: union {
+// CHECK: int x;
+// CHECK: } x;
+// CHECK: };
+// CHECK: }
+void test14() {
+ struct X { union { int x; } x; };
+}
diff --git a/test/SemaCXX/attr-aligned.cpp b/test/SemaCXX/attr-aligned.cpp
new file mode 100644
index 0000000..4b9c55f
--- /dev/null
+++ b/test/SemaCXX/attr-aligned.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+typedef struct S1 { char c; } S1 __attribute__((aligned(8)));
+static_assert(alignof(S1) == 8, "attribute ignored");
+static_assert(alignof(struct S1) == 1, "attribute applied to original type");
+
+typedef struct __attribute__((aligned(8))) S2 { char c; } AS;
+static_assert(alignof(S2) == 8, "attribute not propagated");
+static_assert(alignof(struct S2) == 8, "attribute ignored");
+
+typedef struct __attribute__((aligned(4))) S3 {
+ char c;
+} S3 __attribute__((aligned(8)));
+static_assert(alignof(S3) == 8, "attribute ignored");
+static_assert(alignof(struct S3) == 4, "attribute clobbered");
diff --git a/test/SemaCXX/attr-cleanup-gcc.cpp b/test/SemaCXX/attr-cleanup-gcc.cpp
new file mode 100644
index 0000000..daebbe6
--- /dev/null
+++ b/test/SemaCXX/attr-cleanup-gcc.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Wgcc-compat
+
+namespace N {
+ void c1(int *a) {}
+}
+
+void c2(int *a) {}
+
+template <typename Ty>
+void c3(Ty *a) {}
+
+void t3() {
+ int v1 __attribute__((cleanup(N::c1))); // expected-warning {{GCC does not allow the 'cleanup' attribute argument to be anything other than a simple identifier}}
+ int v2 __attribute__((cleanup(c2)));
+ int v3 __attribute__((cleanup(c3<int>))); // expected-warning {{GCC does not allow the 'cleanup' attribute argument to be anything other than a simple identifier}}
+}
diff --git a/test/SemaCXX/attr-cleanup.cpp b/test/SemaCXX/attr-cleanup.cpp
new file mode 100644
index 0000000..32d1068
--- /dev/null
+++ b/test/SemaCXX/attr-cleanup.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Wno-gcc-compat
+
+namespace N {
+ void c1(int *a) {}
+}
+
+class C {
+ static void c2(int *a) {} // expected-note {{implicitly declared private here}} expected-note {{implicitly declared private here}}
+};
+
+void t1() {
+ int v1 __attribute__((cleanup(N::c1)));
+ int v2 __attribute__((cleanup(N::c2))); // expected-error {{no member named 'c2' in namespace 'N'}}
+ int v3 __attribute__((cleanup(C::c2))); // expected-error {{'c2' is a private member of 'C'}}
+}
+
+class D : public C {
+ void t2() {
+ int v1 __attribute__((cleanup(c2))); // expected-error {{'c2' is a private member of 'C'}}
+ }
+};
+
+namespace E {
+ void c3(int *a) {} // expected-note {{candidate function}}
+ void c3() {} // expected-note {{candidate function}}
+ void t3() {
+ int v1 __attribute__((cleanup(c3))); // expected-error {{'c3' is not a single function}}
+ }
+}
diff --git a/test/SemaCXX/attr-common.cpp b/test/SemaCXX/attr-common.cpp
new file mode 100644
index 0000000..58b3013
--- /dev/null
+++ b/test/SemaCXX/attr-common.cpp
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+__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 e9276cd..e24e12e 100644
--- a/test/SemaCXX/attr-cxx0x.cpp
+++ b/test/SemaCXX/attr-cxx0x.cpp
@@ -12,7 +12,7 @@ struct align_member {
};
void f(alignas(1) char c) { // expected-error {{'alignas' attribute cannot be applied to a function parameter}}
- alignas(1) register char k; // expected-error {{'alignas' attribute cannot be applied to a variable with 'register' storage class}}
+ alignas(1) register char k; // expected-error {{'alignas' attribute cannot be applied to a variable with 'register' storage class}} expected-warning {{deprecated}}
try {
} catch (alignas(4) int n) { // expected-error {{'alignas' attribute cannot be applied to a 'catch' variable}}
}
@@ -44,4 +44,4 @@ static_assert(alignof(align_class_temp_pack_type<short, int, long>) == alignof(l
static_assert(alignof(align_class_temp_pack_expr<8, 16, 32>) == 32, "template's alignment is wrong");
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-warning{{invalid application of 'alignof' to a function type}}
+static_assert(alignof(int(int)) >= 1, "alignof(function) not positive"); // expected-error{{invalid application of 'alignof' to a function type}}
diff --git a/test/SemaCXX/attr-deprecated.cpp b/test/SemaCXX/attr-deprecated.cpp
index d09faf3..b3223f3 100644
--- a/test/SemaCXX/attr-deprecated.cpp
+++ b/test/SemaCXX/attr-deprecated.cpp
@@ -244,3 +244,9 @@ namespace test7 {
X *x = new X; // expected-warning{{'operator new' is deprecated}} expected-warning{{'operator delete' is deprecated}}
}
}
+
+// rdar://problem/15044218
+typedef struct TDS {
+} TDS __attribute__((deprecated)); // expected-note {{'TDS' declared 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-no-sanitize-address.cpp b/test/SemaCXX/attr-no-sanitize-address.cpp
index dc4d797..f180349 100644
--- a/test/SemaCXX/attr-no-sanitize-address.cpp
+++ b/test/SemaCXX/attr-no-sanitize-address.cpp
@@ -9,7 +9,7 @@
void noanal_fun() NO_SANITIZE_ADDRESS;
void noanal_fun_args() __attribute__((no_sanitize_address(1))); // \
- // expected-error {{attribute takes no arguments}}
+ // expected-error {{'no_sanitize_address' attribute takes no arguments}}
int noanal_testfn(int y) NO_SANITIZE_ADDRESS;
diff --git a/test/SemaCXX/attr-no-sanitize-memory.cpp b/test/SemaCXX/attr-no-sanitize-memory.cpp
index 84acdac..d6eca1b 100644
--- a/test/SemaCXX/attr-no-sanitize-memory.cpp
+++ b/test/SemaCXX/attr-no-sanitize-memory.cpp
@@ -9,7 +9,7 @@
void noanal_fun() NO_SANITIZE_MEMORY;
void noanal_fun_args() __attribute__((no_sanitize_memory(1))); // \
- // expected-error {{attribute takes no arguments}}
+ // expected-error {{'no_sanitize_memory' attribute takes no arguments}}
int noanal_testfn(int y) NO_SANITIZE_MEMORY;
diff --git a/test/SemaCXX/attr-no-sanitize-thread.cpp b/test/SemaCXX/attr-no-sanitize-thread.cpp
index 50960c4..d6372bc 100644
--- a/test/SemaCXX/attr-no-sanitize-thread.cpp
+++ b/test/SemaCXX/attr-no-sanitize-thread.cpp
@@ -9,7 +9,7 @@
void noanal_fun() NO_SANITIZE_THREAD;
void noanal_fun_args() __attribute__((no_sanitize_thread(1))); // \
- // expected-error {{attribute takes no arguments}}
+ // expected-error {{'no_sanitize_thread' attribute takes no arguments}}
int noanal_testfn(int y) NO_SANITIZE_THREAD;
diff --git a/test/SemaCXX/attr-print.cpp b/test/SemaCXX/attr-print.cpp
index 2e74789..a07eeff 100644
--- a/test/SemaCXX/attr-print.cpp
+++ b/test/SemaCXX/attr-print.cpp
@@ -16,3 +16,9 @@ void bar() __attribute__((__const));
// FIXME: Print this with correct format and order.
// CHECK: void foo1() __attribute__((pure)) __attribute__((noinline));
void foo1() __attribute__((noinline, pure));
+
+// CHECK: typedef int Small1 __attribute__((mode(byte)));
+typedef int Small1 __attribute__((mode(byte)));
+
+// CHECK: int small __attribute__((mode(byte)));
+int small __attribute__((mode(byte)));
diff --git a/test/SemaCXX/attr-selectany.cpp b/test/SemaCXX/attr-selectany.cpp
new file mode 100644
index 0000000..0f9776d
--- /dev/null
+++ b/test/SemaCXX/attr-selectany.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s
+// MSVC produces similar diagnostics.
+
+__declspec(selectany) void foo() { } // expected-error{{'selectany' can only be applied to data items with external linkage}}
+
+__declspec(selectany) int x1 = 1;
+
+const __declspec(selectany) int x2 = 2; // expected-error{{'selectany' can only be applied to data items with external linkage}}
+
+extern const __declspec(selectany) int x3 = 3;
+
+extern const int x4;
+const __declspec(selectany) int x4 = 4;
+
+// MSDN says this is incorrect, but MSVC doesn't diagnose it.
+extern __declspec(selectany) int x5;
+
+static __declspec(selectany) int x6 = 2; // expected-error{{'selectany' can only be applied to data items with external linkage}}
+
+// FIXME: MSVC accepts this and makes x7 externally visible and comdat, but keep
+// it as internal and not weak/linkonce.
+static int x7; // expected-note{{previous definition}}
+extern __declspec(selectany) int x7; // expected-warning{{attribute declaration must precede definition}}
+
+int asdf() { return x7; }
+
+class X {
+ public:
+ X(int i) { i++; };
+ int i;
+};
+
+__declspec(selectany) X x(1);
diff --git a/test/SemaCXX/attr-used.cpp b/test/SemaCXX/attr-used.cpp
new file mode 100644
index 0000000..9bae3ed
--- /dev/null
+++ b/test/SemaCXX/attr-used.cpp
@@ -0,0 +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 const char test3[] __attribute__((used)) = "";
diff --git a/test/SemaCXX/attr-weakref.cpp b/test/SemaCXX/attr-weakref.cpp
index f3d7a62..0c3f1d2 100644
--- a/test/SemaCXX/attr-weakref.cpp
+++ b/test/SemaCXX/attr-weakref.cpp
@@ -32,3 +32,5 @@ int a9 __attribute__((weakref)); // expected-error {{weakref declaration of 'a9
static int a10();
int a10() __attribute__((weakref ("foo")));
+
+static int v __attribute__((weakref(a1), alias("foo"))); // expected-error {{'weakref' attribute requires a string}}
diff --git a/test/SemaCXX/blocks-1.cpp b/test/SemaCXX/blocks-1.cpp
index 02e9cac..e11fd92 100644
--- a/test/SemaCXX/blocks-1.cpp
+++ b/test/SemaCXX/blocks-1.cpp
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks -std=c++11
-// expected-no-diagnostics
+// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks -std=c++1y
extern "C" int exit(int);
@@ -57,3 +56,18 @@ namespace rdar11055105 {
foo(a);
};
}
+
+namespace LocalDecls {
+ void f() {
+ (void) ^{
+ extern int a; // expected-note {{previous}}
+ extern int b(); // expected-note {{previous}}
+ };
+ }
+ void g() {
+ (void) ^{
+ extern float a; // expected-error {{different type}}
+ extern float b(); // expected-error {{cannot be overloaded}}
+ };
+ }
+}
diff --git a/test/SemaCXX/bool.cpp b/test/SemaCXX/bool.cpp
index f027186..69c0119 100644
--- a/test/SemaCXX/bool.cpp
+++ b/test/SemaCXX/bool.cpp
@@ -1,4 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-constant-conversion %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-constant-conversion \
+// RUN: -Wno-deprecated -Wdeprecated-increment-bool %s
// Bool literals can be enum values.
enum {
diff --git a/test/SemaCXX/builtins.cpp b/test/SemaCXX/builtins.cpp
index 5d61690..69bdfa6 100644
--- a/test/SemaCXX/builtins.cpp
+++ b/test/SemaCXX/builtins.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify
+// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++11
typedef const struct __CFString * CFStringRef;
#define CFSTR __builtin___CFStringMakeConstantString
@@ -24,3 +24,23 @@ void f2() {
// pr14895
typedef __typeof(sizeof(int)) size_t;
extern "C" void *__builtin_alloca (size_t);
+
+namespace addressof {
+ struct S {} s;
+ static_assert(__builtin_addressof(s) == &s, "");
+
+ struct T { constexpr T *operator&() const { return nullptr; } int n; } t;
+ constexpr T *pt = __builtin_addressof(t);
+ static_assert(&pt->n == &t.n, "");
+
+ struct U { int n : 5; } u;
+ int *pbf = __builtin_addressof(u.n); // expected-error {{address of bit-field requested}}
+
+ S *ptmp = __builtin_addressof(S{}); // expected-error {{taking the address of a temporary}}
+}
+
+void no_ms_builtins() {
+ __assume(1); // expected-error {{use of undeclared}}
+ __noop(1); // expected-error {{use of undeclared}}
+ __debugbreak(); // expected-error {{use of undeclared}}
+}
diff --git a/test/SemaCXX/c99.cpp b/test/SemaCXX/c99.cpp
index 13918dc..7afcdd5 100644
--- a/test/SemaCXX/c99.cpp
+++ b/test/SemaCXX/c99.cpp
@@ -2,7 +2,7 @@
void f1(int i[static 5]) { // expected-error{{C99}}
}
-struct Point { int x; int y; };
+struct Point { int x; int y; int z[]; }; // expected-warning{{flexible array members are a C99 feature}}
Point p1 = { .x = 17, // expected-warning{{designated initializers are a C99 feature}}
y: 25 }; // expected-warning{{designated initializers are a C99 feature}} \
diff --git a/test/SemaCXX/calling-conv-compat.cpp b/test/SemaCXX/calling-conv-compat.cpp
new file mode 100644
index 0000000..2d52386
--- /dev/null
+++ b/test/SemaCXX/calling-conv-compat.cpp
@@ -0,0 +1,387 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -fms-extensions -cxx-abi microsoft -verify -triple i686-pc-win32 %s
+
+// Pointers to free functions
+void free_func_default();
+void __cdecl free_func_cdecl();
+void __stdcall free_func_stdcall();
+void __fastcall free_func_fastcall();
+
+typedef void ( *fptr_default)();
+typedef void (__cdecl *fptr_cdecl)();
+typedef void (__stdcall *fptr_stdcall)();
+typedef void (__fastcall *fptr_fastcall)();
+
+// expected-note@+4 {{candidate function not viable: no known conversion from 'void () __attribute__((stdcall))' to 'fptr_default' (aka 'void (*)()') for 1st argument}}
+// expected-note@+3 {{candidate function not viable: no known conversion from 'void () __attribute__((fastcall))' to 'fptr_default' (aka 'void (*)()') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (*)() __attribute__((stdcall))' to 'fptr_default' (aka 'void (*)()') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (*)() __attribute__((fastcall))' to 'fptr_default' (aka 'void (*)()') for 1st argument}}
+void cb_fptr_default(fptr_default ptr);
+// expected-note@+4 {{candidate function not viable: no known conversion from 'void () __attribute__((stdcall))' to 'fptr_cdecl' (aka 'void (*)()') for 1st argument}}
+// expected-note@+3 {{candidate function not viable: no known conversion from 'void () __attribute__((fastcall))' to 'fptr_cdecl' (aka 'void (*)()') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (*)() __attribute__((stdcall))' to 'fptr_cdecl' (aka 'void (*)()') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (*)() __attribute__((fastcall))' to 'fptr_cdecl' (aka 'void (*)()') for 1st argument}}
+void cb_fptr_cdecl(fptr_cdecl ptr);
+// expected-note@+3 {{candidate function not viable: no known conversion from 'void ()' to 'fptr_stdcall' (aka 'void (*)() __attribute__((stdcall))') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void () __attribute__((cdecl))' to 'fptr_stdcall' (aka 'void (*)() __attribute__((stdcall))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void () __attribute__((fastcall))' to 'fptr_stdcall' (aka 'void (*)() __attribute__((stdcall))') for 1st argument}}
+void cb_fptr_stdcall(fptr_stdcall ptr);
+// expected-note@+3 {{candidate function not viable: no known conversion from 'void ()' to 'fptr_fastcall' (aka 'void (*)() __attribute__((fastcall))') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void () __attribute__((cdecl))' to 'fptr_fastcall' (aka 'void (*)() __attribute__((fastcall))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void () __attribute__((stdcall))' to 'fptr_fastcall' (aka 'void (*)() __attribute__((fastcall))') for 1st argument}}
+void cb_fptr_fastcall(fptr_fastcall ptr);
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void () __attribute__((stdcall))' to 'const fptr_default' (aka 'void (*const)()') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void () __attribute__((fastcall))' to 'const fptr_default' (aka 'void (*const)()') for 1st argument}}
+void cb_fptr_const_default(const fptr_default ptr);
+
+void call_free_func() {
+ cb_fptr_default(free_func_default);
+ cb_fptr_default(free_func_cdecl);
+ cb_fptr_default(free_func_stdcall); // expected-error {{no matching function for call to 'cb_fptr_default'}}
+ cb_fptr_default(free_func_fastcall); // expected-error {{no matching function for call to 'cb_fptr_default'}}
+ cb_fptr_default(&free_func_default);
+ cb_fptr_default(&free_func_cdecl);
+ cb_fptr_default(&free_func_stdcall); // expected-error {{no matching function for call to 'cb_fptr_default'}}
+ cb_fptr_default(&free_func_fastcall); // expected-error {{no matching function for call to 'cb_fptr_default'}}
+
+ cb_fptr_cdecl(free_func_default);
+ cb_fptr_cdecl(free_func_cdecl);
+ cb_fptr_cdecl(free_func_stdcall); // expected-error {{no matching function for call to 'cb_fptr_cdecl'}}
+ cb_fptr_cdecl(free_func_fastcall); // expected-error {{no matching function for call to 'cb_fptr_cdecl'}}
+ cb_fptr_cdecl(&free_func_default);
+ cb_fptr_cdecl(&free_func_cdecl);
+ cb_fptr_cdecl(&free_func_stdcall); // expected-error {{no matching function for call to 'cb_fptr_cdecl'}}
+ cb_fptr_cdecl(&free_func_fastcall); // expected-error {{no matching function for call to 'cb_fptr_cdecl'}}
+
+ cb_fptr_stdcall(free_func_default); // expected-error {{no matching function for call to 'cb_fptr_stdcall'}}
+ cb_fptr_stdcall(free_func_cdecl); // expected-error {{no matching function for call to 'cb_fptr_stdcall'}}
+ cb_fptr_stdcall(free_func_stdcall);
+ cb_fptr_stdcall(free_func_fastcall); // expected-error {{no matching function for call to 'cb_fptr_stdcall'}}
+
+ cb_fptr_fastcall(free_func_default); // expected-error {{no matching function for call to 'cb_fptr_fastcall'}}
+ cb_fptr_fastcall(free_func_cdecl); // expected-error {{no matching function for call to 'cb_fptr_fastcall'}}
+ cb_fptr_fastcall(free_func_stdcall); // expected-error {{no matching function for call to 'cb_fptr_fastcall'}}
+ cb_fptr_fastcall(free_func_fastcall);
+
+ cb_fptr_const_default(free_func_default);
+ cb_fptr_const_default(free_func_cdecl);
+ cb_fptr_const_default(free_func_stdcall); // expected-error {{no matching function for call to 'cb_fptr_const_default'}}
+ cb_fptr_const_default(free_func_fastcall); // expected-error {{no matching function for call to 'cb_fptr_const_default'}}
+
+}
+
+// Pointers to variadic functions
+// variadic function can't declared stdcall or fastcall
+void free_func_variadic_default(int, ...);
+void __cdecl free_func_variadic_cdecl(int, ...);
+
+typedef void ( *fptr_variadic_default)(int, ...);
+typedef void (__cdecl *fptr_variadic_cdecl)(int, ...);
+
+void cb_fptr_variadic_default(fptr_variadic_default ptr);
+void cb_fptr_variadic_cdecl(fptr_variadic_cdecl ptr);
+
+void call_free_variadic_func() {
+ cb_fptr_variadic_default(free_func_variadic_default);
+ cb_fptr_variadic_default(free_func_variadic_cdecl);
+ cb_fptr_variadic_default(&free_func_variadic_default);
+ cb_fptr_variadic_default(&free_func_variadic_cdecl);
+
+ cb_fptr_variadic_cdecl(free_func_variadic_default);
+ cb_fptr_variadic_cdecl(free_func_variadic_cdecl);
+ cb_fptr_variadic_cdecl(&free_func_variadic_default);
+ cb_fptr_variadic_cdecl(&free_func_variadic_cdecl);
+}
+
+// References to functions
+typedef void ( &fref_default)();
+typedef void (__cdecl &fref_cdecl)();
+typedef void (__stdcall &fref_stdcall)();
+typedef void (__fastcall &fref_fastcall)();
+
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void () __attribute__((stdcall))' to 'fref_default' (aka 'void (&)()') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void () __attribute__((fastcall))' to 'fref_default' (aka 'void (&)()') for 1st argument}}
+void cb_fref_default(fref_default ptr);
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void () __attribute__((stdcall))' to 'fref_cdecl' (aka 'void (&)()') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void () __attribute__((fastcall))' to 'fref_cdecl' (aka 'void (&)()') for 1st argument}}
+void cb_fref_cdecl(fref_cdecl ptr);
+// expected-note@+3 {{candidate function not viable: no known conversion from 'void ()' to 'fref_stdcall' (aka 'void (&)() __attribute__((stdcall))') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void () __attribute__((cdecl))' to 'fref_stdcall' (aka 'void (&)() __attribute__((stdcall))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void () __attribute__((fastcall))' to 'fref_stdcall' (aka 'void (&)() __attribute__((stdcall))') for 1st argument}}
+void cb_fref_stdcall(fref_stdcall ptr);
+// expected-note@+3 {{candidate function not viable: no known conversion from 'void ()' to 'fref_fastcall' (aka 'void (&)() __attribute__((fastcall))') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void () __attribute__((cdecl))' to 'fref_fastcall' (aka 'void (&)() __attribute__((fastcall))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void () __attribute__((stdcall))' to 'fref_fastcall' (aka 'void (&)() __attribute__((fastcall))') for 1st argument}}
+void cb_fref_fastcall(fref_fastcall ptr);
+
+void call_free_func_ref() {
+ cb_fref_default(free_func_default);
+ cb_fref_default(free_func_cdecl);
+ cb_fref_default(free_func_stdcall); // expected-error {{no matching function for call to 'cb_fref_default'}}
+ cb_fref_default(free_func_fastcall); // expected-error {{no matching function for call to 'cb_fref_default'}}
+
+ cb_fref_cdecl(free_func_default);
+ cb_fref_cdecl(free_func_cdecl);
+ cb_fref_cdecl(free_func_stdcall); // expected-error {{no matching function for call to 'cb_fref_cdecl'}}
+ cb_fref_cdecl(free_func_fastcall); // expected-error {{no matching function for call to 'cb_fref_cdecl'}}
+
+ cb_fref_stdcall(free_func_default); // expected-error {{no matching function for call to 'cb_fref_stdcall'}}
+ cb_fref_stdcall(free_func_cdecl); // expected-error {{no matching function for call to 'cb_fref_stdcall'}}
+ cb_fref_stdcall(free_func_stdcall);
+ cb_fref_stdcall(free_func_fastcall); // expected-error {{no matching function for call to 'cb_fref_stdcall'}}
+
+ cb_fref_fastcall(free_func_default); // expected-error {{no matching function for call to 'cb_fref_fastcall'}}
+ cb_fref_fastcall(free_func_cdecl); // expected-error {{no matching function for call to 'cb_fref_fastcall'}}
+ cb_fref_fastcall(free_func_stdcall); // expected-error {{no matching function for call to 'cb_fref_fastcall'}}
+ cb_fref_fastcall(free_func_fastcall);
+}
+
+// References to variadic functions
+// variadic function can't declared stdcall or fastcall
+typedef void ( &fref_variadic_default)(int, ...);
+typedef void (__cdecl &fref_variadic_cdecl)(int, ...);
+
+void cb_fref_variadic_default(fptr_variadic_default ptr);
+void cb_fref_variadic_cdecl(fptr_variadic_cdecl ptr);
+
+void call_free_variadic_func_ref() {
+ cb_fref_variadic_default(free_func_variadic_default);
+ cb_fref_variadic_default(free_func_variadic_cdecl);
+
+ cb_fref_variadic_cdecl(free_func_variadic_default);
+ cb_fref_variadic_cdecl(free_func_variadic_cdecl);
+}
+
+// Pointers to members
+namespace NonVariadic {
+
+struct A {
+ void member_default();
+ void __cdecl member_cdecl();
+ void __thiscall member_thiscall();
+};
+
+struct B : public A {
+};
+
+struct C {
+ void member_default();
+ void __cdecl member_cdecl();
+ void __thiscall member_thiscall();
+};
+
+typedef void ( A::*memb_a_default)();
+typedef void (__cdecl A::*memb_a_cdecl)();
+typedef void (__thiscall A::*memb_a_thiscall)();
+typedef void ( B::*memb_b_default)();
+typedef void (__cdecl B::*memb_b_cdecl)();
+typedef void (__thiscall B::*memb_b_thiscall)();
+typedef void ( C::*memb_c_default)();
+typedef void (__cdecl C::*memb_c_cdecl)();
+typedef void (__thiscall C::*memb_c_thiscall)();
+
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_a_default' (aka 'void (NonVariadic::A::*)() __attribute__((thiscall))') for 1st argument}}
+void cb_memb_a_default(memb_a_default ptr);
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_a_cdecl' (aka 'void (NonVariadic::A::*)() __attribute__((cdecl))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_a_cdecl' (aka 'void (NonVariadic::A::*)() __attribute__((cdecl))') for 1st argument}}
+void cb_memb_a_cdecl(memb_a_cdecl ptr);
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_a_thiscall' (aka 'void (NonVariadic::A::*)() __attribute__((thiscall))') for 1st argument}}
+void cb_memb_a_thiscall(memb_a_thiscall ptr);
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_b_default' (aka 'void (NonVariadic::B::*)() __attribute__((thiscall))') for 1st argument}}
+void cb_memb_b_default(memb_b_default ptr);
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_b_cdecl' (aka 'void (NonVariadic::B::*)() __attribute__((cdecl))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_b_cdecl' (aka 'void (NonVariadic::B::*)() __attribute__((cdecl))') for 1st argument}}
+void cb_memb_b_cdecl(memb_b_cdecl ptr);
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_b_thiscall' (aka 'void (NonVariadic::B::*)() __attribute__((thiscall))') for 1st argument}}
+void cb_memb_b_thiscall(memb_b_thiscall ptr);
+// expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_default' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_c_default' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_default' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}}
+void cb_memb_c_default(memb_c_default ptr);
+// expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_cdecl' (aka 'void (NonVariadic::C::*)() __attribute__((cdecl))') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_c_cdecl' (aka 'void (NonVariadic::C::*)() __attribute__((cdecl))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_cdecl' (aka 'void (NonVariadic::C::*)() __attribute__((cdecl))') for 1st argument}}
+void cb_memb_c_cdecl(memb_c_cdecl ptr);
+// expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_thiscall' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_c_thiscall' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_thiscall' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}}
+void cb_memb_c_thiscall(memb_c_thiscall ptr);
+
+void call_member() {
+ cb_memb_a_default(&A::member_default);
+ cb_memb_a_default(&A::member_cdecl); // expected-error {{no matching function for call to 'cb_memb_a_default'}}
+ cb_memb_a_default(&A::member_thiscall);
+
+ cb_memb_a_cdecl(&A::member_default); // expected-error {{no matching function for call to 'cb_memb_a_cdecl'}}
+ cb_memb_a_cdecl(&A::member_cdecl);
+ cb_memb_a_cdecl(&A::member_thiscall); // expected-error {{no matching function for call to 'cb_memb_a_cdecl'}}
+
+ cb_memb_a_thiscall(&A::member_default);
+ cb_memb_a_thiscall(&A::member_cdecl); // expected-error {{no matching function for call to 'cb_memb_a_thiscall'}}
+ cb_memb_a_thiscall(&A::member_thiscall);
+}
+
+void call_member_inheritance() {
+ cb_memb_b_default(&A::member_default);
+ cb_memb_b_default(&A::member_cdecl); // expected-error {{no matching function for call to 'cb_memb_b_default'}}
+ cb_memb_b_default(&A::member_thiscall);
+ cb_memb_c_default(&A::member_default); // expected-error {{no matching function for call to 'cb_memb_c_default'}}
+ cb_memb_c_default(&A::member_cdecl); // expected-error {{no matching function for call to 'cb_memb_c_default'}}
+ cb_memb_c_default(&A::member_thiscall); // expected-error {{no matching function for call to 'cb_memb_c_default'}}
+
+ cb_memb_b_cdecl(&A::member_default); // expected-error {{no matching function for call to 'cb_memb_b_cdecl'}}
+ cb_memb_b_cdecl(&A::member_cdecl);
+ cb_memb_b_cdecl(&A::member_thiscall); // expected-error {{no matching function for call to 'cb_memb_b_cdecl'}}
+ cb_memb_c_cdecl(&A::member_default); // expected-error {{no matching function for call to 'cb_memb_c_cdecl'}}
+ cb_memb_c_cdecl(&A::member_cdecl); // expected-error {{no matching function for call to 'cb_memb_c_cdecl'}}
+ cb_memb_c_cdecl(&A::member_thiscall); // expected-error {{no matching function for call to 'cb_memb_c_cdecl'}}
+
+ cb_memb_b_thiscall(&A::member_default);
+ cb_memb_b_thiscall(&A::member_cdecl); // expected-error {{no matching function for call to 'cb_memb_b_thiscall'}}
+ cb_memb_b_thiscall(&A::member_thiscall);
+ cb_memb_c_thiscall(&A::member_default); // expected-error {{no matching function for call to 'cb_memb_c_thiscall'}}
+ cb_memb_c_thiscall(&A::member_cdecl); // expected-error {{no matching function for call to 'cb_memb_c_thiscall'}}
+ cb_memb_c_thiscall(&A::member_thiscall); // expected-error {{no matching function for call to 'cb_memb_c_thiscall'}}
+}
+} // end namespace NonVariadic
+
+namespace Variadic {
+struct A {
+ void member_default(int, ...);
+ void __cdecl member_cdecl(int, ...);
+ void __thiscall member_thiscall(int, ...); // expected-error {{variadic function cannot use thiscall calling convention}}
+};
+
+struct B : public A {
+};
+
+struct C {
+ void member_default(int, ...);
+ void __cdecl member_cdecl(int, ...);
+};
+
+typedef void ( A::*memb_a_default)(int, ...);
+typedef void (__cdecl A::*memb_a_cdecl)(int, ...);
+typedef void ( B::*memb_b_default)(int, ...);
+typedef void (__cdecl B::*memb_b_cdecl)(int, ...);
+typedef void ( C::*memb_c_default)(int, ...);
+typedef void (__cdecl C::*memb_c_cdecl)(int, ...);
+
+void cb_memb_a_default(memb_a_default ptr);
+void cb_memb_a_cdecl(memb_a_cdecl ptr);
+void cb_memb_b_default(memb_b_default ptr);
+void cb_memb_b_cdecl(memb_b_cdecl ptr);
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...)' to 'memb_c_default' (aka 'void (Variadic::C::*)(int, ...)') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...) __attribute__((cdecl))' to 'memb_c_default' (aka 'void (Variadic::C::*)(int, ...)') for 1st argument}}
+void cb_memb_c_default(memb_c_default ptr);
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...)' to 'memb_c_cdecl' (aka 'void (Variadic::C::*)(int, ...) __attribute__((cdecl))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...) __attribute__((cdecl))' to 'memb_c_cdecl' (aka 'void (Variadic::C::*)(int, ...) __attribute__((cdecl))') for 1st argument}}
+void cb_memb_c_cdecl(memb_c_cdecl ptr);
+
+void call_member() {
+ cb_memb_a_default(&A::member_default);
+ cb_memb_a_default(&A::member_cdecl);
+
+ cb_memb_a_cdecl(&A::member_default);
+ cb_memb_a_cdecl(&A::member_cdecl);
+}
+
+void call_member_inheritance() {
+ cb_memb_b_default(&A::member_default);
+ cb_memb_b_default(&A::member_cdecl);
+ cb_memb_c_default(&A::member_default); // expected-error {{no matching function for call to 'cb_memb_c_default'}}
+ cb_memb_c_default(&A::member_cdecl); // expected-error {{no matching function for call to 'cb_memb_c_default'}}
+
+ cb_memb_b_cdecl(&A::member_default);
+ cb_memb_b_cdecl(&A::member_cdecl);
+ cb_memb_c_cdecl(&A::member_default); // expected-error {{no matching function for call to 'cb_memb_c_cdecl'}}
+ cb_memb_c_cdecl(&A::member_cdecl); // expected-error {{no matching function for call to 'cb_memb_c_cdecl'}}
+}
+} // end namespace Variadic
+
+namespace MultiChunkDecls {
+
+// Try to test declarators that have multiple DeclaratorChunks.
+struct A {
+ void __thiscall member_thiscall(int);
+};
+
+void (A::*return_mptr(short))(int) {
+ return &A::member_thiscall;
+}
+
+void (A::*(*return_fptr_mptr(char))(short))(int) {
+ return return_mptr;
+}
+
+typedef void (A::*mptr_t)(int);
+mptr_t __stdcall return_mptr_std(short) {
+ return &A::member_thiscall;
+}
+
+void (A::*(*return_fptr_std_mptr(char))(short))(int) {
+ return return_mptr_std; // expected-error {{cannot initialize return object of type 'void (MultiChunkDecls::A::*(*)(short))(int) __attribute__((thiscall))' with an lvalue of type 'mptr_t (short) __attribute__((stdcall))'}}
+}
+
+void call_return() {
+ A o;
+ void (A::*(*fptr)(short))(int) = return_fptr_mptr('a');
+ void (A::*mptr)(int) = fptr(1);
+ (o.*mptr)(2);
+}
+
+} // end namespace MultiChunkDecls
+
+namespace MemberPointers {
+
+struct A {
+ void __thiscall method_thiscall();
+ void __cdecl method_cdecl();
+ void __stdcall method_stdcall();
+ void __fastcall method_fastcall();
+};
+
+void ( A::*mp1)() = &A::method_thiscall;
+void (__cdecl A::*mp2)() = &A::method_cdecl;
+void (__stdcall A::*mp3)() = &A::method_stdcall;
+void (__fastcall A::*mp4)() = &A::method_fastcall;
+
+// Use a typedef to form the member pointer and verify that cdecl is adjusted.
+typedef void ( fun_default)();
+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_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;
+};
+
+// 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 __stdcall ()>::p tmpl3 = &A::method_stdcall;
+X<void __fastcall ()>::p tmpl4 = &A::method_fastcall;
+
+} // end namespace MemberPointers
+
+// Test that lambdas that capture nothing convert to cdecl function pointers.
+namespace Lambdas {
+
+void pass_fptr_cdecl (void (__cdecl *fp)());
+void pass_fptr_stdcall (void (__stdcall *fp)()); // expected-note {{candidate function not viable}}
+void pass_fptr_fastcall(void (__fastcall *fp)()); // expected-note {{candidate function not viable}}
+
+void conversion_to_fptr() {
+ pass_fptr_cdecl ([]() { } );
+ pass_fptr_stdcall ([]() { } ); // expected-error {{no matching function for call}}
+ pass_fptr_fastcall([]() { } ); // expected-error {{no matching function for call}}
+}
+
+}
diff --git a/test/SemaCXX/captured-statements.cpp b/test/SemaCXX/captured-statements.cpp
index dbb18a7..5fb686c 100644
--- a/test/SemaCXX/captured-statements.cpp
+++ b/test/SemaCXX/captured-statements.cpp
@@ -164,3 +164,10 @@ void test_capture_variadic() {
(void)captured_sum(1, 2, 3); // OK
(void)captured_sum(1, 2, 3, 4, 5); // OK
}
+
+void test_capture_with_attributes() {
+ [[]] // expected-error {{an attribute list cannot appear here}}
+ #pragma clang __debug captured
+ {
+ }
+}
diff --git a/test/SemaCXX/cast-conversion.cpp b/test/SemaCXX/cast-conversion.cpp
index 270f968..4d5abfd 100644
--- a/test/SemaCXX/cast-conversion.cpp
+++ b/test/SemaCXX/cast-conversion.cpp
@@ -16,8 +16,7 @@ struct B { // expected-note 3 {{candidate constructor (the implicit copy constru
int main () {
B(10); // expected-error {{no matching conversion for functional-style cast from 'int' to 'B'}}
(B)10; // expected-error {{no matching conversion for C-style cast from 'int' to 'B'}}
- static_cast<B>(10); // expected-error {{no matching conversion for static_cast from 'int' to 'B'}} \\
- // expected-warning {{expression result unused}}
+ static_cast<B>(10); // expected-error {{no matching conversion for static_cast from 'int' to 'B'}}
}
template<class T>
@@ -65,3 +64,18 @@ void *intToPointer4() {
void *intToPointer5(long l) {
return (void*)l;
}
+
+struct AmbiguousCast {
+ operator int(); // expected-note {{candidate function}}
+ operator unsigned int(); // expected-note {{candidate function}}
+};
+long long AmbiguousCastFunc(AmbiguousCast& a) {
+ return static_cast<long long>(a); // expected-error {{ambiguous conversion for static_cast from 'AmbiguousCast' to 'long long'}}
+}
+
+namespace PR16680 {
+ void f(int (*__pf)());
+ int g() {
+ f(reinterpret_cast<int>(0.0f)); // expected-error {{reinterpret_cast from 'float' to 'int' is not allowed}}
+ }
+}
diff --git a/test/SemaCXX/class-base-member-init.cpp b/test/SemaCXX/class-base-member-init.cpp
index 2cdca82..8344e6f 100644
--- a/test/SemaCXX/class-base-member-init.cpp
+++ b/test/SemaCXX/class-base-member-init.cpp
@@ -98,3 +98,13 @@ namespace rdar13185264 {
union { void *a; };
};
}
+
+namespace PR16596 {
+ class A { public: virtual ~A(); };
+ typedef const A Foo;
+ void Apply(Foo processor);
+ struct Bar : public Foo {};
+ void Fetch() {
+ Apply(Bar());
+ }
+}
diff --git a/test/SemaCXX/class-layout.cpp b/test/SemaCXX/class-layout.cpp
index f2ff9fc..64c8ceb 100644
--- a/test/SemaCXX/class-layout.cpp
+++ b/test/SemaCXX/class-layout.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++98
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11
// expected-no-diagnostics
#define SA(n, p) int a##n[(p) ? 1 : -1]
@@ -103,3 +104,469 @@ struct H { G g; };
SA(0, sizeof(H) == 24);
}
+
+namespace PR16537 {
+namespace test1 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct tail_padded_pod_in_11_only {
+ pod_in_11_only pod11;
+ char tail_padding;
+ };
+
+ struct might_use_tail_padding : public tail_padded_pod_in_11_only {
+ char may_go_into_tail_padding;
+ };
+
+ SA(0, sizeof(might_use_tail_padding) == 16);
+}
+
+namespace test2 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct tail_padded_pod_in_11_only {
+ pod_in_11_only pod11 __attribute__((aligned(16)));
+ };
+
+ struct might_use_tail_padding : public tail_padded_pod_in_11_only {
+ char may_go_into_tail_padding;
+ };
+
+ SA(0, sizeof(might_use_tail_padding) == 16);
+}
+
+namespace test3 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct tail_padded_pod_in_11_only {
+ pod_in_11_only pod11;
+ char tail_padding;
+ };
+
+ struct second_base {
+ char foo;
+ };
+
+ struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
+
+ };
+ SA(0, sizeof(might_use_tail_padding) == 16);
+}
+
+namespace test4 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct tail_padded_pod_in_11_only {
+ pod_in_11_only pod11;
+ char tail_padding;
+ };
+
+ struct second_base {
+ char foo;
+ };
+
+ struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
+ char may_go_into_tail_padding;
+ };
+ SA(0, sizeof(might_use_tail_padding) == 16);
+}
+
+namespace test5 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct pod_in_11_only2 {
+ private:
+ long long x;
+ };
+
+ struct tail_padded_pod_in_11_only {
+ pod_in_11_only pod11;
+ char tail_padding;
+ };
+
+ struct second_base {
+ pod_in_11_only2 two;
+ char foo;
+ };
+
+ struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
+ char may_go_into_tail_padding;
+ };
+ SA(0, sizeof(might_use_tail_padding) == 32);
+}
+
+namespace test6 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct pod_in_11_only2 {
+ private:
+ long long x;
+ };
+
+ struct tail_padded_pod_in_11_only {
+ pod_in_11_only pod11;
+ char tail_padding;
+ };
+
+ struct second_base {
+ pod_in_11_only2 two;
+ char foo;
+ };
+
+ struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
+ char may_go_into_tail_padding;
+ };
+ SA(0, sizeof(might_use_tail_padding) == 32);
+}
+
+namespace test7 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct tail_padded_pod_in_11_only {
+ pod_in_11_only pod11;
+ pod_in_11_only pod12;
+ char tail_padding;
+ };
+
+ struct might_use_tail_padding : public tail_padded_pod_in_11_only {
+ char may_go_into_tail_padding;
+ };
+
+ SA(0, sizeof(might_use_tail_padding) == 24);
+}
+
+namespace test8 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct tail_padded_pod_in_11_only {
+ pod_in_11_only pod11;
+ char tail_padding;
+ };
+
+ struct another_layer {
+ tail_padded_pod_in_11_only pod;
+ char padding;
+ };
+
+ struct might_use_tail_padding : public another_layer {
+ char may_go_into_tail_padding;
+ };
+
+ SA(0, sizeof(might_use_tail_padding) == 24);
+}
+
+namespace test9 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct tail_padded_pod_in_11_only {
+ pod_in_11_only pod11;
+ char tail_padding;
+ };
+
+ struct another_layer : tail_padded_pod_in_11_only {
+ };
+
+ struct might_use_tail_padding : public another_layer {
+ char may_go_into_tail_padding;
+ };
+
+ SA(0, sizeof(might_use_tail_padding) == 16);
+}
+
+namespace test10 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct A {
+ pod_in_11_only a;
+ char apad;
+ };
+
+ struct B {
+ char b;
+ };
+
+ struct C {
+ pod_in_11_only c;
+ char cpad;
+ };
+
+ struct D {
+ char d;
+ };
+
+ struct might_use_tail_padding : public A, public B, public C, public D {
+ };
+
+ SA(0, sizeof(might_use_tail_padding) == 32);
+}
+
+namespace test11 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct A {
+ pod_in_11_only a;
+ char apad;
+ };
+
+ struct B {
+ char b_pre;
+ pod_in_11_only b;
+ char bpad;
+ };
+
+ struct C {
+ char c_pre;
+ pod_in_11_only c;
+ char cpad;
+ };
+
+ struct D {
+ char d_pre;
+ pod_in_11_only d;
+ char dpad;
+ };
+
+ struct might_use_tail_padding : public A, public B, public C, public D {
+ char m;
+ };
+
+ SA(0, sizeof(might_use_tail_padding) == 88);
+}
+
+namespace test12 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct A {
+ pod_in_11_only a __attribute__((aligned(128)));
+ };
+
+ struct B {
+ char bpad;
+ };
+
+ struct C {
+ char cpad;
+ };
+
+ struct D {
+ char dpad;
+ };
+
+ struct might_use_tail_padding : public A, public B, public C, public D {
+ char m;
+ };
+ SA(0, sizeof(might_use_tail_padding) == 128);
+}
+
+namespace test13 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct A {
+ pod_in_11_only a;
+ char apad;
+ };
+
+ struct B {
+ };
+
+ struct C {
+ char c_pre;
+ pod_in_11_only c;
+ char cpad;
+ };
+
+ struct D {
+ };
+
+ struct might_use_tail_padding : public A, public B, public C, public D {
+ char m;
+ };
+ SA(0, sizeof(might_use_tail_padding) == 40);
+}
+
+namespace test14 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct A {
+ pod_in_11_only a;
+ char apad;
+ };
+
+ struct might_use_tail_padding : public A {
+ struct {
+ int : 0;
+ } x;
+ };
+ SA(0, sizeof(might_use_tail_padding) == 16);
+}
+
+namespace test15 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct A {
+ pod_in_11_only a;
+ char apad;
+ };
+
+ struct might_use_tail_padding : public A {
+ struct {
+ char a:1;
+ char b:2;
+ char c:2;
+ char d:2;
+ char e:1;
+ } x;
+ };
+ SA(0, sizeof(might_use_tail_padding) == 16);
+}
+
+namespace test16 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct A {
+ pod_in_11_only a;
+ char apad;
+ };
+
+ struct B {
+ char bpod;
+ pod_in_11_only b;
+ char bpad;
+ };
+
+ struct C : public A, public B {
+ };
+
+ struct D : public C {
+ };
+
+ struct might_use_tail_padding : public D {
+ char m;
+ };
+ SA(0, sizeof(might_use_tail_padding) == 40);
+}
+
+namespace test17 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct A {
+ pod_in_11_only a __attribute__((aligned(512)));
+ };
+
+ struct B {
+ char bpad;
+ pod_in_11_only foo;
+ char btail;
+ };
+
+ struct C {
+ char cpad;
+ };
+
+ struct D {
+ char dpad;
+ };
+
+ struct might_use_tail_padding : public A, public B, public C, public D {
+ char a;
+ };
+ SA(0, sizeof(might_use_tail_padding) == 512);
+}
+
+namespace test18 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct A {
+ pod_in_11_only a;
+ char apad;
+ };
+
+ struct B {
+ char bpod;
+ pod_in_11_only b;
+ char bpad;
+ };
+
+ struct A1 {
+ pod_in_11_only a;
+ char apad;
+ };
+
+ struct B1 {
+ char bpod;
+ pod_in_11_only b;
+ char bpad;
+ };
+
+ struct C : public A, public B {
+ };
+
+ struct D : public A1, public B1 {
+ };
+
+ struct E : public D, public C {
+ };
+
+ struct F : public E {
+ };
+
+ struct might_use_tail_padding : public F {
+ char m;
+ };
+ SA(0, sizeof(might_use_tail_padding) == 80);
+}
+} // namespace PR16537
diff --git a/test/SemaCXX/class.cpp b/test/SemaCXX/class.cpp
index 972a79b..636f584 100644
--- a/test/SemaCXX/class.cpp
+++ b/test/SemaCXX/class.cpp
@@ -126,12 +126,8 @@ struct S
// Don't crash on this bogus code.
namespace pr6629 {
- // TODO: most of these errors are spurious
template<class T1, class T2> struct foo :
- bogus<foo<T1,T2> > // expected-error {{unknown template name 'bogus'}} \
- // BOGUS expected-error {{expected '{' after base class list}} \
- // BOGUS expected-error {{expected ';' after struct}} \
- // BOGUS expected-error {{expected unqualified-id}}
+ bogus<foo<T1,T2> > // expected-error {{unknown template name 'bogus'}}
{ };
template<> struct foo<unknown,unknown> { // expected-error {{undeclared identifier 'unknown'}}
diff --git a/test/SemaCXX/compare.cpp b/test/SemaCXX/compare.cpp
index feb1ccb..8214f78 100644
--- a/test/SemaCXX/compare.cpp
+++ b/test/SemaCXX/compare.cpp
@@ -355,3 +355,70 @@ void test9(int x) {
};
(void)((E)x == 1);
}
+
+namespace templates {
+ template<class T> T max();
+
+ template<> constexpr int max<int>() { return 2147483647; };
+
+ template<typename T>
+ bool less_than_max(short num, T value) {
+ const T vmax = max<T>();
+ return (vmax >= num); // no warning
+ }
+
+ template<typename T>
+ bool less_than_max(short num) {
+ // This should trigger one warning on the template pattern, and not a
+ // warning per specialization.
+ return num < max<int>(); // expected-warning{{comparison of constant 2147483647 with expression of type 'short' is always true}}
+ }
+
+ void test10(short num, int x) {
+ less_than_max(num, x);
+ less_than_max<int>(num);
+ less_than_max<long>(num);
+ less_than_max<short>(num);
+ }
+
+ template<typename T>
+ inline bool less_than_zero(T num, T value) {
+ return num < 0; // no warning
+ }
+
+ template<typename T>
+ inline bool less_than_zero(unsigned num) {
+ // This should trigger one warning on the template pattern, and not a
+ // warning per specialization.
+ return num < 0; // expected-warning{{comparison of unsigned expression < 0 is always false}}
+ }
+
+ void test11(unsigned num) {
+ less_than_zero(num, num);
+ less_than_zero<int>(num);
+ less_than_zero<long>(num);
+ less_than_zero<short>(num);
+ }
+
+ template<unsigned n> bool compare(unsigned k) { return k >= n; }
+
+ void test12() {
+ compare<0>(42);
+ }
+
+ struct A { static int x; };
+ struct B { static int x; };
+ typedef A otherA;
+
+ template <typename T>
+ void testx() {
+ if (A::x == T::x && // no warning
+ A::x == otherA::x) // expected-warning{{self-comparison always evaluates to true}}
+ return;
+ }
+
+ void test13() {
+ testx<A>();
+ testx<B>();
+ }
+}
diff --git a/test/SemaCXX/complex-overload.cpp b/test/SemaCXX/complex-overload.cpp
index 719a850..1381968 100644
--- a/test/SemaCXX/complex-overload.cpp
+++ b/test/SemaCXX/complex-overload.cpp
@@ -42,9 +42,15 @@ void test_promote_or_convert2(float _Complex fc) {
int *cp = promote_or_convert2(fc);
}
-char *promote_or_convert3(int _Complex);
-int *promote_or_convert3(long _Complex);
+char *promote_or_convert3(int _Complex); // expected-note {{candidate}}
+int *promote_or_convert3(long _Complex); // expected-note {{candidate}}
void test_promote_or_convert3(short _Complex sc) {
- char *cp = promote_or_convert3(sc);
+ char *cp1 = promote_or_convert3(sc);
+ char *cp2 = promote_or_convert3(1i);
+ int *cp3 = promote_or_convert3(1il);
+ int *cp4 = promote_or_convert3(1ill); // expected-error {{ambiguous}}
}
+
+char &convert4(short _Complex);
+char &test_convert4 = convert4(1i);
diff --git a/test/SemaCXX/compound-literal.cpp b/test/SemaCXX/compound-literal.cpp
index 595747e..3fc6150 100644
--- a/test/SemaCXX/compound-literal.cpp
+++ b/test/SemaCXX/compound-literal.cpp
@@ -76,3 +76,13 @@ namespace brace_initializers {
(void)(PrivateDtor){1, 2}; // expected-error {{temporary of type 'brace_initializers::PrivateDtor' has private destructor}}
}
}
+
+// This doesn't necessarily need to be an error, but CodeGen can't handle it
+// at the moment.
+int PR17415 = (int){PR17415}; // expected-error {{initializer element is not a compile-time constant}}
+
+// Make sure we accept this. (Not sure if we actually should... but we do
+// at the moment.)
+template<unsigned> struct Value { };
+template<typename T>
+int &check_narrowed(Value<sizeof((T){1.1})>);
diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp
index 692aaef..5abee4a 100644
--- a/test/SemaCXX/conditional-expr.cpp
+++ b/test/SemaCXX/conditional-expr.cpp
@@ -81,6 +81,8 @@ void test()
i1 ? test() : test();
i1 = i1 ? throw 0 : 0;
i1 = i1 ? 0 : throw 0;
+ i1 = i1 ? (throw 0) : 0;
+ 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}}
diff --git a/test/SemaCXX/const-cast.cpp b/test/SemaCXX/const-cast.cpp
index 62851f8..1fe350d 100644
--- a/test/SemaCXX/const-cast.cpp
+++ b/test/SemaCXX/const-cast.cpp
@@ -38,6 +38,7 @@ char ***good_const_cast_test(ccvpcvpp var)
f *fpp = const_cast<f*>(&fp);
int const A::* const A::*icapcap = 0;
int A::* A::* iapap = const_cast<int A::* A::*>(icapcap);
+ (void)const_cast<A&&>(A()); // expected-warning {{C++11}}
return var4;
}
@@ -60,5 +61,6 @@ short *bad_const_cast_test(char const *volatile *const volatile *var)
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<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 09a9cb5..6724be7 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 -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
namespace StaticAssertFoldTest {
@@ -79,6 +79,11 @@ constexpr int **n6 = const_cast<int**>(&n3);
constexpr int n7 = **n5;
constexpr int n8 = **n6;
+// const_cast from prvalue to xvalue.
+struct A { int n; };
+constexpr int n9 = (const_cast<A&&>(A{123})).n;
+static_assert(n9 == 123, "");
+
}
namespace TemplateArgumentConversion {
@@ -339,6 +344,46 @@ static_assert(!same(4, 4), "");
static_assert(same(n, n), "");
static_assert(sameTemporary(9), "");
+struct A { int &&r; };
+struct B { A &&a1; A &&a2; };
+
+constexpr B b1 { { 1 }, { 2 } }; // expected-note {{temporary created here}}
+static_assert(&b1.a1 != &b1.a2, "");
+static_assert(&b1.a1.r != &b1.a2.r, ""); // expected-error {{constant expression}} expected-note {{outside the expression that created the temporary}}
+
+constexpr B &&b2 { { 3 }, { 4 } }; // expected-note {{temporary created here}}
+static_assert(&b1 != &b2, "");
+static_assert(&b1.a1 != &b2.a1, ""); // expected-error {{constant expression}} expected-note {{outside the expression that created the temporary}}
+
+constexpr thread_local B b3 { { 1 }, { 2 } }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}}
+void foo() {
+ constexpr static B b1 { { 1 }, { 2 } }; // ok
+ constexpr thread_local B b2 { { 1 }, { 2 } }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}}
+ constexpr B b3 { { 1 }, { 2 } }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}}
+}
+
+constexpr B &&b4 = ((1, 2), 3, 4, B { {10}, {{20}} }); // expected-warning 4{{unused}}
+static_assert(&b4 != &b2, "");
+
+// Proposed DR: copy-elision doesn't trigger lifetime extension.
+constexpr B b5 = B{ {0}, {0} }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}}
+
+namespace NestedNonStatic {
+ // Proposed DR: for a reference constant expression to refer to a static
+ // storage duration temporary, that temporary must itself be initialized
+ // by a constant expression (a core constant expression is not enough).
+ struct A { int &&r; };
+ struct B { A &&a; };
+ constexpr B a = { A{0} }; // ok
+ constexpr B b = { A(A{0}) }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}}
+}
+
+namespace FakeInitList {
+ struct init_list_3_ints { const int (&x)[3]; };
+ struct init_list_2_init_list_3_ints { const init_list_3_ints (&x)[2]; };
+ constexpr init_list_2_init_list_3_ints ils = { { { { 1, 2, 3 } }, { { 4, 5, 6 } } } };
+}
+
}
constexpr int strcmp_ce(const char *p, const char *q) {
@@ -572,7 +617,7 @@ struct E {
constexpr E() : p(&p) {}
void *p;
};
-constexpr const E &e1 = E(); // expected-error {{constant expression}} expected-note {{reference to temporary is not a constant expression}} expected-note {{temporary created here}}
+constexpr const E &e1 = E();
// This is a constant expression if we elide the copy constructor call, and
// is not a constant expression if we don't! But we do, so it is.
constexpr E e2 = E();
@@ -729,15 +774,22 @@ static_assert(&ok2 == pok2, "");
static_assert((Base2*)(Derived*)(Base*)pb1 == pok2, "");
static_assert((Derived*)(Base*)pb1 == (Derived*)pok2, "");
-constexpr Base *nullB = 42 - 6 * 7; // expected-warning {{expression which evaluates to zero treated as a null pointer constant of type 'Class::Base *const'}}
+// Core issue 903: we do not perform constant evaluation when checking for a
+// null pointer in C++11. Just check for an integer literal with value 0.
+constexpr Base *nullB = 42 - 6 * 7; // expected-error {{cannot initialize a variable of type 'Class::Base *const' with an rvalue of type 'int'}}
+constexpr Base *nullB1 = 0;
static_assert((Bottom*)nullB == 0, "");
static_assert((Derived*)nullB == 0, "");
static_assert((void*)(Bottom*)nullB == (void*)(Derived*)nullB, "");
-Base * nullB2 = '\0'; // expected-warning {{expression which evaluates to zero treated as a null pointer constant of type 'Class::Base *'}}
-Base * nullB3 = (0);
-// We suppress the warning in unevaluated contexts to workaround some gtest
-// behavior. Once this becomes an error this isn't a problem anymore.
-static_assert(nullB == (1 - 1), "");
+Base *nullB2 = '\0'; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'char'}}
+Base *nullB3 = (0);
+Base *nullB4 = false; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'bool'}}
+Base *nullB5 = ((0ULL));
+Base *nullB6 = 0.; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'double'}}
+enum Null { kNull };
+Base *nullB7 = kNull; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'Class::Null'}}
+static_assert(nullB1 == (1 - 1), ""); // expected-error {{comparison between pointer and integer}}
+
namespace ConversionOperators {
@@ -778,21 +830,26 @@ namespace Temporaries {
struct S {
constexpr S() {}
constexpr int f() const;
+ constexpr int g() const;
};
struct T : S {
constexpr T(int n) : S(), n(n) {}
int n;
};
constexpr int S::f() const {
- // 'this' must be the postfix-expression in a class member access expression,
- // so we can't just use
- // return static_cast<T*>(this)->n;
- return this->*(int(S::*))&T::n;
+ return static_cast<const T*>(this)->n; // expected-note {{cannot cast}}
+}
+constexpr int S::g() const {
+ // FIXME: Better diagnostic for this.
+ return this->*(int(S::*))&T::n; // expected-note {{subexpression}}
}
// The T temporary is implicitly cast to an S subobject, but we can recover the
// T full-object via a base-to-derived cast, or a derived-to-base-casted member
// pointer.
+static_assert(S().f(), ""); // expected-error {{constant expression}} expected-note {{in call to '&Temporaries::S()->f()'}}
+static_assert(S().g(), ""); // expected-error {{constant expression}} expected-note {{in call to '&Temporaries::S()->g()'}}
static_assert(T(3).f() == 3, "");
+static_assert(T(4).g() == 4, "");
constexpr int f(const S &s) {
return static_cast<const T&>(s).n;
@@ -1138,6 +1195,31 @@ namespace ComplexConstexpr {
static_assert(&__imag test6 == &__real test6 + 1, "");
}
+// _Atomic(T) is exactly like T for the purposes of constant expression
+// evaluation..
+namespace Atomic {
+ constexpr _Atomic int n = 3;
+
+ struct S { _Atomic(double) d; };
+ constexpr S s = { 0.5 };
+ constexpr double d1 = s.d;
+ constexpr double d2 = n;
+ constexpr _Atomic double d3 = n;
+
+ constexpr _Atomic(int) n2 = d3;
+ static_assert(d1 == 0.5, "");
+ static_assert(d3 == 3.0, "");
+
+ namespace PR16056 {
+ struct TestVar {
+ _Atomic(int) value;
+ constexpr TestVar(int value) : value(value) {}
+ };
+ constexpr TestVar testVar{-1};
+ static_assert(testVar.value == -1, "");
+ }
+}
+
namespace InstantiateCaseStmt {
template<int x> constexpr int f() { return x; }
template<int x> int g(int c) { switch(c) { case f<x>(): return 1; } return 0; }
@@ -1252,8 +1334,23 @@ struct Wrap {
constexpr const Wrap &g(const Wrap &w) { return w; }
constexpr int k2 = g({0}).value; // ok
-constexpr const int &i = 0; // expected-error {{constant expression}} expected-note {{temporary}} expected-note 2{{here}}
-constexpr const int j = i; // expected-error {{constant expression}} expected-note {{initializer of 'i' is not a constant expression}}
+// The temporary here has static storage duration, so we can bind a constexpr
+// reference to it.
+constexpr const int &i = 1;
+constexpr const int j = i;
+static_assert(j == 1, "");
+
+// The temporary here is not const, so it can't be read outside the expression
+// in which it was created (per the C++14 rules, which we use to avoid a C++11
+// defect).
+constexpr int &&k = 1; // expected-note {{temporary created here}}
+constexpr const int l = k; // expected-error {{constant expression}} expected-note {{read of temporary}}
+
+void f() {
+ // The temporary here has automatic storage duration, so we can't bind a
+ // constexpr reference to it.
+ constexpr const int &i = 1; // expected-error {{constant expression}} expected-note 2{{temporary}}
+}
}
@@ -1503,3 +1600,266 @@ namespace PR15884 {
// expected-note@-3 {{pointer to temporary is not a constant expression}}
// expected-note@-4 {{temporary created here}}
}
+
+namespace AfterError {
+ // FIXME: Suppress the 'no return statements' diagnostic if the body is invalid.
+ constexpr int error() { // expected-error {{no return statement}}
+ return foobar; // expected-error {{undeclared identifier}}
+ }
+ constexpr int k = error(); // expected-error {{must be initialized by a constant expression}}
+}
+
+namespace std {
+ typedef decltype(sizeof(int)) size_t;
+
+ template <class _E>
+ class initializer_list
+ {
+ const _E* __begin_;
+ size_t __size_;
+
+ constexpr initializer_list(const _E* __b, size_t __s)
+ : __begin_(__b),
+ __size_(__s)
+ {}
+
+ public:
+ typedef _E value_type;
+ typedef const _E& reference;
+ typedef const _E& const_reference;
+ typedef size_t size_type;
+
+ typedef const _E* iterator;
+ typedef const _E* const_iterator;
+
+ constexpr initializer_list() : __begin_(nullptr), __size_(0) {}
+
+ constexpr size_t size() const {return __size_;}
+ constexpr const _E* begin() const {return __begin_;}
+ constexpr const _E* end() const {return __begin_ + __size_;}
+ };
+}
+
+namespace InitializerList {
+ constexpr int sum(const int *b, const int *e) {
+ return b != e ? *b + sum(b+1, e) : 0;
+ }
+ constexpr int sum(std::initializer_list<int> ints) {
+ return sum(ints.begin(), ints.end());
+ }
+ static_assert(sum({1, 2, 3, 4, 5}) == 15, "");
+}
+
+namespace StmtExpr {
+ struct A { int k; };
+ void f() {
+ static_assert(({ const int x = 5; x * 3; }) == 15, ""); // expected-warning {{extension}}
+ constexpr auto a = ({ A(); }); // expected-warning {{extension}}
+ }
+ constexpr int g(int k) {
+ return ({ // expected-warning {{extension}}
+ const int x = k;
+ x * x;
+ });
+ }
+ static_assert(g(123) == 15129, "");
+ constexpr int h() { // expected-error {{never produces a constant}}
+ return ({ // expected-warning {{extension}}
+ return 0; // expected-note {{not supported}}
+ 1;
+ });
+ }
+}
+
+namespace VirtualFromBase {
+ struct S1 {
+ virtual int f() const;
+ };
+ struct S2 {
+ virtual int f();
+ };
+ template <typename T> struct X : T {
+ constexpr X() {}
+ double d = 0.0;
+ constexpr int f() { return sizeof(T); } // expected-warning {{will not be implicitly 'const' in C++1y}}
+ };
+
+ // Virtual f(), not OK.
+ constexpr X<X<S1>> xxs1;
+ constexpr X<S1> *p = const_cast<X<X<S1>>*>(&xxs1);
+ static_assert(p->f() == sizeof(X<S1>), ""); // expected-error {{constant expression}} expected-note {{virtual function call}}
+
+ // Non-virtual f(), OK.
+ constexpr X<X<S2>> xxs2;
+ constexpr X<S2> *q = const_cast<X<X<S2>>*>(&xxs2);
+ static_assert(q->f() == sizeof(S2), "");
+}
+
+namespace ConstexprConstructorRecovery {
+ class X {
+ public:
+ enum E : short {
+ headers = 0x1,
+ middlefile = 0x2,
+ choices = 0x4
+ };
+ constexpr X() noexcept {};
+ protected:
+ E val{0}; // expected-error {{cannot initialize a member subobject of type 'ConstexprConstructorRecovery::X::E' with an rvalue of type 'int'}}
+ };
+ constexpr X x{};
+}
+
+namespace Lifetime {
+ void f() {
+ constexpr int &n = n; // expected-error {{constant expression}} expected-note {{use of reference outside its lifetime}} expected-warning {{not yet bound to a value}}
+ constexpr int m = m; // expected-error {{constant expression}} expected-note {{read of object outside its lifetime}}
+ }
+
+ constexpr int &get(int &&n) { return n; }
+ struct S {
+ int &&r; // expected-note 2{{declared here}}
+ int &s;
+ int t;
+ constexpr S() : r(0), s(get(0)), t(r) {} // expected-warning {{temporary}}
+ constexpr S(int) : r(0), s(get(0)), t(s) {} // expected-warning {{temporary}} expected-note {{read of object outside its lifetime}}
+ };
+ constexpr int k1 = S().t; // ok, int is lifetime-extended to end of constructor
+ constexpr int k2 = S(0).t; // expected-error {{constant expression}} expected-note {{in call}}
+}
+
+namespace Bitfields {
+ struct A {
+ bool b : 1;
+ unsigned u : 5;
+ int n : 5;
+ bool b2 : 3;
+ unsigned u2 : 74; // expected-warning {{exceeds the size of its type}}
+ int n2 : 81; // expected-warning {{exceeds the size of its type}}
+ };
+
+ constexpr A a = { false, 33, 31, false, 0xffffffff, 0x7fffffff }; // expected-warning 2{{truncation}}
+ static_assert(a.b == 0 && a.u == 1 && a.n == -1 && a.b2 == 0 &&
+ a.u2 + 1 == 0 && a.n2 == 0x7fffffff,
+ "bad truncation of bitfield values");
+
+ struct B {
+ int n : 3;
+ constexpr B(int k) : n(k) {}
+ };
+ static_assert(B(3).n == 3, "");
+ static_assert(B(4).n == -4, "");
+ static_assert(B(7).n == -1, "");
+ static_assert(B(8).n == 0, "");
+ static_assert(B(-1).n == -1, "");
+ static_assert(B(-8889).n == -1, "");
+
+ namespace PR16755 {
+ struct X {
+ int x : 1;
+ constexpr static int f(int x) {
+ return X{x}.x;
+ }
+ };
+ static_assert(X::f(3) == -1, "3 should truncate to -1");
+ }
+}
+
+namespace ZeroSizeTypes {
+ constexpr int (*p1)[0] = 0, (*p2)[0] = 0;
+ constexpr int k = p2 - p1;
+ // expected-error@-1 {{constexpr variable 'k' must be initialized by a constant expression}}
+ // expected-note@-2 {{subtraction of pointers to type 'int [0]' of zero size}}
+
+ int arr[5][0];
+ constexpr int f() { // expected-error {{never produces a constant expression}}
+ return &arr[3] - &arr[0]; // expected-note {{subtraction of pointers to type 'int [0]' of zero size}}
+ }
+}
+
+namespace BadDefaultInit {
+ template<int N> struct X { static const int n = N; };
+
+ struct A { // expected-note {{subexpression}}
+ int k = X<A().k>::n; // expected-error {{defaulted default constructor of 'A' cannot be used}} expected-error {{not a constant expression}} expected-note {{in call to 'A()'}}
+ };
+
+ // FIXME: The "constexpr constructor must initialize all members" diagnostic
+ // here is bogus (we discard the k(k) initializer because the parameter 'k'
+ // has been marked invalid).
+ struct B { // expected-note 2{{candidate}}
+ constexpr B( // expected-error {{must initialize all members}} expected-note {{candidate}}
+ int k = X<B().k>::n) : // expected-error {{no matching constructor}}
+ k(k) {}
+ int k; // expected-note {{not initialized}}
+ };
+}
+
+namespace NeverConstantTwoWays {
+ // If we see something non-constant but foldable followed by something
+ // non-constant and not foldable, we want the first diagnostic, not the
+ // second.
+ constexpr int f(int n) { // expected-error {{never produces a constant expression}}
+ return (int *)(long)&n == &n ? // expected-note {{reinterpret_cast}}
+ 1 / 0 : // expected-warning {{division by zero}}
+ 0;
+ }
+
+ // FIXME: We should diagnose the cast to long here, not the division by zero.
+ constexpr int n = // expected-error {{must be initialized by a constant expression}}
+ (int *)(long)&n == &n ?
+ 1 / 0 : // expected-warning {{division by zero}} expected-note {{division by zero}}
+ 0;
+}
+
+namespace PR17800 {
+ struct A {
+ constexpr int operator()() const { return 0; }
+ };
+ template <typename ...T> constexpr int sink(T ...) {
+ return 0;
+ }
+ template <int ...N> constexpr int run() {
+ return sink(A()() + N ...);
+ }
+ constexpr int k = run<1, 2, 3>();
+}
+
+namespace BuiltinStrlen {
+ constexpr const char *a = "foo\0quux";
+ constexpr char b[] = "foo\0quux";
+ constexpr int f() { return 'u'; }
+ constexpr char c[] = { 'f', 'o', 'o', 0, 'q', f(), 'u', 'x', 0 };
+
+ static_assert(__builtin_strlen("foo") == 3, "");
+ static_assert(__builtin_strlen("foo\0quux") == 3, "");
+ static_assert(__builtin_strlen("foo\0quux" + 4) == 4, "");
+
+ constexpr bool check(const char *p) {
+ return __builtin_strlen(p) == 3 &&
+ __builtin_strlen(p + 1) == 2 &&
+ __builtin_strlen(p + 2) == 1 &&
+ __builtin_strlen(p + 3) == 0 &&
+ __builtin_strlen(p + 4) == 4 &&
+ __builtin_strlen(p + 5) == 3 &&
+ __builtin_strlen(p + 6) == 2 &&
+ __builtin_strlen(p + 7) == 1 &&
+ __builtin_strlen(p + 8) == 0;
+ }
+
+ static_assert(check(a), "");
+ static_assert(check(b), "");
+ static_assert(check(c), "");
+
+ constexpr int over1 = __builtin_strlen(a + 9); // expected-error {{constant expression}} expected-note {{one-past-the-end}}
+ constexpr int over2 = __builtin_strlen(b + 9); // expected-error {{constant expression}} expected-note {{one-past-the-end}}
+ constexpr int over3 = __builtin_strlen(c + 9); // expected-error {{constant expression}} expected-note {{one-past-the-end}}
+
+ constexpr int under1 = __builtin_strlen(a - 1); // expected-error {{constant expression}} expected-note {{cannot refer to element -1}}
+ constexpr int under2 = __builtin_strlen(b - 1); // expected-error {{constant expression}} expected-note {{cannot refer to element -1}}
+ constexpr int under3 = __builtin_strlen(c - 1); // expected-error {{constant expression}} expected-note {{cannot refer to element -1}}
+
+ // FIXME: The diagnostic here could be better.
+ constexpr char d[] = { 'f', 'o', 'o' }; // no nul terminator.
+ constexpr int bad = __builtin_strlen(d); // expected-error {{constant expression}} expected-note {{one-past-the-end}}
+}
diff --git a/test/SemaCXX/constant-expression-cxx1y.cpp b/test/SemaCXX/constant-expression-cxx1y.cpp
index 60ec820..521526d 100644
--- a/test/SemaCXX/constant-expression-cxx1y.cpp
+++ b/test/SemaCXX/constant-expression-cxx1y.cpp
@@ -128,10 +128,10 @@ constexpr int namespace_alias() {
namespace assign {
constexpr int a = 0;
const int b = 0;
- int c = 0; // expected-note 2{{here}}
+ int c = 0; // expected-note {{here}}
constexpr void set(const int &a, int b) {
- const_cast<int&>(a) = b; // expected-note 2{{constant expression cannot modify an object that is visible outside that expression}}
+ const_cast<int&>(a) = b; // expected-note 3{{constant expression cannot modify an object that is visible outside that expression}}
}
constexpr int wrap(int a, int b) {
set(a, b);
@@ -140,7 +140,7 @@ namespace assign {
static_assert((set(a, 1), a) == 1, ""); // expected-error {{constant expression}} expected-note {{in call to 'set(a, 1)'}}
static_assert((set(b, 1), b) == 1, ""); // expected-error {{constant expression}} expected-note {{in call to 'set(b, 1)'}}
- static_assert((set(c, 1), c) == 1, ""); // expected-error {{constant expression}} expected-note {{read of non-const variable 'c'}}
+ static_assert((set(c, 1), c) == 1, ""); // expected-error {{constant expression}} expected-note {{in call to 'set(c, 1)'}}
static_assert(wrap(a, 1) == 1, "");
static_assert(wrap(b, 1) == 1, "");
@@ -250,11 +250,12 @@ namespace lifetime {
}
namespace const_modify {
- constexpr int modify(int &n) { return n = 1; } // expected-note {{modification of object of const-qualified type 'const int'}}
+ constexpr int modify(int &n) { return n = 1; } // expected-note 2 {{modification of object of const-qualified type 'const int'}}
constexpr int test1() { int k = 0; return modify(k); }
- constexpr int test2() { const int k = 0; return modify(const_cast<int&>(k)); } // expected-note {{in call}}
+ constexpr int test2() { const int k = 0; return modify(const_cast<int&>(k)); } // expected-note 2 {{in call}}
static_assert(test1() == 1, "");
static_assert(test2() == 1, ""); // expected-error {{constant expression}} expected-note {{in call}}
+ constexpr int i = test2(); // expected-error {{constant expression}} expected-note {{in call}}
}
namespace null {
@@ -334,6 +335,99 @@ namespace incdec {
static_assert(incr(0) == 101, "");
}
+namespace compound_assign {
+ constexpr bool test_int() {
+ int a = 3;
+ a += 6;
+ if (a != 9) return false;
+ a -= 2;
+ if (a != 7) return false;
+ a *= 3;
+ if (a != 21) return false;
+ if (&(a /= 10) != &a) return false;
+ if (a != 2) return false;
+ a <<= 3;
+ if (a != 16) return false;
+ a %= 6;
+ if (a != 4) return false;
+ a >>= 1;
+ if (a != 2) return false;
+ a ^= 10;
+ if (a != 8) return false;
+ a |= 5;
+ if (a != 13) return false;
+ a &= 14;
+ if (a != 12) return false;
+ return true;
+ }
+ static_assert(test_int(), "");
+
+ constexpr bool test_float() {
+ float f = 123.;
+ f *= 2;
+ if (f != 246.) return false;
+ if ((f -= 0.5) != 245.5) return false;
+ if (f != 245.5) return false;
+ f /= 0.5;
+ if (f != 491.) return false;
+ f += -40;
+ if (f != 451.) return false;
+ return true;
+ }
+ static_assert(test_float(), "");
+
+ constexpr bool test_ptr() {
+ int arr[123] = {};
+ int *p = arr;
+ if ((p += 4) != &arr[4]) return false;
+ if (p != &arr[4]) return false;
+ p += -1;
+ if (p != &arr[3]) return false;
+ if ((p -= -10) != &arr[13]) return false;
+ if (p != &arr[13]) return false;
+ p -= 11;
+ if (p != &arr[2]) return false;
+ return true;
+ }
+ static_assert(test_ptr(), "");
+
+ template<typename T>
+ constexpr bool test_overflow() {
+ T a = 1;
+ while (a != a / 2)
+ a *= 2; // expected-note {{value 2147483648 is outside the range}} expected-note {{ 9223372036854775808 }} expected-note {{floating point arithmetic produces an infinity}}
+ return true;
+ }
+
+ static_assert(test_overflow<int>(), ""); // expected-error {{constant}} expected-note {{call}}
+ static_assert(test_overflow<unsigned>(), ""); // ok, unsigned overflow is defined
+ static_assert(test_overflow<short>(), ""); // ok, short is promoted to int before multiplication
+ static_assert(test_overflow<unsigned short>(), ""); // ok
+ static_assert(test_overflow<unsigned long long>(), ""); // ok
+ static_assert(test_overflow<long long>(), ""); // expected-error {{constant}} expected-note {{call}}
+ static_assert(test_overflow<float>(), ""); // expected-error {{constant}} expected-note {{call}}
+
+ constexpr short test_promotion(short k) {
+ short s = k;
+ s *= s;
+ return s;
+ }
+ static_assert(test_promotion(100) == 10000, "");
+ static_assert(test_promotion(200) == -25536, "");
+ static_assert(test_promotion(256) == 0, "");
+
+ constexpr const char *test_bounds(const char *p, int o) {
+ return p += o; // expected-note {{element 5 of}} expected-note {{element -1 of}} expected-note {{element 1000 of}}
+ }
+ static_assert(test_bounds("foo", 0)[0] == 'f', "");
+ static_assert(test_bounds("foo", 3)[0] == 0, "");
+ static_assert(test_bounds("foo", 4)[-3] == 'o', "");
+ static_assert(test_bounds("foo" + 4, -4)[0] == 'f', "");
+ static_assert(test_bounds("foo", 5) != 0, ""); // expected-error {{constant}} expected-note {{call}}
+ static_assert(test_bounds("foo", -1) != 0, ""); // expected-error {{constant}} expected-note {{call}}
+ static_assert(test_bounds("foo", 1000) != 0, ""); // expected-error {{constant}} expected-note {{call}}
+}
+
namespace loops {
constexpr int fib_loop(int a) {
int f_k = 0, f_k_plus_one = 1;
@@ -407,7 +501,7 @@ namespace loops {
int arr[] = { 1, 2, 3, 4, 5 };
int sum = 0;
for (int x : arr)
- sum = sum + x;
+ sum += x;
return sum;
}
static_assert(range_for() == 15, "");
@@ -450,10 +544,370 @@ namespace loops {
array<int, 5> arr { 1, 2, 3, 4, 5 };
int sum = 0;
for (int k : arr) {
- sum = sum + k;
+ sum += k;
if (sum > 8) break;
}
return sum;
}
static_assert(range_for_2() == 10, "");
}
+
+namespace assignment_op {
+ struct A {
+ constexpr A() : n(5) {}
+ int n;
+ struct B {
+ int k = 1;
+ union U {
+ constexpr U() : y(4) {}
+ int x;
+ int y;
+ } u;
+ } b;
+ };
+ constexpr bool testA() {
+ A a, b;
+ a.n = 7;
+ a.b.u.y = 5;
+ b = a;
+ return b.n == 7 && b.b.u.y == 5 && b.b.k == 1;
+ }
+ static_assert(testA(), "");
+
+ struct B {
+ bool assigned = false;
+ constexpr B &operator=(const B&) {
+ assigned = true;
+ return *this;
+ }
+ };
+ struct C : B {
+ B b;
+ int n = 5;
+ };
+ constexpr bool testC() {
+ C c, d;
+ c.n = 7;
+ d = c;
+ c.n = 3;
+ return d.n == 7 && d.assigned && d.b.assigned;
+ }
+ static_assert(testC(), "");
+}
+
+namespace switch_stmt {
+ constexpr int f(char k) {
+ bool b = false;
+ int z = 6;
+ switch (k) {
+ return -1;
+ case 0:
+ if (false) {
+ case 1:
+ z = 1;
+ for (; b;) {
+ return 5;
+ while (0)
+ case 2: return 2;
+ case 7: z = 7;
+ do case 6: {
+ return z;
+ if (false)
+ case 3: return 3;
+ case 4: z = 4;
+ } while (1);
+ case 5: b = true;
+ case 9: z = 9;
+ }
+ return z;
+ } else if (false) case 8: z = 8;
+ else if (false) {
+ case 10:
+ z = -10;
+ break;
+ }
+ else z = 0;
+ return z;
+ default:
+ return -1;
+ }
+ return -z;
+ }
+ static_assert(f(0) == 0, "");
+ static_assert(f(1) == 1, "");
+ static_assert(f(2) == 2, "");
+ static_assert(f(3) == 3, "");
+ static_assert(f(4) == 4, "");
+ static_assert(f(5) == 5, "");
+ static_assert(f(6) == 6, "");
+ static_assert(f(7) == 7, "");
+ static_assert(f(8) == 8, "");
+ static_assert(f(9) == 9, "");
+ static_assert(f(10) == 10, "");
+
+ // Check that we can continue an outer loop from within a switch.
+ constexpr bool contin() {
+ for (int n = 0; n != 10; ++n) {
+ switch (n) {
+ case 0:
+ ++n;
+ continue;
+ case 1:
+ return false;
+ case 2:
+ return true;
+ }
+ }
+ return false;
+ }
+ static_assert(contin(), "");
+
+ constexpr bool switch_into_for() {
+ int n = 0;
+ switch (n) {
+ for (; n == 1; ++n) {
+ return n == 1;
+ case 0: ;
+ }
+ }
+ return false;
+ }
+ static_assert(switch_into_for(), "");
+
+ constexpr void duff_copy(char *a, const char *b, int n) {
+ switch ((n - 1) % 8 + 1) {
+ for ( ; n; n = (n - 1) & ~7) {
+ case 8: a[n-8] = b[n-8];
+ case 7: a[n-7] = b[n-7];
+ case 6: a[n-6] = b[n-6];
+ case 5: a[n-5] = b[n-5];
+ case 4: a[n-4] = b[n-4];
+ case 3: a[n-3] = b[n-3];
+ case 2: a[n-2] = b[n-2];
+ case 1: a[n-1] = b[n-1];
+ }
+ case 0: ;
+ }
+ }
+
+ constexpr bool test_copy(const char *str, int n) {
+ char buffer[16] = {};
+ duff_copy(buffer, str, n);
+ for (int i = 0; i != sizeof(buffer); ++i)
+ if (buffer[i] != (i < n ? str[i] : 0))
+ return false;
+ return true;
+ }
+ static_assert(test_copy("foo", 0), "");
+ static_assert(test_copy("foo", 1), "");
+ static_assert(test_copy("foo", 2), "");
+ static_assert(test_copy("hello world", 0), "");
+ static_assert(test_copy("hello world", 7), "");
+ static_assert(test_copy("hello world", 8), "");
+ static_assert(test_copy("hello world", 9), "");
+ static_assert(test_copy("hello world", 10), "");
+ static_assert(test_copy("hello world", 10), "");
+}
+
+namespace deduced_return_type {
+ constexpr auto f() { return 0; }
+ template<typename T> constexpr auto g(T t) { return t; }
+ static_assert(f() == 0, "");
+ static_assert(g(true), "");
+}
+
+namespace modify_temporary_during_construction {
+ struct A { int &&temporary; int x; int y; };
+ constexpr int f(int &r) { r *= 9; return r - 12; }
+ // FIXME: The 'uninitialized' warning here is bogus.
+ constexpr A a = { 6, f(a.temporary), a.temporary }; // expected-warning {{uninitialized}} expected-note {{temporary created here}}
+ static_assert(a.x == 42, "");
+ static_assert(a.y == 54, "");
+ constexpr int k = a.temporary++; // expected-error {{constant expression}} expected-note {{outside the expression that created the temporary}}
+}
+
+namespace std {
+ typedef decltype(sizeof(int)) size_t;
+
+ template <class _E>
+ class initializer_list
+ {
+ const _E* __begin_;
+ size_t __size_;
+
+ constexpr initializer_list(const _E* __b, size_t __s)
+ : __begin_(__b),
+ __size_(__s)
+ {}
+
+ public:
+ typedef _E value_type;
+ typedef const _E& reference;
+ typedef const _E& const_reference;
+ typedef size_t size_type;
+
+ typedef const _E* iterator;
+ typedef const _E* const_iterator;
+
+ constexpr initializer_list() : __begin_(nullptr), __size_(0) {}
+
+ constexpr size_t size() const {return __size_;}
+ constexpr const _E* begin() const {return __begin_;}
+ constexpr const _E* end() const {return __begin_ + __size_;}
+ };
+}
+
+namespace InitializerList {
+ constexpr int sum(std::initializer_list<int> ints) {
+ int total = 0;
+ for (int n : ints) total += n;
+ return total;
+ }
+ static_assert(sum({1, 2, 3, 4, 5}) == 15, "");
+}
+
+namespace StmtExpr {
+ constexpr int f(int k) {
+ switch (k) {
+ case 0:
+ return 0;
+
+ ({
+ case 1: // expected-note {{not supported}}
+ return 1;
+ });
+ }
+ }
+ static_assert(f(1) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}}
+
+ constexpr int g() { // expected-error {{never produces a constant}}
+ return ({ int n; n; }); // expected-note {{object of type 'int' is not initialized}}
+ }
+
+ // FIXME: We should handle the void statement expression case.
+ constexpr int h() { // expected-error {{never produces a constant}}
+ ({ if (true) {} }); // expected-note {{not supported}}
+ return 0;
+ }
+}
+
+namespace VirtualFromBase {
+ struct S1 {
+ virtual int f() const;
+ };
+ struct S2 {
+ virtual int f();
+ };
+ template <typename T> struct X : T {
+ constexpr X() {}
+ double d = 0.0;
+ constexpr int f() { return sizeof(T); }
+ };
+
+ // Non-virtual f(), OK.
+ constexpr X<X<S1>> xxs1;
+ constexpr X<S1> *p = const_cast<X<X<S1>>*>(&xxs1);
+ static_assert(p->f() == sizeof(S1), "");
+
+ // Virtual f(), not OK.
+ constexpr X<X<S2>> xxs2;
+ constexpr X<S2> *q = const_cast<X<X<S2>>*>(&xxs2);
+ static_assert(q->f() == sizeof(X<S2>), ""); // expected-error {{constant expression}} expected-note {{virtual function call}}
+}
+
+namespace Lifetime {
+ constexpr int &get(int &&r) { return r; }
+ constexpr int f() {
+ int &r = get(123);
+ return r; // expected-note {{read of object outside its lifetime}}
+ }
+ static_assert(f() == 123, ""); // expected-error {{constant expression}} expected-note {{in call}}
+
+ constexpr int g() {
+ int *p = 0;
+ {
+ int n = 0;
+ p = &n;
+ n = 42;
+ }
+ *p = 123; // expected-note {{assignment to object outside its lifetime}}
+ return *p;
+ }
+ static_assert(g() == 42, ""); // expected-error {{constant expression}} expected-note {{in call}}
+
+ constexpr int h(int n) {
+ int *p[4] = {};
+ int &&r = 1;
+ p[0] = &r;
+ while (int a = 1) {
+ p[1] = &a;
+ for (int b = 1; int c = 1; ) {
+ p[2] = &b, p[3] = &c;
+ break;
+ }
+ break;
+ }
+ *p[n] = 0; // expected-note 3{{assignment to object outside its lifetime}}
+ return *p[n];
+ }
+ static_assert(h(0) == 0, ""); // ok, lifetime-extended
+ static_assert(h(1) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}}
+ static_assert(h(2) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}}
+ static_assert(h(3) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}}
+
+ // FIXME: This function should be treated as non-constant.
+ constexpr void lifetime_versus_loops() {
+ int *p = 0;
+ for (int i = 0; i != 2; ++i) {
+ int *q = p;
+ int n = 0;
+ p = &n;
+ if (i)
+ // This modifies the 'n' from the previous iteration of the loop outside
+ // its lifetime.
+ ++*q;
+ }
+ }
+ static_assert((lifetime_versus_loops(), true), "");
+}
+
+namespace Bitfields {
+ struct A {
+ bool b : 3;
+ int n : 4;
+ unsigned u : 5;
+ };
+ constexpr bool test() {
+ A a {};
+ a.b += 2;
+ --a.n;
+ --a.u;
+ a.n = -a.n * 3;
+ return a.b == false && a.n == 3 && a.u == 31;
+ }
+ static_assert(test(), "");
+}
+
+namespace PR17615 {
+ struct A {
+ int &&r;
+ constexpr A(int &&r) : r(static_cast<int &&>(r)) {}
+ constexpr A() : A(0) {
+ (void)+r; // expected-note {{outside its lifetime}}
+ }
+ };
+ constexpr int k = A().r; // expected-error {{constant expression}} expected-note {{in call to}}
+}
+
+namespace PR17331 {
+ template<typename T, unsigned int N>
+ constexpr T sum(const T (&arr)[N]) {
+ T result = 0;
+ for (T i : arr)
+ result += i;
+ return result;
+ }
+
+ constexpr int ARR[] = { 1, 2, 3, 4, 5 };
+ static_assert(sum(ARR) == 15, "");
+}
diff --git a/test/SemaCXX/constexpr-backtrace-limit.cpp b/test/SemaCXX/constexpr-backtrace-limit.cpp
index 9c40eed..64a26cf 100644
--- a/test/SemaCXX/constexpr-backtrace-limit.cpp
+++ b/test/SemaCXX/constexpr-backtrace-limit.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only %s -fconstexpr-backtrace-limit 0 -fconstexpr-depth 4 -fno-caret-diagnostics 2>&1 | FileCheck %s -check-prefix=TEST1
+// RUN: not %clang_cc1 -std=c++11 -fsyntax-only %s -fconstexpr-backtrace-limit 0 -fconstexpr-depth 4 -fno-caret-diagnostics 2>&1 | FileCheck %s -check-prefix=TEST1
// TEST1: constant expression
// TEST1-NEXT: exceeded maximum depth of 4
// TEST1-NEXT: in call to 'recurse(2)'
@@ -6,21 +6,21 @@
// TEST1-NEXT: in call to 'recurse(4)'
// TEST1-NEXT: in call to 'recurse(5)'
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only %s -fconstexpr-backtrace-limit 2 -fconstexpr-depth 4 -fno-caret-diagnostics 2>&1 | FileCheck %s -check-prefix=TEST2
+// RUN: not %clang_cc1 -std=c++11 -fsyntax-only %s -fconstexpr-backtrace-limit 2 -fconstexpr-depth 4 -fno-caret-diagnostics 2>&1 | FileCheck %s -check-prefix=TEST2
// TEST2: constant expression
// TEST2-NEXT: exceeded maximum depth of 4
// TEST2-NEXT: in call to 'recurse(2)'
// TEST2-NEXT: skipping 2 calls
// TEST2-NEXT: in call to 'recurse(5)'
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only %s -fconstexpr-backtrace-limit 2 -fconstexpr-depth 8 -fno-caret-diagnostics 2>&1 | FileCheck %s -check-prefix=TEST3
+// RUN: not %clang_cc1 -std=c++11 -fsyntax-only %s -fconstexpr-backtrace-limit 2 -fconstexpr-depth 8 -fno-caret-diagnostics 2>&1 | FileCheck %s -check-prefix=TEST3
// TEST3: constant expression
// TEST3-NEXT: reinterpret_cast
// TEST3-NEXT: in call to 'recurse(0)'
// TEST3-NEXT: skipping 4 calls
// TEST3-NEXT: in call to 'recurse(5)'
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only %s -fconstexpr-backtrace-limit 8 -fconstexpr-depth 8 -fno-caret-diagnostics 2>&1 | FileCheck %s -check-prefix=TEST4
+// RUN: not %clang_cc1 -std=c++11 -fsyntax-only %s -fconstexpr-backtrace-limit 8 -fconstexpr-depth 8 -fno-caret-diagnostics 2>&1 | FileCheck %s -check-prefix=TEST4
// TEST4: constant expression
// TEST4-NEXT: reinterpret_cast
// TEST4-NEXT: in call to 'recurse(0)'
diff --git a/test/SemaCXX/constexpr-duffs-device.cpp b/test/SemaCXX/constexpr-duffs-device.cpp
new file mode 100644
index 0000000..f77d989
--- /dev/null
+++ b/test/SemaCXX/constexpr-duffs-device.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -std=c++1y -verify %s
+
+// expected-no-diagnostics
+constexpr void copy(const char *from, unsigned long count, char *to) {
+ unsigned long n = (count + 7) / 8;
+ switch(count % 8) {
+ case 0: do { *to++ = *from++;
+ case 7: *to++ = *from++;
+ case 6: *to++ = *from++;
+ case 5: *to++ = *from++;
+ case 4: *to++ = *from++;
+ case 3: *to++ = *from++;
+ case 2: *to++ = *from++;
+ case 1: *to++ = *from++;
+ } while(--n > 0);
+ }
+}
+
+struct S {
+ char stuff[14];
+ constexpr S() : stuff{} {
+ copy("Hello, world!", 14, stuff);
+ }
+};
+
+constexpr bool streq(const char *a, const char *b) {
+ while (*a && *a == *b) ++a, ++b;
+ return *a == *b;
+}
+
+static_assert(streq(S().stuff, "Hello, world!"), "should be same");
+static_assert(!streq(S().stuff, "Something else"), "should be different");
diff --git a/test/SemaCXX/constexpr-steps.cpp b/test/SemaCXX/constexpr-steps.cpp
new file mode 100644
index 0000000..f7967ee
--- /dev/null
+++ b/test/SemaCXX/constexpr-steps.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=c++1y -fsyntax-only -verify %s -DMAX=1234 -fconstexpr-steps 1234
+// RUN: %clang_cc1 -std=c++1y -fsyntax-only -verify %s -DMAX=10 -fconstexpr-steps 10
+// RUN: %clang -std=c++1y -fsyntax-only -Xclang -verify %s -DMAX=12345 -fconstexpr-steps=12345
+
+// This takes a total of n + 4 steps according to our current rules:
+// - One for the compound-statement that is the function body
+// - One for the 'for' statement
+// - One for the 'int k = 0;' statement
+// - One for each of the n evaluations of the compound-statement in the 'for' body
+// - One for the 'return' statemnet
+constexpr bool steps(int n) {
+ for (int k = 0; k != n; ++k) {}
+ return true; // expected-note {{step limit}}
+}
+
+static_assert(steps((MAX - 4)), ""); // ok
+static_assert(steps((MAX - 3)), ""); // expected-error {{constant}} expected-note{{call}}
diff --git a/test/SemaCXX/constexpr-turing.cpp b/test/SemaCXX/constexpr-turing.cpp
index 07c04ef..75aefbf 100644
--- a/test/SemaCXX/constexpr-turing.cpp
+++ b/test/SemaCXX/constexpr-turing.cpp
@@ -33,24 +33,24 @@ constexpr Tape move(const Tape &old, Dir dir) { return Tape(old, dir); }
// Run turing machine 'tm' on tape 'tape' from state 'state'. Return number of
// steps taken until halt.
constexpr unsigned run(const State *tm, const Tape &tape, unsigned state) {
- return state == halt ? 1 :
+ return state == halt ? 0 :
run(tm, move(update(tape, tm[state][tape.val].tape),
tm[state][tape.val].dir),
tm[state][tape.val].next) + 1;
}
-// 3-state busy beaver. 14 steps.
+// 3-state busy beaver. S(bb3) = 21.
constexpr State bb3[] = {
- { { true, R, 1 }, { true, L, 2 } },
- { { true, L, 0 }, { true, R, 1 } },
- { { true, L, 1 }, { true, R, halt } }
+ { { true, R, 1 }, { true, R, halt } },
+ { { true, L, 1 }, { false, R, 2 } },
+ { { true, L, 2 }, { true, L, 0 } }
};
-static_assert(run(bb3, Tape(), 0) == 14, "");
+static_assert(run(bb3, Tape(), 0) == 21, "");
-// 4-state busy beaver. 108 steps.
+// 4-state busy beaver. S(bb4) = 107.
constexpr State bb4[] = {
{ { true, R, 1 }, { true, L, 1 } },
{ { true, L, 0 }, { false, L, 2 } },
{ { true, R, halt }, { true, L, 3 } },
{ { true, R, 3 }, { false, R, 0 } } };
-static_assert(run(bb4, Tape(), 0) == 108, "");
+static_assert(run(bb4, Tape(), 0) == 107, "");
diff --git a/test/SemaCXX/constexpr-value-init.cpp b/test/SemaCXX/constexpr-value-init.cpp
index d137bd8..e5b7db5 100644
--- a/test/SemaCXX/constexpr-value-init.cpp
+++ b/test/SemaCXX/constexpr-value-init.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -std=c++11 -fsyntax-only -verify
+// RUN: %clang_cc1 %s -Wno-uninitialized -std=c++11 -fsyntax-only -verify
struct A {
constexpr A() : a(b + 1), b(a + 1) {} // expected-note {{outside its lifetime}}
diff --git a/test/SemaCXX/conversion-delete-expr.cpp b/test/SemaCXX/conversion-delete-expr.cpp
index 0f298a8..a1ddeb2 100644
--- a/test/SemaCXX/conversion-delete-expr.cpp
+++ b/test/SemaCXX/conversion-delete-expr.cpp
@@ -2,11 +2,11 @@
// Test1
struct B {
- operator char *(); // expected-note {{candidate function}}
+ operator char *(); // expected-note {{conversion to pointer type}}
};
struct D : B {
- operator int *(); // expected-note {{candidate function}}
+ operator int *(); // expected-note {{conversion to pointer type}}
};
void f (D d)
@@ -30,11 +30,11 @@ void f1 (D1 d)
// Test3
struct B2 {
- operator const int *(); // expected-note {{candidate function}}
+ operator const int *(); // expected-note {{conversion to pointer type}}
};
struct D2 : B2 {
- operator int *(); // expected-note {{candidate function}}
+ operator int *(); // expected-note {{conversion to pointer type}}
};
void f2 (D2 d)
@@ -44,11 +44,11 @@ void f2 (D2 d)
// Test4
struct B3 {
- operator const int *(); // expected-note {{candidate function}}
+ operator const int *(); // expected-note {{conversion to pointer type}}
};
struct A3 {
- operator const int *(); // expected-note {{candidate function}}
+ operator const int *(); // expected-note {{conversion to pointer type}}
};
struct D3 : A3, B3 {
@@ -78,7 +78,7 @@ void f5(X1 x) { delete x; } // OK. In selecting a conversion to pointer functio
// Test7
struct Base {
- operator int*();
+ operator int*();
};
struct Derived : Base {
@@ -87,9 +87,9 @@ struct Derived : Base {
};
void foo6(const Derived cd, Derived d) {
- // overload resolution selects Derived::operator int*() const;
- delete cd;
- delete d;
+ // overload resolution selects Derived::operator int*() const;
+ delete cd;
+ delete d;
}
// Test8
@@ -104,6 +104,6 @@ struct DD : BB {
void foo7 (DD d)
{
- // OK. In selecting a conversion to pointer function, template convesions are skipped.
- delete d;
+ // OK. In selecting a conversion to pointer function, template convesions are skipped.
+ delete d;
}
diff --git a/test/SemaCXX/conversion-function.cpp b/test/SemaCXX/conversion-function.cpp
index 6fca050..7eaed54 100644
--- a/test/SemaCXX/conversion-function.cpp
+++ b/test/SemaCXX/conversion-function.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
class X {
public:
operator bool();
@@ -11,6 +11,8 @@ public:
float g() {
return operator float(); // expected-error{{use of undeclared 'operator float'}}
}
+
+ static operator short(); // expected-error{{conversion function must be a non-static member function}}
};
operator int(); // expected-error{{conversion function must be a non-static member function}}
diff --git a/test/SemaCXX/conversion-incomplete-type.cpp b/test/SemaCXX/conversion-incomplete-type.cpp
new file mode 100644
index 0000000..ebedd04
--- /dev/null
+++ b/test/SemaCXX/conversion-incomplete-type.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct string {};
+
+class StringPiece; // expected-note {{forward declaration of 'StringPiece'}} \
+ // expected-note {{forward declaration of 'StringPiece'}}
+
+struct Test {
+ void expectStringPiece(const StringPiece& blah) {}; // expected-note {{passing argument to parameter 'blah' here}}
+
+ void test(const string& s) {
+ expectStringPiece(s); // expected-error {{no viable conversion from 'const string' to incomplete type 'const StringPiece'}}
+ }
+};
+
+struct TestStatic {
+ static void expectStringPiece(const StringPiece& blah) {}; // expected-note {{passing argument to parameter 'blah' here}}
+
+ static void test(const string& s) {
+ expectStringPiece(s); // expected-error {{no viable conversion from 'const string' to incomplete type 'const StringPiece'}}
+ }
+};
+
diff --git a/test/SemaCXX/crashes.cpp b/test/SemaCXX/crashes.cpp
index f5682bd..0b15bb0 100644
--- a/test/SemaCXX/crashes.cpp
+++ b/test/SemaCXX/crashes.cpp
@@ -171,3 +171,50 @@ namespace test3 {
int& x = dimenX.*sides;
}
}
+
+namespace pr16964 {
+ template<typename> struct bs {
+ bs();
+ static int* member();
+ member(); // expected-error{{C++ requires a type specifier for all declarations}}
+ static member(); // expected-error{{C++ requires a type specifier for all declarations}}
+ static int* member(int);
+ };
+
+ template<typename T> bs<T>::bs() { member; }
+
+ bs<int> test() {
+ return bs<int>();
+ }
+}
+
+namespace pr12791 {
+ template<class _Alloc> class allocator {};
+ template<class _CharT> struct char_traits;
+ struct input_iterator_tag {};
+ struct forward_iterator_tag : public input_iterator_tag {};
+
+ template<typename _CharT, typename _Traits, typename _Alloc> struct basic_string {
+ struct _Alloc_hider : _Alloc {};
+ mutable _Alloc_hider _M_dataplus;
+ template<class _InputIterator> basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a = _Alloc());
+ template<class _InIterator> static _CharT* _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, input_iterator_tag);
+ template<class _FwdIterator> static _CharT* _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a, forward_iterator_tag);
+ static _CharT* _S_construct(size_type __req, _CharT __c, const _Alloc& __a); // expected-error{{unknown type name 'size_type'}}
+ };
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ template<typename _InputIterator>
+ basic_string<_CharT, _Traits, _Alloc>:: basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a)
+ : _M_dataplus(_S_construct(__beg, __end, __a), __a) {}
+
+ template<typename _CharT, typename _Traits = char_traits<_CharT>, typename _Alloc = allocator<_CharT> > struct basic_stringbuf {
+ typedef _CharT char_type;
+ typedef basic_string<char_type, _Traits, _Alloc> __string_type;
+ typedef typename __string_type::size_type __size_type;
+ __string_type str() const {__string_type((char_type*)0,(char_type*)0);}
+ };
+
+ template class basic_stringbuf<char>;
+}
+
diff --git a/test/SemaCXX/cxx0x-class.cpp b/test/SemaCXX/cxx0x-class.cpp
index 074591e..2b1338f9 100644
--- a/test/SemaCXX/cxx0x-class.cpp
+++ b/test/SemaCXX/cxx0x-class.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wno-error=static-float-init %s
+// RUN: %clang_cc1 -Wno-uninitialized -fsyntax-only -verify -std=c++11 -Wno-error=static-float-init %s
int vs = 0;
diff --git a/test/SemaCXX/cxx0x-compat.cpp b/test/SemaCXX/cxx0x-compat.cpp
index 123008a..ffbd20f 100644
--- a/test/SemaCXX/cxx0x-compat.cpp
+++ b/test/SemaCXX/cxx0x-compat.cpp
@@ -1,4 +1,7 @@
// 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
+
+#if __cplusplus < 201103L
namespace N {
template<typename T> void f(T) {} // expected-note 2{{here}}
@@ -37,3 +40,9 @@ void h(size_t foo, size_t bar) {
#define _x + 1
char c = 'x'_x; // expected-warning {{will be treated as a user-defined literal suffix}}
+
+#else
+
+auto init_capture = [a(0)] {}; // expected-warning {{initialized lambda captures are incompatible with C++ standards before C++1y}}
+
+#endif
diff --git a/test/SemaCXX/cxx0x-initializer-aggregates.cpp b/test/SemaCXX/cxx0x-initializer-aggregates.cpp
index f53ac6d..0e9a97d 100644
--- a/test/SemaCXX/cxx0x-initializer-aggregates.cpp
+++ b/test/SemaCXX/cxx0x-initializer-aggregates.cpp
@@ -4,7 +4,6 @@ struct one { char c[1]; };
struct two { char c[2]; };
namespace aggregate {
- // Direct list initialization does NOT allow braces to be elided!
struct S {
int ar[2];
struct T {
@@ -20,25 +19,25 @@ namespace aggregate {
};
void bracing() {
- S s1 = { 1, 2, 3 ,4, 5, 6, 7, 8 }; // no-error
- S s2{ {1, 2}, {3, 4}, { {5}, {6} }, { {7, 8} } }; // completely braced
- S s3{ 1, 2, 3, 4, 5, 6 }; // expected-error 5 {{cannot omit braces}}
- S s4{ {1, 2}, {3, 4}, {5, 6}, { {7, 8} } }; // expected-error 2 {{cannot omit braces}}
- S s5{ {1, 2}, {3, 4}, { {5}, {6} }, {7, 8} }; // expected-error {{cannot omit braces}}
+ S s1 = { 1, 2, 3 ,4, 5, 6, 7, 8 };
+ S s2{ {1, 2}, {3, 4}, { {5}, {6} }, { {7, 8} } };
+ S s3{ 1, 2, 3, 4, 5, 6 };
+ S s4{ {1, 2}, {3, 4}, {5, 6}, { {7, 8} } };
+ S s5{ {1, 2}, {3, 4}, { {5}, {6} }, {7, 8} };
}
void bracing_new() {
- new S{ {1, 2}, {3, 4}, { {5}, {6} }, { {7, 8} } }; // completely braced
- new S{ 1, 2, 3, 4, 5, 6 }; // expected-error 5 {{cannot omit braces}}
- new S{ {1, 2}, {3, 4}, {5, 6}, { {7, 8} } }; // expected-error 2 {{cannot omit braces}}
- new S{ {1, 2}, {3, 4}, { {5}, {6} }, {7, 8} }; // expected-error {{cannot omit braces}}
+ new S{ {1, 2}, {3, 4}, { {5}, {6} }, { {7, 8} } };
+ new S{ 1, 2, 3, 4, 5, 6 };
+ new S{ {1, 2}, {3, 4}, {5, 6}, { {7, 8} } };
+ new S{ {1, 2}, {3, 4}, { {5}, {6} }, {7, 8} };
}
void bracing_construct() {
- (void) S{ {1, 2}, {3, 4}, { {5}, {6} }, { {7, 8} } }; // completely braced
- (void) S{ 1, 2, 3, 4, 5, 6 }; // expected-error 5 {{cannot omit braces}}
- (void) S{ {1, 2}, {3, 4}, {5, 6}, { {7, 8} } }; // expected-error 2 {{cannot omit braces}}
- (void) S{ {1, 2}, {3, 4}, { {5}, {6} }, {7, 8} }; // expected-error {{cannot omit braces}}
+ (void) S{ {1, 2}, {3, 4}, { {5}, {6} }, { {7, 8} } };
+ (void) S{ 1, 2, 3, 4, 5, 6 };
+ (void) S{ {1, 2}, {3, 4}, {5, 6}, { {7, 8} } };
+ (void) S{ {1, 2}, {3, 4}, { {5}, {6} }, {7, 8} };
}
struct String {
diff --git a/test/SemaCXX/cxx0x-initializer-references.cpp b/test/SemaCXX/cxx0x-initializer-references.cpp
index 283c32a..9096c8a 100644
--- a/test/SemaCXX/cxx0x-initializer-references.cpp
+++ b/test/SemaCXX/cxx0x-initializer-references.cpp
@@ -36,10 +36,10 @@ namespace reference {
};
void call() {
- void f(const int&);
+ one f(const int&);
f({1});
- void g(int&); // expected-note {{passing argument}}
+ one g(int&); // expected-note {{passing argument}}
g({1}); // expected-error {{cannot bind to an initializer list temporary}}
int i = 0;
g({i});
@@ -97,3 +97,24 @@ namespace b7891773 {
int g(const ptr &);
int k = g({ f<int> });
}
+
+namespace inner_init {
+ struct A { int n; };
+ struct B { A &&r; };
+ B b1 { 0 }; // expected-error {{reference to type 'inner_init::A' could not bind to an rvalue of type 'int'}}
+ B b2 { { 0 } };
+ B b3 { { { 0 } } }; // expected-warning {{braces around scalar init}}
+
+ struct C { C(int); };
+ struct D { C &&r; };
+ D d1 { 0 }; // ok, 0 implicitly converts to C
+ D d2 { { 0 } }; // ok, { 0 } calls C(0)
+ D d3 { { { 0 } } }; // ok, { { 0 } } calls C({ 0 })
+ D d4 { { { { 0 } } } }; // expected-warning {{braces around scalar init}}
+
+ struct E { explicit E(int); }; // expected-note 2{{here}}
+ struct F { E &&r; };
+ F f1 { 0 }; // expected-error {{could not bind to an rvalue of type 'int'}}
+ F f2 { { 0 } }; // expected-error {{chosen constructor is explicit}}
+ F f3 { { { 0 } } }; // expected-error {{chosen constructor is explicit}}
+}
diff --git a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
index 88571d6..9d89cce 100644
--- a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -144,7 +144,7 @@ namespace PR12119 {
template<typename T> void g(std::initializer_list<std::initializer_list<T>>);
void foo() {
- f({0, {1}});
+ f({0, {1}}); // expected-warning{{braces around scalar initializer}}
g({{0, 1}, {2, 3}});
std::initializer_list<int> il = {1, 2};
g({il, {2, 3}});
@@ -208,3 +208,25 @@ namespace init_list_deduction_failure {
void h() { g({f}); }
// expected-error@-1 {{no matching function for call to 'g'}}
}
+
+namespace deleted_copy {
+ struct X {
+ X(int i) {}
+ X(const X& x) = delete; // expected-note {{here}}
+ void operator=(const X& x) = delete;
+ };
+
+ std::initializer_list<X> x{1}; // expected-error {{invokes deleted constructor}}
+}
+
+namespace RefVersusInitList {
+ struct S {};
+ void f(const S &) = delete;
+ void f(std::initializer_list<S>);
+ void g(S s) { f({S()}); }
+}
+
+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')}}
+}
diff --git a/test/SemaCXX/cxx0x-nontrivial-union.cpp b/test/SemaCXX/cxx0x-nontrivial-union.cpp
index 0e4add8..db296bd 100644
--- a/test/SemaCXX/cxx0x-nontrivial-union.cpp
+++ b/test/SemaCXX/cxx0x-nontrivial-union.cpp
@@ -122,3 +122,25 @@ namespace optional {
o2 = optional<non_trivial>();
}
}
+
+namespace pr16061 {
+ struct X { X(); };
+
+ template<typename T> struct Test1 {
+ union {
+ struct {
+ X x;
+ };
+ };
+ };
+
+ template<typename T> struct Test2 {
+ union {
+ struct { // expected-note {{default constructor of 'Test2<pr16061::X>' is implicitly deleted because variant field '' has a non-trivial default constructor}}
+ T x;
+ };
+ };
+ };
+
+ Test2<X> t2x; // expected-error {{call to implicitly-deleted default constructor of 'Test2<pr16061::X>'}}
+}
diff --git a/test/SemaCXX/cxx11-attr-print.cpp b/test/SemaCXX/cxx11-attr-print.cpp
index 19de5b5..01325d3 100644
--- a/test/SemaCXX/cxx11-attr-print.cpp
+++ b/test/SemaCXX/cxx11-attr-print.cpp
@@ -52,7 +52,7 @@ inline void f6() __attribute__((gnu_inline));
inline void f7 [[gnu::gnu_inline]] ();
// arguments printing
-// CHECK: __attribute__((format("printf", 2, 3)));
+// CHECK: __attribute__((format(printf, 2, 3)));
void f8 (void *, const char *, ...) __attribute__ ((format (printf, 2, 3)));
// CHECK: int m __attribute__((aligned(4
@@ -75,3 +75,6 @@ template <typename T> struct S {
// CHECK: static int f() __attribute__((pure))
// CHECK: static int g() {{\[}}[gnu::pure]]
template struct S<int>;
+
+// CHECK: using Small2 {{\[}}[gnu::mode(byte)]] = int;
+using Small2 [[gnu::mode(byte)]] = int;
diff --git a/test/SemaCXX/cxx11-crashes.cpp b/test/SemaCXX/cxx11-crashes.cpp
index a4d4829..bd51af1 100644
--- a/test/SemaCXX/cxx11-crashes.cpp
+++ b/test/SemaCXX/cxx11-crashes.cpp
@@ -70,9 +70,7 @@ namespace b6981007 {
for (auto x : s) {
// We used to attempt to evaluate the initializer of this variable,
// and crash because it has an undeduced type.
- // FIXME: We should set the loop variable to be invalid if we can't build
- // the loop, to suppress this follow-on error.
- const int &n(x); // expected-error {{could not bind to an lvalue of type 'auto'}}
+ const int &n(x);
}
}
}
diff --git a/test/SemaCXX/cxx11-gnu-attrs.cpp b/test/SemaCXX/cxx11-gnu-attrs.cpp
index def83a9..22d61a1 100644
--- a/test/SemaCXX/cxx11-gnu-attrs.cpp
+++ b/test/SemaCXX/cxx11-gnu-attrs.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang -cc1 -triple x86_64-unknown-unknown -std=c++11 -verify %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++11 -verify %s
// Error cases.
@@ -11,8 +11,9 @@ int *[[gnu::unused]] attr_on_ptr;
// Valid cases.
+void aliasb [[gnu::alias("_Z6alias1v")]] ();
void alias1() {}
-void alias2 [[gnu::alias("_Z6alias1v")]] ();
+void aliasa [[gnu::alias("_Z6alias1v")]] ();
[[gnu::aligned(8)]] int aligned;
void aligned_fn [[gnu::aligned(32)]] ();
diff --git a/test/SemaCXX/cxx11-thread-local-print.cpp b/test/SemaCXX/cxx11-thread-local-print.cpp
index 9d9a82b..1adafbd 100644
--- a/test/SemaCXX/cxx11-thread-local-print.cpp
+++ b/test/SemaCXX/cxx11-thread-local-print.cpp
@@ -7,3 +7,9 @@ __thread int gnu_tl;
_Thread_local int c11_tl;
thread_local int cxx11_tl;
+// CHECK: void foo() {
+// CHECK: thread_local int cxx11_tl;
+// CHECK: }
+void foo() {
+ thread_local int cxx11_tl;
+}
diff --git a/test/SemaCXX/cxx1y-array-runtime-bound.cpp b/test/SemaCXX/cxx1y-array-runtime-bound.cpp
deleted file mode 100644
index 1643adb..0000000
--- a/test/SemaCXX/cxx1y-array-runtime-bound.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-// RUN: %clang_cc1 -std=c++1y %s -verify -triple=x86_64-linux-gnu -pedantic-errors
-
-// FIXME: many diagnostics here say 'variably modified type'.
-// catch this case and say 'array of runtime bound' instead.
-
-namespace std { struct type_info; }
-
-struct S {
- int arr[__SIZE_MAX__ / 32];
-};
-S s[32]; // expected-error {{array is too large}}
-
-int n;
-int a[n]; // expected-error {{not allowed at file scope}}
-
-struct T {
- int a[n]; // expected-error {{fields must have a constant size}}
- static int b[n]; // expected-error {{not allowed at file scope}}
-};
-
-int g(int n, int a[n]);
-
-template<typename T> struct X {};
-template<int N, int[N]> struct Y {};
-template<int[n]> struct Z {}; // expected-error {{of variably modified type}}
-
-int f(int n) {
- int arb[n]; // expected-note 3{{here}}
- [arb] {} (); // expected-error {{cannot be captured}}
-
- // FIXME: an array of runtime bound can be captured by reference.
- [&arb] { // expected-error {{cannot be captured}}
- // Capturing the array implicitly captures the bound, if we need it
- // in a range-based for loop.
- for (auto &n : arb) { } // expected-error {{cannot be captured}}
- } ();
-
- X<int[n]> x; // expected-error {{variably modified type}}
-
- int arb_neg[-1]; // expected-error {{negative size}}
- int arb_of_array[n][2];
- int arr[3] = { 1, 2, 3, 4 }; // expected-error {{excess elements}}
- char foo[4] = "fool"; // expected-error {{initializer-string for char array is too long}}
-
- static int not_auto1[n]; // expected-error {{can not have 'static'}}
- extern int not_auto2[n]; // expected-error {{can not have 'extern'}}
- // FIXME: say 'thread_local' not 'static'.
- thread_local int not_auto1[n]; // expected-error {{can not have 'static'}}
-
- // FIXME: these should all be invalid.
- auto &&ti1 = typeid(arb);
- auto &&ti2 = typeid(int[n]);
- auto &&so1 = sizeof(arb);
- auto &&so2 = sizeof(int[n]);
- auto *p = &arb;
- decltype(arb) arb2;
- int (*arbp)[n] = 0;
- const int (&arbr)[n] = arbr; // expected-warning {{not yet bound}}
- typedef int arbty[n];
- int array_of_arb[2][n];
-
- struct Dyn { Dyn() {} Dyn(int) {} ~Dyn() {} };
-
- // FIXME: these should be valid.
- int arb_dynamic[n] = { 1, 2, 3, 4 }; // expected-error {{may not be initialized}}
- Dyn dyn[n]; // expected-error {{non-POD}}
- Dyn dyn_init[n] = { 1, 2, 3, 4 }; // expected-error {{non-POD}}
-}
diff --git a/test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp b/test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp
new file mode 100644
index 0000000..58bbbb2
--- /dev/null
+++ b/test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp
@@ -0,0 +1,177 @@
+// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only %s
+// RUN: %clang_cc1 -std=c++1y %s -verify -DCXX1Y
+
+// Explicit member declarations behave as in C++11.
+
+namespace n3323_example {
+
+ template <class T> class zero_init {
+ public:
+ zero_init() : val(static_cast<T>(0)) {}
+ zero_init(T val) : val(val) {}
+
+ operator T &() { return val; } //@13
+ operator T() const { return val; } //@14
+
+ private:
+ T val;
+ };
+
+ void Delete() {
+ zero_init<int *> p;
+ p = new int(7);
+ delete p; //@23
+ delete (p + 0);
+ delete + p;
+ }
+
+ void Switch() {
+ zero_init<int> i;
+ i = 7;
+ switch (i) {} // @31
+ switch (i + 0) {}
+ switch (+i) {}
+ }
+}
+
+#ifdef CXX1Y
+#else
+//expected-error@23 {{ambiguous conversion of delete expression of type 'zero_init<int *>' to a pointer}}
+//expected-note@13 {{conversion to pointer type 'int *'}}
+//expected-note@14 {{conversion to pointer type 'int *'}}
+//expected-error@31 {{multiple conversions from switch condition type 'zero_init<int>' to an integral or enumeration type}}
+//expected-note@13 {{conversion to integral type 'int'}}
+//expected-note@14 {{conversion to integral type 'int'}}
+#endif
+
+namespace extended_examples {
+
+ struct A0 {
+ operator int(); // matching and viable
+ };
+
+ struct A1 {
+ operator int() &&; // matching and not viable
+ };
+
+ struct A2 {
+ operator float(); // not matching
+ };
+
+ struct A3 {
+ template<typename T> operator T(); // not matching (ambiguous anyway)
+ };
+
+ struct A4 {
+ template<typename T> operator int(); // not matching (ambiguous anyway)
+ };
+
+ struct B1 {
+ operator int() &&; // @70
+ operator int(); // @71 -- duplicate declaration with different qualifier is not allowed
+ };
+
+ struct B2 {
+ operator int() &&; // matching but not viable
+ operator float(); // not matching
+ };
+
+ void foo(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, B2 b2) {
+ switch (a0) {}
+ switch (a1) {} // @81 -- fails for different reasons
+ switch (a2) {} // @82
+ switch (a3) {} // @83
+ switch (a4) {} // @84
+ switch (b2) {} // @85 -- fails for different reasons
+ }
+}
+
+//expected-error@71 {{cannot overload a member function without a ref-qualifier with a member function with ref-qualifier '&&'}}
+//expected-note@70 {{previous declaration is here}}
+//expected-error@82 {{statement requires expression of integer type ('extended_examples::A2' invalid)}}
+//expected-error@83 {{statement requires expression of integer type ('extended_examples::A3' invalid)}}
+//expected-error@84 {{statement requires expression of integer type ('extended_examples::A4' invalid)}}
+
+#ifdef CXX1Y
+//expected-error@81 {{statement requires expression of integer type ('extended_examples::A1' invalid)}}
+//expected-error@85 {{statement requires expression of integer type ('extended_examples::B2' invalid)}}
+#else
+//expected-error@81 {{cannot initialize object parameter of type 'extended_examples::A1' with an expression of type 'extended_examples::A1'}}
+//expected-error@85 {{cannot initialize object parameter of type 'extended_examples::B2' with an expression of type 'extended_examples::B2'}}
+#endif
+
+namespace extended_examples_cxx1y {
+
+ struct A1 { // leads to viable match in C++1y, and no viable match in C++11
+ operator int() &&; // matching but not viable
+ template <typename T> operator T(); // In C++1y: matching and viable, since disambiguated by L.100
+ };
+
+ struct A2 { // leads to ambiguity in C++1y, and no viable match in C++11
+ operator int() &&; // matching but not viable
+ template <typename T> operator int(); // In C++1y: matching but ambiguous (disambiguated by L.105).
+ };
+
+ struct B1 { // leads to one viable match in both cases
+ operator int(); // matching and viable
+ template <typename T> operator T(); // In C++1y: matching and viable, since disambiguated by L.110
+ };
+
+ struct B2 { // leads to one viable match in both cases
+ operator int(); // matching and viable
+ template <typename T> operator int(); // In C++1y: matching but ambiguous, since disambiguated by L.115
+ };
+
+ struct C { // leads to no match in both cases
+ operator float(); // not matching
+ template <typename T> operator T(); // In C++1y: not matching, nor viable.
+ };
+
+ struct D { // leads to viable match in C++1y, and no viable match in C++11
+ operator int() &&; // matching but not viable
+ operator float(); // not matching
+ template <typename T> operator T(); // In C++1y: matching and viable, since disambiguated by L.125
+ };
+
+
+ void foo(A1 a1, A2 a2, B1 b1, B2 b2, C c, D d) {
+ switch (a1) {} // @138 -- should presumably call templated conversion operator to convert to int.
+ switch (a2) {} // @139
+ switch (b1) {}
+ switch (b2) {}
+ switch (c) {} // @142
+ switch (d) {} // @143
+ }
+}
+
+//expected-error@142 {{statement requires expression of integer type ('extended_examples_cxx1y::C' invalid)}}
+
+#ifdef CXX1Y
+//expected-error@139 {{statement requires expression of integer type ('extended_examples_cxx1y::A2' invalid)}}
+#else
+//expected-error@138 {{cannot initialize object parameter of type 'extended_examples_cxx1y::A1' with an expression of type 'extended_examples_cxx1y::A1'}}
+//expected-error@139 {{cannot initialize object parameter of type 'extended_examples_cxx1y::A2' with an expression of type 'extended_examples_cxx1y::A2'}}
+//expected-error@143 {{cannot initialize object parameter of type 'extended_examples_cxx1y::D' with an expression of type 'extended_examples_cxx1y::D'}}
+#endif
+
+namespace extended_examples_array_bounds {
+
+ typedef decltype(sizeof(int)) size_t;
+
+ struct Foo {
+ operator size_t(); // @162
+ operator unsigned short(); // @163
+ };
+
+ void bar() {
+ Foo x;
+ int *p = new int[x]; // @168
+ }
+}
+
+#ifdef CXX1Y
+#else
+//expected-error@168 {{ambiguous conversion of array size expression of type 'extended_examples_array_bounds::Foo' to an integral or enumeration type}}
+//expected-note@162 {{conversion to integral type 'size_t'}}
+//expected-note@163 {{conversion to integral type 'unsigned short' declared here}}
+#endif
diff --git a/test/SemaCXX/cxx1y-deduced-return-type.cpp b/test/SemaCXX/cxx1y-deduced-return-type.cpp
index f0146f8..d3308b3 100644
--- a/test/SemaCXX/cxx1y-deduced-return-type.cpp
+++ b/test/SemaCXX/cxx1y-deduced-return-type.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s -fdelayed-template-parsing -DDELAYED_TEMPLATE_PARSING
auto f(); // expected-note {{previous}}
int f(); // expected-error {{differ only in their return type}}
@@ -112,7 +113,8 @@ namespace Templates {
int e = fwd_decl<int>(); // expected-error {{cannot be used before it is defined}}
template<typename T> auto fwd_decl() { return 0; }
int f = fwd_decl<int>();
- template<typename T> auto fwd_decl();
+ template <typename T>
+ auto fwd_decl(); // expected-note {{candidate template ignored: could not match 'auto ()' against 'int ()'}}
int g = fwd_decl<char>();
auto (*p)() = f1; // expected-error {{incompatible initializer}}
@@ -126,7 +128,8 @@ namespace Templates {
extern template int fwd_decl<char>(); // expected-error {{does not refer to a function template}}
int k2 = fwd_decl<char>();
- template<typename T> auto instantiate() { T::error; } // expected-error {{has no members}}
+ template <typename T> auto instantiate() { T::error; } // expected-error {{has no members}} \
+ // expected-note {{candidate template ignored: could not match 'auto ()' against 'void ()'}}
extern template auto instantiate<int>(); // ok
int k = instantiate<int>(); // expected-note {{in instantiation of}}
template<> auto instantiate<char>() {} // ok
@@ -157,7 +160,7 @@ namespace Templates {
double &mem_check4 = take_fn<double>(Outer<double>::arg_multi);
namespace Deduce1 {
- template<typename T> auto f() { return 0; } // expected-note {{candidate}}
+ template <typename T> auto f() { return 0; } // expected-note {{couldn't infer template argument 'T'}}
template<typename T> void g(T(*)()); // expected-note 2{{candidate}}
void h() {
auto p = f<int>;
@@ -170,7 +173,7 @@ namespace Templates {
}
namespace Deduce2 {
- template<typename T> auto f(int) { return 0; } // expected-note {{candidate}}
+ template <typename T> auto f(int) { return 0; } // expected-note {{couldn't infer template argument 'T'}}
template<typename T> void g(T(*)(int)); // expected-note 2{{candidate}}
void h() {
auto p = f<int>;
@@ -253,7 +256,7 @@ namespace DefaultedMethods {
auto operator=(const A&) = default; // expected-error {{must return 'DefaultedMethods::A &'}}
A &operator=(A&&); // expected-note {{previous}}
};
- auto A::operator=(A&&) = default; // expected-error {{differs from the declaration in the return type}}
+ auto A::operator=(A&&) = default; // expected-error {{return type of out-of-line definition of 'DefaultedMethods::A::operator=' differs from that in the declaration}}
}
namespace Constexpr {
@@ -295,7 +298,12 @@ namespace NoReturn {
auto f() {}
void (*p)() = &f;
+ auto f(); // ok
+
auto *g() {} // expected-error {{cannot deduce return type 'auto *' for function with no return statements}}
+
+ auto h() = delete; // expected-note {{explicitly deleted}}
+ auto x = h(); // expected-error {{call to deleted}}
}
namespace UseBeforeComplete {
@@ -317,7 +325,8 @@ namespace Redecl {
int f(); // expected-error {{functions that differ only in their return type cannot be overloaded}}
decltype(auto) f(); // expected-error {{cannot be overloaded}}
- template<typename T> auto g(T t) { return t; } // expected-note {{candidate}}
+ template <typename T> auto g(T t) { return t; } // expected-note {{candidate}} \
+ // expected-note {{candidate function [with T = int]}}
template auto g(int);
template char g(char); // expected-error {{does not refer to a function}}
template<> auto g(double);
@@ -334,5 +343,136 @@ namespace ExplicitInstantiationDecl {
extern template auto f(int);
int (*p)(int) = f;
}
+namespace MemberTemplatesWithDeduction {
+ struct M {
+ template<class T> auto foo(T t) { return t; }
+ template<class T> auto operator()(T t) const { return t; }
+ template<class T> static __attribute__((unused)) int static_foo(T) {
+ return 5;
+ }
+ template<class T> operator T() { return T{}; }
+ operator auto() { return &static_foo<int>; }
+ };
+ struct N : M {
+ using M::foo;
+ using M::operator();
+ using M::static_foo;
+ using M::operator auto;
+ };
+
+ template <class T> int test() {
+ int i = T{}.foo(3);
+ T m = T{}.foo(M{});
+ int j = T{}(3);
+ M m2 = M{}(M{});
+ int k = T{}.static_foo(4);
+ int l = T::static_foo(5);
+ int l2 = T{};
+ struct X { };
+ X x = T{};
+ return 0;
+ }
+ int Minst = test<M>();
+ int Ninst = test<N>();
+
+}
+}
+
+namespace CurrentInstantiation {
+ // PR16875
+ template<typename T> struct S {
+ auto f() { return T(); }
+ int g() { return f(); }
+ auto h(bool b) {
+ if (b)
+ return T();
+ return h(true);
+ }
+ };
+ int k1 = S<int>().g();
+ int k2 = S<int>().h(false);
+
+ template<typename T> struct U {
+ #ifndef DELAYED_TEMPLATE_PARSING
+ auto f(); // expected-note {{here}}
+ int g() { return f(); } // expected-error {{cannot be used before it is defined}}
+ #else
+ auto f();
+ int g() { return f(); }
+ #endif
+ };
+ #ifndef DELAYED_TEMPLATE_PARSING
+ template int U<int>::g(); // expected-note {{in instantiation of}}
+ #else
+ template int U<int>::g();
+ #endif
+ template<typename T> auto U<T>::f() { return T(); }
+ template int U<short>::g(); // ok
+}
+
+namespace WithDefaultArgs {
+ template<typename U> struct A {
+ template<typename T = U> friend auto f(A) { return []{}; }
+ };
+ template<typename T> void f();
+ using T = decltype(f(A<int>()));
+ using T = decltype(f<int>(A<int>()));
+}
+
+namespace MultilevelDeduction {
+
+auto F() -> auto* { return (int*)0; }
+
+auto (*G())() -> int* { return F; }
+
+auto run = G();
+
+namespace Templated {
+template<class T>
+auto F(T t) -> auto* { return (T*)0; }
+
+template<class T>
+auto (*G(T t))(T) -> T* { return &F<T>; }
+
+
+template<class T>
+auto (*G2(T t))(T) -> auto* { return &F<T>; }
+
+auto run_int = G(1);
+auto run_char = G2('a');
+
+}
+}
+
+namespace rnk {
+extern "C" int puts(const char *s);
+template <typename T>
+auto foo(T x) -> decltype(x) {
+#ifdef DELAYED_TEMPLATE_PARSING
+ ::rnk::bar();
+#endif
+ return x;
+}
+void bar() { puts("bar"); }
+int main() { return foo(0); }
}
+
+namespace OverloadedOperators {
+ template<typename T> struct A {
+ auto operator()() { return T{}; }
+ auto operator[](int) { return T{}; }
+ auto operator+(int) { return T{}; }
+ auto operator+() { return T{}; }
+ friend auto operator-(A) { return T{}; }
+ friend auto operator-(A, A) { return T{}; }
+ };
+ void f(A<int> a) {
+ int b = a();
+ int c = a[0];
+ int d = a + 0;
+ int e = +a;
+ int f = -a;
+ int g = a - a;
+ }
+}
diff --git a/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp b/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp
new file mode 100644
index 0000000..8bd4f42
--- /dev/null
+++ b/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp
@@ -0,0 +1,1363 @@
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -emit-llvm-only %s
+// DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
+// DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS
+// DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING
+
+constexpr int ODRUSE_SZ = sizeof(char);
+
+template<class T, int N>
+void f(T, const int (&)[N]) { }
+
+template<class T>
+void f(const T&, const int (&)[ODRUSE_SZ]) { }
+
+#define DEFINE_SELECTOR(x) \
+ int selector_ ## x[sizeof(x) == ODRUSE_SZ ? ODRUSE_SZ : ODRUSE_SZ + 5]
+
+#define F_CALL(x, a) f(x, selector_ ## a)
+
+// This is a risky assumption, because if an empty class gets captured by value
+// the lambda's size will still be '1'
+#define ASSERT_NO_CAPTURES(L) static_assert(sizeof(L) == 1, "size of closure with no captures must be 1")
+#define ASSERT_CLOSURE_SIZE_EXACT(L, N) static_assert(sizeof(L) == (N), "size of closure must be " #N)
+#define ASSERT_CLOSURE_SIZE(L, N) static_assert(sizeof(L) >= (N), "size of closure must be >=" #N)
+
+
+namespace sample {
+ struct X {
+ int i;
+ X(int i) : i(i) { }
+ };
+}
+
+namespace test_transformations_in_templates {
+template<class T> void foo(T t) {
+ auto L = [](auto a) { return a; };
+}
+template<class T> void foo2(T t) {
+ auto L = [](auto a) -> void {
+ auto M = [](char b) -> void {
+ auto N = [](auto c) -> void {
+ int selector[sizeof(c) == 1 ?
+ (sizeof(b) == 1 ? 1 : 2)
+ : 2
+ ]{};
+ };
+ N('a');
+ };
+ };
+ L(3.14);
+}
+
+void doit() {
+ foo(3);
+ foo('a');
+ foo2('A');
+}
+}
+
+namespace test_return_type_deduction {
+
+void doit() {
+
+ auto L = [](auto a, auto b) {
+ if ( a > b ) return a;
+ return b;
+ };
+ L(2, 4);
+ {
+ auto L2 = [](auto a, int i) {
+ return a + i;
+ };
+ L2(3.14, 2);
+ }
+ {
+ int a; //expected-note{{declared here}}
+ auto B = []() { return ^{ return a; }; }; //expected-error{{cannot be implicitly capture}}\
+ //expected-note{{begins here}}
+ //[](){ return ({int b = 5; return 'c'; 'x';}); };
+
+ //auto X = ^{ return a; };
+
+ //auto Y = []() -> auto { return 3; return 'c'; };
+
+ }
+}
+}
+
+
+namespace test_no_capture{
+void doit() {
+ const int x = 10; //expected-note{{declared here}}
+ {
+ // should not capture 'x' - variable undergoes lvalue-to-rvalue
+ auto L = [=](auto a) {
+ int y = x;
+ return a + y;
+ };
+ ASSERT_NO_CAPTURES(L);
+ }
+ {
+ // should not capture 'x' - even though certain instantiations require
+ auto L = [](auto a) { //expected-note{{begins here}}
+ DEFINE_SELECTOR(a);
+ F_CALL(x, a); //expected-error{{'x' cannot be implicitly captured}}
+ };
+ ASSERT_NO_CAPTURES(L);
+ L('s'); //expected-note{{in instantiation of}}
+ }
+ {
+ // Does not capture because no default capture in inner most lambda 'b'
+ auto L = [=](auto a) {
+ return [=](int p) {
+ return [](auto b) {
+ DEFINE_SELECTOR(a);
+ F_CALL(x, a);
+ return 0;
+ };
+ };
+ };
+ ASSERT_NO_CAPTURES(L);
+ }
+} // doit
+} // namespace
+
+namespace test_capture_of_potentially_evaluated_expression {
+void doit() {
+ const int x = 5;
+ {
+ auto L = [=](auto a) {
+ DEFINE_SELECTOR(a);
+ F_CALL(x, a);
+ };
+ static_assert(sizeof(L) == 4, "Must be captured");
+ }
+ {
+ int j = 0; //expected-note{{declared}}
+ auto L = [](auto a) { //expected-note{{begins here}}
+ return j + 1; //expected-error{{cannot be implicitly captured}}
+ };
+ }
+ {
+ const int x = 10;
+ auto L = [](auto a) {
+ //const int y = 20;
+ return [](int p) {
+ return [](auto b) {
+ DEFINE_SELECTOR(a);
+ F_CALL(x, a);
+ return 0;
+ };
+ };
+ };
+ auto M = L(3);
+ auto N = M(5);
+
+ }
+
+ { // if the nested capture does not implicitly or explicitly allow any captures
+ // nothing should capture - and instantiations will create errors if needed.
+ const int x = 0;
+ auto L = [=](auto a) { // <-- #A
+ const int y = 0;
+ return [](auto b) { // <-- #B
+ int c[sizeof(b)];
+ f(x, c);
+ f(y, c);
+ int i = x;
+ };
+ };
+ ASSERT_NO_CAPTURES(L);
+ auto M_int = L(2);
+ ASSERT_NO_CAPTURES(M_int);
+ }
+ { // Permutations of this example must be thoroughly tested!
+ const int x = 0;
+ sample::X cx{5};
+ auto L = [=](auto a) {
+ const int z = 3;
+ return [&,a](auto b) {
+ const int y = 5;
+ return [=](auto c) {
+ int d[sizeof(a) == sizeof(c) || sizeof(c) == sizeof(b) ? 2 : 1];
+ f(x, d);
+ f(y, d);
+ f(z, d);
+ decltype(a) A = a;
+ decltype(b) B = b;
+ const int &i = cx.i;
+ };
+ };
+ };
+ auto M = L(3)(3.5);
+ M(3.14);
+ }
+}
+namespace Test_no_capture_of_clearly_no_odr_use {
+auto foo() {
+ const int x = 10;
+ auto L = [=](auto a) {
+ return [=](auto b) {
+ return [=](auto c) {
+ int A = x;
+ return A;
+ };
+ };
+ };
+ auto M = L(1);
+ auto N = M(2.14);
+ ASSERT_NO_CAPTURES(L);
+ ASSERT_NO_CAPTURES(N);
+
+ return 0;
+}
+}
+
+namespace Test_capture_of_odr_use_var {
+auto foo() {
+ const int x = 10;
+ auto L = [=](auto a) {
+ return [=](auto b) {
+ return [=](auto c) {
+ int A = x;
+ const int &i = x;
+ decltype(a) A2 = a;
+ return A;
+ };
+ };
+ };
+ auto M_int = L(1);
+ auto N_int_int = M_int(2);
+ ASSERT_CLOSURE_SIZE_EXACT(L, sizeof(x));
+ // M_int captures both a & x
+ ASSERT_CLOSURE_SIZE_EXACT(M_int, sizeof(x) + sizeof(int));
+ // N_int_int captures both a & x
+ ASSERT_CLOSURE_SIZE_EXACT(N_int_int, sizeof(x) + sizeof(int));
+ auto M_double = L(3.14);
+ ASSERT_CLOSURE_SIZE(M_double, sizeof(x) + sizeof(double));
+
+ return 0;
+}
+auto run = foo();
+}
+
+}
+namespace more_nested_captures_1 {
+template<class T> struct Y {
+ static void f(int, double, ...) { }
+ template<class R>
+ static void f(const int&, R, ...) { }
+ template<class R>
+ void foo(R t) {
+ const int x = 10; //expected-note{{declared here}}
+ auto L = [](auto a) {
+ return [=](auto b) {
+ return [=](auto c) {
+ f(x, c, b, a); //expected-error{{reference to local variable 'x'}}
+ return 0;
+ };
+ };
+ };
+ auto M = L(t);
+ auto N = M('b');
+ N(3.14);
+ N(5); //expected-note{{in instantiation of}}
+ }
+};
+Y<int> yi;
+int run = (yi.foo(3.14), 0); //expected-note{{in instantiation of}}
+}
+
+
+namespace more_nested_captures_1_1 {
+template<class T> struct Y {
+ static void f(int, double, ...) { }
+ template<class R>
+ static void f(const int&, R, ...) { }
+ template<class R>
+ void foo(R t) {
+ const int x = 10; //expected-note{{declared here}}
+ auto L = [](auto a) {
+ return [=](char b) {
+ return [=](auto c) {
+ f(x, c, b, a); //expected-error{{reference to local variable 'x'}}
+ return 0;
+ };
+ };
+ };
+ auto M = L(t);
+ auto N = M('b');
+ N(3.14);
+ N(5); //expected-note{{in instantiation of}}
+ }
+};
+Y<int> yi;
+int run = (yi.foo(3.14), 0); //expected-note{{in instantiation of}}
+}
+namespace more_nested_captures_1_2 {
+template<class T> struct Y {
+ static void f(int, double, ...) { }
+ template<class R>
+ static void f(const int&, R, ...) { }
+ template<class R>
+ void foo(R t) {
+ const int x = 10;
+ auto L = [=](auto a) {
+ return [=](char b) {
+ return [=](auto c) {
+ f(x, c, b, a);
+ return 0;
+ };
+ };
+ };
+ auto M = L(t);
+ auto N = M('b');
+ N(3.14);
+ N(5);
+ }
+};
+Y<int> yi;
+int run = (yi.foo(3.14), 0);
+}
+
+namespace more_nested_captures_1_3 {
+template<class T> struct Y {
+ static void f(int, double, ...) { }
+ template<class R>
+ static void f(const int&, R, ...) { }
+ template<class R>
+ void foo(R t) {
+ const int x = 10; //expected-note{{declared here}}
+ auto L = [=](auto a) {
+ return [](auto b) {
+ const int y = 0;
+ return [=](auto c) {
+ f(x, c, b); //expected-error{{reference to local variable 'x'}}
+ f(y, b, c);
+ return 0;
+ };
+ };
+ };
+ auto M = L(t);
+ auto N = M('b');
+ N(3.14);
+ N(5); //expected-note{{in instantiation of}}
+ }
+};
+Y<int> yi;
+int run = (yi.foo(3.14), 0); //expected-note{{in instantiation of}}
+}
+
+
+namespace more_nested_captures_1_4 {
+template<class T> struct Y {
+ static void f(int, double, ...) { }
+ template<class R>
+ static void f(const int&, R, ...) { }
+ template<class R>
+ void foo(R t) {
+ const int x = 10; //expected-note{{declared here}}
+ auto L = [=](auto a) {
+ T t2{t};
+ return [](auto b) {
+ const int y = 0; //expected-note{{declared here}}
+ return [](auto c) { //expected-note 2{{lambda expression begins here}}
+ f(x, c); //expected-error{{variable 'x'}}
+ f(y, c); //expected-error{{variable 'y'}}
+ return 0;
+ };
+ };
+ };
+ auto M = L(t);
+ auto N_char = M('b');
+ N_char(3.14);
+ auto N_double = M(3.14);
+ N_double(3.14);
+ N_char(3); //expected-note{{in instantiation of}}
+ }
+};
+Y<int> yi;
+int run = (yi.foo('a'), 0); //expected-note{{in instantiation of}}
+}
+
+
+namespace more_nested_captures_2 {
+template<class T> struct Y {
+ static void f(int, double) { }
+ template<class R>
+ static void f(const int&, R) { }
+ template<class R>
+ void foo(R t) {
+ const int x = 10;
+ auto L = [=](auto a) {
+ return [=](auto b) {
+ return [=](auto c) {
+ f(x, c);
+ return 0;
+ };
+ };
+ };
+ auto M = L(t);
+ auto N = M('b');
+ N(3);
+ N(3.14);
+ }
+};
+Y<int> yi;
+int run = (yi.foo(3.14), 0);
+
+}
+
+namespace more_nested_captures_3 {
+template<class T> struct Y {
+ static void f(int, double) { }
+ template<class R>
+ static void f(const int&, R) { }
+ template<class R>
+ void foo(R t) {
+ const int x = 10; //expected-note{{declared here}}
+ auto L = [](auto a) {
+ return [=](auto b) {
+ return [=](auto c) {
+ f(x, c); //expected-error{{reference to local variable 'x'}}
+ return 0;
+ };
+ };
+ };
+ auto M = L(t);
+ auto N = M('b');
+ N(3); //expected-note{{in instantiation of}}
+ N(3.14);
+ }
+};
+Y<int> yi;
+int run = (yi.foo(3.14), 0); //expected-note{{in instantiation of}}
+
+}
+
+namespace more_nested_captures_4 {
+template<class T> struct Y {
+ static void f(int, double) { }
+ template<class R>
+ static void f(const int&, R) { }
+ template<class R>
+ void foo(R t) {
+ const int x = 10; //expected-note{{'x' declared here}}
+ auto L = [](auto a) {
+ return [=](char b) {
+ return [=](auto c) {
+ f(x, c); //expected-error{{reference to local variable 'x'}}
+ return 0;
+ };
+ };
+ };
+ auto M = L(t);
+ auto N = M('b');
+ N(3); //expected-note{{in instantiation of}}
+ N(3.14);
+ }
+};
+Y<int> yi;
+int run = (yi.foo(3.14), 0); //expected-note{{in instantiation of}}
+
+}
+
+namespace more_nested_captures_5 {
+template<class T> struct Y {
+ static void f(int, double) { }
+ template<class R>
+ static void f(const int&, R) { }
+ template<class R>
+ void foo(R t) {
+ const int x = 10;
+ auto L = [=](auto a) {
+ return [=](char b) {
+ return [=](auto c) {
+ f(x, c);
+ return 0;
+ };
+ };
+ };
+ auto M = L(t);
+ auto N = M('b');
+ N(3);
+ N(3.14);
+ }
+};
+Y<int> yi;
+int run = (yi.foo(3.14), 0);
+
+}
+
+namespace lambdas_in_NSDMIs {
+template<class T>
+ struct L {
+ T t{};
+ T t2 = ([](auto a) { return [](auto b) { return b; };})(t)(t);
+ T t3 = ([](auto a) { return a; })(t);
+ };
+ L<int> l;
+ int run = l.t2;
+}
+namespace test_nested_decltypes_in_trailing_return_types {
+int foo() {
+ auto L = [](auto a) {
+ return [](auto b, decltype(a) b2) -> decltype(a) {
+ return decltype(a){};
+ };
+ };
+ auto M = L(3.14);
+ M('a', 6.26);
+ return 0;
+}
+}
+
+namespace more_this_capture_1 {
+struct X {
+ void f(int) { }
+ static void f(double) { }
+ void foo() {
+ {
+ auto L = [=](auto a) {
+ f(a);
+ };
+ L(3);
+ L(3.13);
+ }
+ {
+ auto L = [](auto a) {
+ f(a); //expected-error{{this}}
+ };
+ L(3.13);
+ L(2); //expected-note{{in instantiation}}
+ }
+ }
+
+ int g() {
+ auto L = [=](auto a) {
+ return [](int i) {
+ return [=](auto b) {
+ f(b);
+ int x = i;
+ };
+ };
+ };
+ auto M = L(0.0);
+ auto N = M(3);
+ N(5.32); // OK
+ return 0;
+ }
+};
+int run = X{}.g();
+}
+namespace more_this_capture_1_1 {
+struct X {
+ void f(int) { }
+ static void f(double) { }
+
+ int g() {
+ auto L = [=](auto a) {
+ return [](int i) {
+ return [=](auto b) {
+ f(decltype(a){}); //expected-error{{this}}
+ int x = i;
+ };
+ };
+ };
+ auto M = L(0.0);
+ auto N = M(3);
+ N(5.32); // OK
+ L(3); // expected-note{{instantiation}}
+ return 0;
+ }
+};
+int run = X{}.g();
+}
+
+namespace more_this_capture_1_1_1 {
+struct X {
+ void f(int) { }
+ static void f(double) { }
+
+ int g() {
+ auto L = [=](auto a) {
+ return [](auto b) {
+ return [=](int i) {
+ f(b);
+ f(decltype(a){}); //expected-error{{this}}
+ };
+ };
+ };
+ auto M = L(0.0); // OK
+ auto N = M(3.3); //OK
+ auto M_int = L(0); //expected-note{{instantiation}}
+ return 0;
+ }
+};
+int run = X{}.g();
+}
+
+
+namespace more_this_capture_1_1_1_1 {
+struct X {
+ void f(int) { }
+ static void f(double) { }
+
+ int g() {
+ auto L = [=](auto a) {
+ return [](auto b) {
+ return [=](int i) {
+ f(b); //expected-error{{this}}
+ f(decltype(a){});
+ };
+ };
+ };
+ auto M_double = L(0.0); // OK
+ auto N = M_double(3); //expected-note{{instantiation}}
+
+ return 0;
+ }
+};
+int run = X{}.g();
+}
+
+namespace more_this_capture_2 {
+struct X {
+ void f(int) { }
+ static void f(double) { }
+
+ int g() {
+ auto L = [=](auto a) {
+ return [](int i) {
+ return [=](auto b) {
+ f(b); //expected-error{{'this' cannot}}
+ int x = i;
+ };
+ };
+ };
+ auto M = L(0.0);
+ auto N = M(3);
+ N(5); // NOT OK expected-note{{in instantiation of}}
+ return 0;
+ }
+};
+int run = X{}.g();
+}
+namespace diagnose_errors_early_in_generic_lambdas {
+
+int foo()
+{
+
+ { // This variable is used and must be caught early, do not need instantiation
+ const int x = 0; //expected-note{{declared}}
+ auto L = [](auto a) { //expected-note{{begins}}
+ const int &r = x; //expected-error{{variable}}
+ };
+ }
+ { // This variable is not used
+ const int x = 0;
+ auto L = [](auto a) {
+ int i = x;
+ };
+ }
+ {
+
+ const int x = 0; //expected-note{{declared}}
+ auto L = [=](auto a) { // <-- #A
+ const int y = 0;
+ return [](auto b) { //expected-note{{begins}}
+ int c[sizeof(b)];
+ f(x, c);
+ f(y, c);
+ int i = x;
+ // This use will always be an error regardless of instantatiation
+ // so diagnose this early.
+ const int &r = x; //expected-error{{variable}}
+ };
+ };
+
+ }
+ return 0;
+}
+
+int run = foo();
+}
+
+namespace generic_nongenerics_interleaved_1 {
+int foo() {
+ {
+ auto L = [](int a) {
+ int y = 10;
+ return [=](auto b) {
+ return a + y;
+ };
+ };
+ auto M = L(3);
+ M(5);
+ }
+ {
+ int x;
+ auto L = [](int a) {
+ int y = 10;
+ return [=](auto b) {
+ return a + y;
+ };
+ };
+ auto M = L(3);
+ M(5);
+ }
+ {
+ // FIXME: why are there 2 error messages here?
+ int x;
+ auto L = [](auto a) { //expected-note {{declared here}}
+ int y = 10; //expected-note {{declared here}}
+ return [](int b) { //expected-note 2{{expression begins here}}
+ return [=] (auto c) {
+ return a + y; //expected-error 2{{cannot be implicitly captured}}
+ };
+ };
+ };
+ }
+ {
+ int x;
+ auto L = [](auto a) {
+ int y = 10;
+ return [=](int b) {
+ return [=] (auto c) {
+ return a + y;
+ };
+ };
+ };
+ }
+ return 1;
+}
+
+int run = foo();
+}
+namespace dont_capture_refs_if_initialized_with_constant_expressions {
+
+auto foo(int i) {
+ // This is surprisingly not odr-used within the lambda!
+ static int j;
+ j = i;
+ int &ref_j = j;
+ return [](auto a) { return ref_j; }; // ok
+}
+
+template<class T>
+auto foo2(T t) {
+ // This is surprisingly not odr-used within the lambda!
+ static T j;
+ j = t;
+ T &ref_j = j;
+ return [](auto a) { return ref_j; }; // ok
+}
+
+int do_test() {
+ auto L = foo(3);
+ auto L_int = L(3);
+ auto L_char = L('a');
+ auto L1 = foo2(3.14);
+ auto L1_int = L1(3);
+ auto L1_char = L1('a');
+ return 0;
+}
+
+} // dont_capture_refs_if_initialized_with_constant_expressions
+
+namespace test_conversion_to_fptr {
+
+template<class T> struct X {
+
+ T (*fp)(T) = [](auto a) { return a; };
+
+};
+
+X<int> xi;
+
+template<class T>
+void fooT(T t, T (*fp)(T) = [](auto a) { return a; }) {
+ fp(t);
+}
+
+int test() {
+{
+ auto L = [](auto a) { return a; };
+ int (*fp)(int) = L;
+ fp(5);
+ L(3);
+ char (*fc)(char) = L;
+ fc('b');
+ L('c');
+ double (*fd)(double) = L;
+ fd(3.14);
+ fd(6.26);
+ L(4.25);
+}
+{
+ auto L = [](auto a) ->int { return a; }; //expected-note 2{{candidate template ignored}}
+ int (*fp)(int) = L;
+ char (*fc)(char) = L; //expected-error{{no viable conversion}}
+ double (*fd)(double) = L; //expected-error{{no viable conversion}}
+}
+{
+ int x = 5;
+ auto L = [=](auto b, char c = 'x') {
+ int i = x;
+ return [](auto a) ->decltype(a) { return a; };
+ };
+ int (*fp)(int) = L(8);
+ fp(5);
+ L(3);
+ char (*fc)(char) = L('a');
+ fc('b');
+ L('c');
+ double (*fd)(double) = L(3.14);
+ fd(3.14);
+ fd(6.26);
+
+}
+{
+ auto L = [=](auto b) {
+ return [](auto a) ->decltype(b)* { return (decltype(b)*)0; };
+ };
+ int* (*fp)(int) = L(8);
+ fp(5);
+ L(3);
+ char* (*fc)(char) = L('a');
+ fc('b');
+ L('c');
+ double* (*fd)(double) = L(3.14);
+ fd(3.14);
+ fd(6.26);
+}
+{
+ auto L = [=](auto b) {
+ return [](auto a) ->decltype(b)* { return (decltype(b)*)0; }; //expected-note{{candidate template ignored}}
+ };
+ char* (*fp)(int) = L('8');
+ fp(5);
+ char* (*fc)(char) = L('a');
+ fc('b');
+ double* (*fi)(int) = L(3.14);
+ fi(5);
+ int* (*fi2)(int) = L(3.14); //expected-error{{no viable conversion}}
+}
+
+{
+ auto L = [=](auto b) {
+ return [](auto a) {
+ return [=](auto c) {
+ return [](auto d) ->decltype(a + b + c + d) { return d; };
+ };
+ };
+ };
+ int (*fp)(int) = L('8')(3)(short{});
+ double (*fs)(char) = L(3.14)(short{})('4');
+}
+
+ fooT(3);
+ fooT('a');
+ fooT(3.14);
+ fooT("abcdefg");
+ return 0;
+}
+int run2 = test();
+
+}
+
+
+namespace this_capture {
+void f(char, int) { }
+template<class T>
+void f(T, const int&) { }
+
+struct X {
+ int x = 0;
+ void foo() {
+ auto L = [=](auto a) {
+ return [=](auto b) {
+ //f(a, x++);
+ x++;
+ };
+ };
+ L('a')(5);
+ L('b')(4);
+ L(3.14)('3');
+
+ }
+
+};
+
+int run = (X{}.foo(), 0);
+
+namespace this_capture_unresolvable {
+struct X {
+ void f(int) { }
+ static void f(double) { }
+
+ int g() {
+ auto lam = [=](auto a) { f(a); }; // captures 'this'
+ lam(0); // ok.
+ lam(0.0); // ok.
+ return 0;
+ }
+ int g2() {
+ auto lam = [](auto a) { f(a); }; // expected-error{{'this'}}
+ lam(0); // expected-note{{in instantiation of}}
+ lam(0.0); // ok.
+ return 0;
+ }
+ double (*fd)(double) = [](auto a) { f(a); return a; };
+
+};
+
+int run = X{}.g();
+
+}
+
+namespace check_nsdmi_and_this_capture_of_member_functions {
+
+struct FunctorDouble {
+ template<class T> FunctorDouble(T t) { t(2.14); };
+};
+struct FunctorInt {
+ template<class T> FunctorInt(T t) { t(2); }; //expected-note{{in instantiation of}}
+};
+
+template<class T> struct YUnresolvable {
+ void f(int) { }
+ static void f(double) { }
+
+ T t = [](auto a) { f(a); return a; };
+ T t2 = [=](auto b) { f(b); return b; };
+};
+
+template<class T> struct YUnresolvable2 {
+ void f(int) { }
+ static void f(double) { }
+
+ T t = [](auto a) { f(a); return a; }; //expected-error{{'this'}} \
+ //expected-note{{in instantiation of}}
+ T t2 = [=](auto b) { f(b); return b; };
+};
+
+
+YUnresolvable<FunctorDouble> yud;
+// This will cause an error since it call's with an int and calls a member function.
+YUnresolvable2<FunctorInt> yui;
+
+
+template<class T> struct YOnlyStatic {
+ static void f(double) { }
+
+ T t = [](auto a) { f(a); return a; };
+};
+YOnlyStatic<FunctorDouble> yos;
+template<class T> struct YOnlyNonStatic {
+ void f(int) { }
+
+ T t = [](auto a) { f(a); return a; }; //expected-error{{'this'}}
+};
+
+
+}
+
+
+namespace check_nsdmi_and_this_capture_of_data_members {
+
+struct FunctorDouble {
+ template<class T> FunctorDouble(T t) { t(2.14); };
+};
+struct FunctorInt {
+ template<class T> FunctorInt(T t) { t(2); };
+};
+
+template<class T> struct YThisCapture {
+ const int x = 10;
+ static double d;
+ T t = [](auto a) { return x; }; //expected-error{{'this'}}
+ T t2 = [](auto b) { return d; };
+ T t3 = [this](auto a) {
+ return [=](auto b) {
+ return x;
+ };
+ };
+ T t4 = [=](auto a) {
+ return [=](auto b) {
+ return x;
+ };
+ };
+ T t5 = [](auto a) {
+ return [=](auto b) {
+ return x; //expected-error{{'this'}}
+ };
+ };
+};
+
+template<class T> double YThisCapture<T>::d = 3.14;
+
+
+}
+
+
+#ifdef DELAYED_TEMPLATE_PARSING
+template<class T> void foo_no_error(T t) {
+ auto L = []()
+ { return t; };
+}
+template<class T> void foo(T t) { //expected-note 2{{declared here}}
+ auto L = []() //expected-note 2{{begins here}}
+ { return t; }; //expected-error 2{{cannot be implicitly captured}}
+}
+template void foo(int); //expected-note{{in instantiation of}}
+
+#else
+
+template<class T> void foo(T t) { //expected-note{{declared here}}
+ auto L = []() //expected-note{{begins here}}
+ { return t; }; //expected-error{{cannot be implicitly captured}}
+}
+
+#endif
+}
+
+namespace no_this_capture_for_static {
+
+struct X {
+ static void f(double) { }
+
+ int g() {
+ auto lam = [=](auto a) { f(a); };
+ lam(0); // ok.
+ ASSERT_NO_CAPTURES(lam);
+ return 0;
+ }
+};
+
+int run = X{}.g();
+}
+
+namespace this_capture_for_non_static {
+
+struct X {
+ void f(double) { }
+
+ int g() {
+ auto L = [=](auto a) { f(a); };
+ L(0);
+ auto L2 = [](auto a) { f(a); }; //expected-error {{cannot be implicitly captured}}
+ return 0;
+ }
+};
+
+int run = X{}.g();
+}
+
+namespace this_captures_with_num_args_disambiguation {
+
+struct X {
+ void f(int) { }
+ static void f(double, int i) { }
+ int g() {
+ auto lam = [](auto a) { f(a, a); };
+ lam(0);
+ return 0;
+ }
+};
+
+int run = X{}.g();
+}
+namespace enclosing_function_is_template_this_capture {
+// Only error if the instantiation tries to use the member function.
+struct X {
+ void f(int) { }
+ static void f(double) { }
+ template<class T>
+ int g(T t) {
+ auto L = [](auto a) { f(a); }; //expected-error{{'this'}}
+ L(t); // expected-note{{in instantiation of}}
+ return 0;
+ }
+};
+
+int run = X{}.g(0.0); // OK.
+int run2 = X{}.g(0); // expected-note{{in instantiation of}}
+
+
+}
+
+namespace enclosing_function_is_template_this_capture_2 {
+// This should error, even if not instantiated, since
+// this would need to be captured.
+struct X {
+ void f(int) { }
+ template<class T>
+ int g(T t) {
+ auto L = [](auto a) { f(a); }; //expected-error{{'this'}}
+ L(t);
+ return 0;
+ }
+};
+
+}
+
+
+namespace enclosing_function_is_template_this_capture_3 {
+// This should not error, this does not need to be captured.
+struct X {
+ static void f(int) { }
+ template<class T>
+ int g(T t) {
+ auto L = [](auto a) { f(a); };
+ L(t);
+ return 0;
+ }
+};
+
+int run = X{}.g(0.0); // OK.
+int run2 = X{}.g(0); // OK.
+
+}
+
+namespace nested_this_capture_1 {
+struct X {
+ void f(int) { }
+ static void f(double) { }
+
+ int g() {
+ auto L = [=](auto a) {
+ return [this]() {
+ return [=](auto b) {
+ f(b);
+ };
+ };
+ };
+ auto M = L(0);
+ auto N = M();
+ N(5);
+ return 0;
+ }
+};
+
+int run = X{}.g();
+
+}
+
+
+namespace nested_this_capture_2 {
+struct X {
+ void f(int) { }
+ static void f(double) { }
+
+ int g() {
+ auto L = [=](auto a) {
+ return [&]() {
+ return [=](auto b) {
+ f(b);
+ };
+ };
+ };
+ auto M = L(0);
+ auto N = M();
+ N(5);
+ N(3.14);
+ return 0;
+ }
+};
+
+int run = X{}.g();
+
+}
+
+namespace nested_this_capture_3_1 {
+struct X {
+ template<class T>
+ void f(int, T t) { }
+ template<class T>
+ static void f(double, T t) { }
+
+ int g() {
+ auto L = [=](auto a) {
+ return [&](auto c) {
+ return [=](auto b) {
+ f(b, c);
+ };
+ };
+ };
+ auto M = L(0);
+ auto N = M('a');
+ N(5);
+ N(3.14);
+ return 0;
+ }
+};
+
+int run = X{}.g();
+
+}
+
+
+namespace nested_this_capture_3_2 {
+struct X {
+ void f(int) { }
+ static void f(double) { }
+
+ int g() {
+ auto L = [=](auto a) {
+ return [](int i) {
+ return [=](auto b) {
+ f(b); //expected-error {{'this' cannot}}
+ int x = i;
+ };
+ };
+ };
+ auto M = L(0.0);
+ auto N = M(3);
+ N(5); //expected-note {{in instantiation of}}
+ N(3.14); // OK.
+ return 0;
+ }
+};
+
+int run = X{}.g();
+
+}
+
+namespace nested_this_capture_4 {
+struct X {
+ void f(int) { }
+ static void f(double) { }
+
+ int g() {
+ auto L = [](auto a) {
+ return [=](auto i) {
+ return [=](auto b) {
+ f(b); //expected-error {{'this' cannot}}
+ int x = i;
+ };
+ };
+ };
+ auto M = L(0.0);
+ auto N = M(3);
+ N(5); //expected-note {{in instantiation of}}
+ N(3.14); // OK.
+ return 0;
+ }
+};
+
+int run = X{}.g();
+
+}
+namespace capture_enclosing_function_parameters {
+
+
+inline auto foo(int x) {
+ int i = 10;
+ auto lambda = [=](auto z) { return x + z; };
+ return lambda;
+}
+
+int foo2() {
+ auto L = foo(3);
+ L(4);
+ L('a');
+ L(3.14);
+ return 0;
+}
+
+inline auto foo3(int x) {
+ int local = 1;
+ auto L = [=](auto a) {
+ int i = a[local];
+ return [=](auto b) mutable {
+ auto n = b;
+ return [&, n](auto c) mutable {
+ ++local;
+ return ++x;
+ };
+ };
+ };
+ auto M = L("foo-abc");
+ auto N = M("foo-def");
+ auto O = N("foo-ghi");
+
+ return L;
+}
+
+int main() {
+ auto L3 = foo3(3);
+ auto M3 = L3("L3-1");
+ auto N3 = M3("M3-1");
+ auto O3 = N3("N3-1");
+ N3("N3-2");
+ M3("M3-2");
+ M3("M3-3");
+ L3("L3-2");
+}
+} // end ns
+
+namespace capture_arrays {
+
+inline int sum_array(int n) {
+ int array2[5] = { 1, 2, 3, 4, 5};
+
+ auto L = [=](auto N) -> int {
+ int sum = 0;
+ int array[5] = { 1, 2, 3, 4, 5 };
+ sum += array2[sum];
+ sum += array2[N];
+ return 0;
+ };
+ L(2);
+ return L(n);
+}
+}
+
+namespace capture_non_odr_used_variable_because_named_in_instantiation_dependent_expressions {
+
+// even though 'x' is not odr-used, it should be captured.
+
+int test() {
+ const int x = 10;
+ auto L = [=](auto a) {
+ (void) +x + a;
+ };
+ ASSERT_CLOSURE_SIZE_EXACT(L, sizeof(x));
+}
+
+} //end ns
+#ifdef MS_EXTENSIONS
+namespace explicit_spec {
+template<class R> struct X {
+ template<class T> int foo(T t) {
+ auto L = [](auto a) { return a; };
+ L(&t);
+ return 0;
+ }
+
+ template<> int foo<char>(char c) { //expected-warning{{explicit specialization}}
+ const int x = 10;
+ auto LC = [](auto a) { return a; };
+ R r;
+ LC(&r);
+ auto L = [=](auto a) {
+ return [=](auto b) {
+ int d[sizeof(a)];
+ f(x, d);
+ };
+ };
+ auto M = L(1);
+
+ ASSERT_NO_CAPTURES(M);
+ return 0;
+ }
+
+};
+
+int run_char = X<int>{}.foo('a');
+int run_int = X<double>{}.foo(4);
+}
+
+#endif // MS_EXTENSIONS
+
diff --git a/test/SemaCXX/cxx1y-generic-lambdas.cpp b/test/SemaCXX/cxx1y-generic-lambdas.cpp
new file mode 100644
index 0000000..20e06f4
--- /dev/null
+++ b/test/SemaCXX/cxx1y-generic-lambdas.cpp
@@ -0,0 +1,908 @@
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -emit-llvm-only %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_call {
+int test() {
+ auto L = [](auto a) { return a; };
+ L.operator()(3);
+ L.operator()<char>(3.14); //expected-warning{{implicit conversion}}
+ return 0;
+}
+} //end ns
+
+namespace test_conversion_to_fptr_2 {
+
+template<class T> struct X {
+
+ T (*fp)(T) = [](auto a) { return a; };
+
+};
+
+X<int> xi;
+
+template<class T>
+void fooT(T t, T (*fp)(T) = [](auto a) { return a; }) {
+ fp(t);
+}
+
+int test() {
+{
+ auto L = [](auto a) { return a; };
+ int (*fp)(int) = L;
+ fp(5);
+ L(3);
+ char (*fc)(char) = L;
+ fc('b');
+ L('c');
+ double (*fd)(double) = L;
+ fd(3.14);
+ fd(6.26);
+ L(4.25);
+}
+{
+ auto L = [](auto a) ->int { return a; }; //expected-note 2{{candidate template ignored}}
+ int (*fp)(int) = L;
+ char (*fc)(char) = L; //expected-error{{no viable conversion}}
+ double (*fd)(double) = L; //expected-error{{no viable conversion}}
+}
+{
+ int x = 5;
+ auto L = [=](auto b, char c = 'x') {
+ int i = x;
+ return [](auto a) ->decltype(a) { return a; };
+ };
+ int (*fp)(int) = L(8);
+ fp(5);
+ L(3);
+ char (*fc)(char) = L('a');
+ fc('b');
+ L('c');
+ double (*fd)(double) = L(3.14);
+ fd(3.14);
+ fd(6.26);
+
+}
+{
+ auto L = [=](auto b) {
+ return [](auto a) ->decltype(b)* { return (decltype(b)*)0; };
+ };
+ int* (*fp)(int) = L(8);
+ fp(5);
+ L(3);
+ char* (*fc)(char) = L('a');
+ fc('b');
+ L('c');
+ double* (*fd)(double) = L(3.14);
+ fd(3.14);
+ fd(6.26);
+}
+{
+ auto L = [=](auto b) {
+ return [](auto a) ->decltype(b)* { return (decltype(b)*)0; }; //expected-note{{candidate template ignored}}
+ };
+ char* (*fp)(int) = L('8');
+ fp(5);
+ char* (*fc)(char) = L('a');
+ fc('b');
+ double* (*fi)(int) = L(3.14);
+ fi(5);
+ int* (*fi2)(int) = L(3.14); //expected-error{{no viable conversion}}
+}
+
+{
+ auto L = [=](auto b) {
+ return [](auto a) {
+ return [=](auto c) {
+ return [](auto d) ->decltype(a + b + c + d) { return d; };
+ };
+ };
+ };
+ int (*fp)(int) = L('8')(3)(short{});
+ double (*fs)(char) = L(3.14)(short{})('4');
+}
+
+ fooT(3);
+ fooT('a');
+ fooT(3.14);
+ fooT("abcdefg");
+ return 0;
+}
+int run2 = test();
+
+}
+
+
+namespace test_conversion_to_fptr {
+
+void f1(int (*)(int)) { }
+void f2(char (*)(int)) { } // expected-note{{candidate}}
+void g(int (*)(int)) { } // #1 expected-note{{candidate}}
+void g(char (*)(char)) { } // #2 expected-note{{candidate}}
+void h(int (*)(int)) { } // #3
+void h(char (*)(int)) { } // #4
+
+int test() {
+{
+ auto glambda = [](auto a) { return a; };
+ glambda(1);
+ f1(glambda); // OK
+ f2(glambda); // expected-error{{no matching function}}
+ g(glambda); // expected-error{{call to 'g' is ambiguous}}
+ h(glambda); // OK: calls #3 since it is convertible from ID
+
+ int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK
+
+}
+{
+
+ auto L = [](auto a) { return a; };
+ int (*fp)(int) = L;
+ fp(5);
+ L(3);
+ char (*fc)(char) = L;
+ fc('b');
+ L('c');
+ double (*fd)(double) = L;
+ fd(3.14);
+ fd(6.26);
+ L(4.25);
+}
+{
+ auto L = [](auto a) ->int { return a; }; //expected-note 2{{candidate template ignored}}
+ int (*fp)(int) = L;
+ char (*fc)(char) = L; //expected-error{{no viable conversion}}
+ double (*fd)(double) = L; //expected-error{{no viable conversion}}
+}
+{
+ int* (*fp)(int*) = [](auto *a) -> auto* { return a; };
+ fp(0);
+}
+}
+
+namespace more_converion_to_ptr_to_function_tests {
+
+
+int test() {
+ {
+ int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK
+ int (*fp2)(int) = [](auto b) -> int { return b; };
+ int (*fp3)(char) = [](auto c) -> int { return c; };
+ char (*fp4)(int) = [](auto d) { return d; }; //expected-error{{no viable conversion}}\
+ //expected-note{{candidate template ignored}}
+ char (*fp5)(char) = [](auto e) -> int { return e; }; //expected-error{{no viable conversion}}\
+ //expected-note{{candidate template ignored}}
+
+ fp2(3);
+ fp3('\n');
+ fp3('a');
+ return 0;
+ }
+} // end test()
+
+template<class ... Ts> void vfun(Ts ... ) { }
+
+int variadic_test() {
+
+ int (*fp)(int, char, double) = [](auto ... a) -> int { vfun(a...); return 4; };
+ fp(3, '4', 3.14);
+
+ int (*fp2)(int, char, double) = [](auto ... a) { vfun(a...); return 4; };
+ fp(3, '4', 3.14);
+ return 2;
+}
+
+} // end ns
+
+namespace conversion_operator {
+void test() {
+ auto L = [](auto a) -> int { return a; };
+ int (*fp)(int) = L;
+ int (&fp2)(int) = [](auto a) { return a; }; // expected-error{{non-const lvalue}}
+ int (&&fp3)(int) = [](auto a) { return a; }; // expected-error{{no viable conversion}}\
+ //expected-note{{candidate}}
+ }
+}
+}
+
+namespace return_type_deduction_ok {
+ auto l = [](auto a) ->auto { return a; }(2);
+ auto l2 = [](auto a) ->decltype(auto) { return a; }(2);
+ auto l3 = [](auto a) { return a; }(2);
+
+}
+
+namespace generic_lambda_as_default_argument_ok {
+ void test(int i = [](auto a)->int { return a; }(3)) {
+ }
+}
+
+namespace nested_non_capturing_lambda_tests {
+template<class ... Ts> void print(Ts ...) { }
+int test() {
+{
+ auto L = [](auto a) {
+ return [](auto b) {
+ return b;
+ };
+ };
+ auto M = L(3);
+ M(4.15);
+ }
+{
+ int i = 10; //expected-note 3{{declared here}}
+ auto L = [](auto a) {
+ return [](auto b) { //expected-note 3{{begins here}}
+ i = b; //expected-error 3{{cannot be implicitly captured}}
+ return b;
+ };
+ };
+ auto M = L(3); //expected-note{{instantiation}}
+ M(4.15); //expected-note{{instantiation}}
+ }
+ {
+ int i = 10;
+ auto L = [](auto a) {
+ return [](auto b) {
+ b = sizeof(i); //ok
+ return b;
+ };
+ };
+ }
+ {
+ auto L = [](auto a) {
+ print("a = ", a, "\n");
+ return [](auto b) ->decltype(a) {
+ print("b = ", b, "\n");
+ return b;
+ };
+ };
+ auto M = L(3);
+ M(4.15);
+ }
+
+{
+ auto L = [](auto a) ->decltype(a) {
+ print("a = ", a, "\n");
+ return [](auto b) ->decltype(a) { //expected-error{{no viable conversion}}\
+ //expected-note{{candidate template ignored}}
+ print("b = ", b, "\n");
+ return b;
+ };
+ };
+ auto M = L(3); //expected-note{{in instantiation of}}
+ }
+{
+ auto L = [](auto a) {
+ print("a = ", a, "\n");
+ return [](auto ... b) ->decltype(a) {
+ print("b = ", b ..., "\n");
+ return 4;
+ };
+ };
+ auto M = L(3);
+ M(4.15, 3, "fv");
+}
+
+{
+ auto L = [](auto a) {
+ print("a = ", a, "\n");
+ return [](auto ... b) ->decltype(a) {
+ print("b = ", b ..., "\n");
+ return 4;
+ };
+ };
+ auto M = L(3);
+ int (*fp)(double, int, const char*) = M;
+ fp(4.15, 3, "fv");
+}
+
+{
+ auto L = [](auto a) {
+ print("a = ", a, "\n");
+ return [](char b) {
+ return [](auto ... c) ->decltype(b) {
+ print("c = ", c ..., "\n");
+ return 42;
+ };
+ };
+ };
+ L(4);
+ auto M = L(3);
+ M('a');
+ auto N = M('x');
+ N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
+ char (*np)(const char*, int, const char*, double, const char*, int) = N;
+ np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
+}
+
+
+{
+ auto L = [](auto a) {
+ print("a = ", a, "\n");
+ return [](decltype(a) b) {
+ return [](auto ... c) ->decltype(b) {
+ print("c = ", c ..., "\n");
+ return 42;
+ };
+ };
+ };
+ L('4');
+ auto M = L('3');
+ M('a');
+ auto N = M('x');
+ N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
+ char (*np)(const char*, int, const char*, double, const char*, int) = N;
+ np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
+}
+
+
+{
+ struct X {
+ static void foo(double d) { }
+ void test() {
+ auto L = [](auto a) {
+ print("a = ", a, "\n");
+ foo(a);
+ return [](decltype(a) b) {
+ foo(b);
+ foo(sizeof(a) + sizeof(b));
+ return [](auto ... c) ->decltype(b) {
+ print("c = ", c ..., "\n");
+ foo(decltype(b){});
+ foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
+ return 42;
+ };
+ };
+ };
+ L('4');
+ auto M = L('3');
+ M('a');
+ auto N = M('x');
+ N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
+ char (*np)(const char*, int, const char*, double, const char*, int) = N;
+ np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
+ }
+};
+X x;
+x.test();
+}
+// Make sure we can escape the function
+{
+ struct X {
+ static void foo(double d) { }
+ auto test() {
+ auto L = [](auto a) {
+ print("a = ", a, "\n");
+ foo(a);
+ return [](decltype(a) b) {
+ foo(b);
+ foo(sizeof(a) + sizeof(b));
+ return [](auto ... c) ->decltype(b) {
+ print("c = ", c ..., "\n");
+ foo(decltype(b){});
+ foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
+ return 42;
+ };
+ };
+ };
+ return L;
+ }
+};
+ X x;
+ auto L = x.test();
+ L('4');
+ auto M = L('3');
+ M('a');
+ auto N = M('x');
+ N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
+ char (*np)(const char*, int, const char*, double, const char*, int) = N;
+ np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
+}
+
+{
+ struct X {
+ static void foo(double d) { }
+ auto test() {
+ auto L = [](auto a) {
+ print("a = ", a, "\n");
+ foo(a);
+ return [](decltype(a) b) {
+ foo(b);
+ foo(sizeof(a) + sizeof(b));
+ return [](auto ... c) {
+ print("c = ", c ..., "\n");
+ foo(decltype(b){});
+ foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
+ return [](decltype(c) ... d) ->decltype(a) { //expected-note{{candidate}}
+ print("d = ", d ..., "\n");
+ foo(decltype(b){});
+ foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
+ return decltype(a){};
+ };
+ };
+ };
+ };
+ return L;
+ }
+};
+ X x;
+ auto L = x.test();
+ L('4');
+ auto M = L('3');
+ M('a');
+ auto N = M('x');
+ auto O = N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
+ char (*np)(const char*, int, const char*, double, const char*, int) = O;
+ np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
+ int (*np2)(const char*, int, const char*, double, const char*, int) = O; // expected-error{{no viable conversion}}
+
+}
+} // end test()
+
+namespace wrapped_within_templates {
+
+namespace explicit_return {
+template<class T> int fooT(T t) {
+ auto L = [](auto a) -> void {
+ auto M = [](char b) -> void {
+ auto N = [](auto c) -> void {
+ int x = 0;
+ x = sizeof(a);
+ x = sizeof(b);
+ x = sizeof(c);
+ };
+ N('a');
+ N(decltype(a){});
+ };
+ };
+ L(t);
+ L(3.14);
+ return 0;
+}
+
+int run = fooT('a') + fooT(3.14);
+
+} // end explicit_return
+
+namespace implicit_return_deduction {
+template<class T> auto fooT(T t) {
+ auto L = [](auto a) {
+ auto M = [](char b) {
+ auto N = [](auto c) {
+ int x = 0;
+ x = sizeof(a);
+ x = sizeof(b);
+ x = sizeof(c);
+ };
+ N('a');
+ N(decltype(a){});
+ };
+ };
+ L(t);
+ L(3.14);
+ return 0;
+}
+
+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) {
+ auto N = [](auto c) {
+ int x = 0;
+ x = sizeof...(a);
+ x = sizeof...(b);
+ x = sizeof(c);
+ };
+ N('a');
+ N(N);
+ N(first<Ts...>{});
+ };
+ M(a...);
+ print("a = ", a..., "\n");
+ };
+ L(L, ts...);
+ print("ts = ", ts..., "\n");
+ return 0;
+}
+
+int run2 = fooV(3.14, " ", '4', 5) + fooV("BC", 3, 2.77, 'A', float{}, short{}, unsigned{});
+
+} //implicit_return_deduction
+
+
+} //wrapped_within_templates
+
+namespace at_ns_scope {
+ void foo(double d) { }
+ auto test() {
+ auto L = [](auto a) {
+ print("a = ", a, "\n");
+ foo(a);
+ return [](decltype(a) b) {
+ foo(b);
+ foo(sizeof(a) + sizeof(b));
+ return [](auto ... c) {
+ print("c = ", c ..., "\n");
+ foo(decltype(b){});
+ foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
+ return [](decltype(c) ... d) ->decltype(a) { //expected-note{{candidate}}
+ print("d = ", d ..., "\n");
+ foo(decltype(b){});
+ foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
+ return decltype(a){};
+ };
+ };
+ };
+ };
+ return L;
+ }
+auto L = test();
+auto L_test = L('4');
+auto M = L('3');
+auto M_test = M('a');
+auto N = M('x');
+auto O = N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
+char (*np)(const char*, int, const char*, double, const char*, int) = O;
+auto NP_result = np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
+int (*np2)(const char*, int, const char*, double, const char*, int) = O; // expected-error{{no viable conversion}}
+
+
+
+}
+
+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) {
+ auto L = [](auto ... a) -> void {
+ auto M = [](decltype(a) ... b) -> void {
+ auto N = [](auto c) -> void {
+ int x = 0;
+ x = sizeof...(a);
+ x = sizeof...(b);
+ x = sizeof(c);
+ };
+ N('a');
+ N(N);
+ N(FirstType<Ts...>{});
+ };
+ M(a...);
+ print("a = ", a..., "\n");
+ };
+ L(L, ts...);
+ print("ts = ", ts..., "\n");
+ return 0;
+}
+
+int run2 = fooV(3.14, " ", '4', 5) + fooV("BC", 3, 2.77, 'A', float{}, short{}, unsigned{});
+
+namespace more_variadic_1 {
+
+template<class ... Ts> int fooV(Ts ... ts) {
+ auto L = [](auto ... a) {
+ auto M = [](decltype(a) ... b) -> void {
+ auto N = [](auto c) -> void {
+ int x = 0;
+ x = sizeof...(a);
+ x = sizeof...(b);
+ x = sizeof(c);
+ };
+ N('a');
+ N(N);
+ N(FirstType<Ts...>{});
+ };
+ M(a...);
+ return M;
+ };
+ auto M = L(L, ts...);
+ decltype(L(L, ts...)) (*fp)(decltype(L), decltype(ts) ...) = L;
+ void (*fp2)(decltype(L), decltype(ts) ...) = L(L, ts...);
+
+ {
+ auto L = [](auto ... a) {
+ auto M = [](decltype(a) ... b) {
+ auto N = [](auto c) -> void {
+ int x = 0;
+ x = sizeof...(a);
+ x = sizeof...(b);
+ x = sizeof(c);
+ };
+ N('a');
+ N(N);
+ N(FirstType<Ts...>{});
+ return N;
+ };
+ M(a...);
+ return M;
+ };
+ auto M = L(L, ts...);
+ decltype(L(L, ts...)) (*fp)(decltype(L), decltype(ts) ...) = L;
+ fp(L, ts...);
+ decltype(L(L, ts...)(L, ts...)) (*fp2)(decltype(L), decltype(ts) ...) = L(L, ts...);
+ fp2 = fp(L, ts...);
+ void (*fp3)(char) = fp2(L, ts...);
+ fp3('a');
+ }
+ return 0;
+}
+
+int run2 = fooV(3.14, " ", '4', 5) + fooV("BC", 3, 2.77, 'A', float{}, short{}, unsigned{});
+
+
+} //end ns more_variadic_1
+
+} // end ns variadic_tests_1
+
+namespace at_ns_scope_within_class_member {
+ struct X {
+ static void foo(double d) { }
+ auto test() {
+ auto L = [](auto a) {
+ print("a = ", a, "\n");
+ foo(a);
+ return [](decltype(a) b) {
+ foo(b);
+ foo(sizeof(a) + sizeof(b));
+ return [](auto ... c) {
+ print("c = ", c ..., "\n");
+ foo(decltype(b){});
+ foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
+ return [](decltype(c) ... d) ->decltype(a) { //expected-note{{candidate}}
+ print("d = ", d ..., "\n");
+ foo(decltype(b){});
+ foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
+ return decltype(a){};
+ };
+ };
+ };
+ };
+ return L;
+ }
+};
+X x;
+auto L = x.test();
+auto L_test = L('4');
+auto M = L('3');
+auto M_test = M('a');
+auto N = M('x');
+auto O = N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
+char (*np)(const char*, int, const char*, double, const char*, int) = O;
+auto NP_result = np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
+int (*np2)(const char*, int, const char*, double, const char*, int) = O; // expected-error{{no viable conversion}}
+
+} //end at_ns_scope_within_class_member
+
+
+namespace at_ns_scope_within_class_template_member {
+ struct X {
+ static void foo(double d) { }
+ template<class T = int>
+ auto test(T = T{}) {
+ auto L = [](auto a) {
+ print("a = ", a, "\n");
+ foo(a);
+ return [](decltype(a) b) {
+ foo(b);
+ foo(sizeof(a) + sizeof(b));
+ return [](auto ... c) {
+ print("c = ", c ..., "\n");
+ foo(decltype(b){});
+ foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
+ return [](decltype(c) ... d) ->decltype(a) { //expected-note{{candidate}}
+ print("d = ", d ..., "\n");
+ foo(decltype(b){});
+ foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
+ return decltype(a){};
+ };
+ };
+ };
+ };
+ return L;
+ }
+
+};
+X x;
+auto L = x.test();
+auto L_test = L('4');
+auto M = L('3');
+auto M_test = M('a');
+auto N = M('x');
+auto O = N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
+char (*np)(const char*, int, const char*, double, const char*, int) = O;
+auto NP_result = np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
+int (*np2)(const char*, int, const char*, double, const char*, int) = O; // expected-error{{no viable conversion}}
+
+} //end at_ns_scope_within_class_member
+
+
+namespace nested_generic_lambdas_123 {
+void test() {
+ auto L = [](auto a) -> int {
+ auto M = [](auto b, decltype(a) b2) -> int {
+ return 1;
+ };
+ M(a, a);
+ };
+ L(3);
+}
+template<class T> void foo(T) {
+ auto L = [](auto a) { return a; };
+}
+template void foo(int);
+} // end ns nested_generic_lambdas_123
+
+namespace nested_fptr_235 {
+int test()
+{
+ auto L = [](auto b) {
+ return [](auto a) ->decltype(a) { return a; };
+ };
+ int (*fp)(int) = L(8);
+ fp(5);
+ L(3);
+ char (*fc)(char) = L('a');
+ fc('b');
+ L('c');
+ double (*fd)(double) = L(3.14);
+ fd(3.14);
+ fd(6.26);
+ return 0;
+}
+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...);
+ return FirstArg(ts...);
+}
+int test()
+{
+ {
+ auto L = [](auto ... As) {
+ return [](auto b) ->decltype(b) {
+ vfun([](decltype(As) a) -> decltype(a) { return a; } ...)(FirstType<decltype(As)...>{});
+ return decltype(b){};
+ };
+ };
+ auto LL = L(1, 'a', 3.14, "abc");
+ LL("dim");
+ }
+ return 0;
+}
+int run = test();
+}
+
+} // end ns nested_non_capturing_lambda_tests
+
+namespace PR17476 {
+struct string {
+ string(const char *__s) { }
+ string &operator+=(const string &__str) { return *this; }
+};
+
+template <class T>
+void finalizeDefaultAtomValues() {
+ auto startEnd = [](const char * sym) -> void {
+ string start("__");
+ start += sym;
+ };
+ startEnd("preinit_array");
+}
+
+void f() { finalizeDefaultAtomValues<char>(); }
+
+}
+
+namespace PR17476_variant {
+struct string {
+ string(const char *__s) { }
+ string &operator+=(const string &__str) { return *this; }
+};
+
+template <class T>
+void finalizeDefaultAtomValues() {
+ auto startEnd = [](const T *sym) -> void {
+ string start("__");
+ start += sym;
+ };
+ startEnd("preinit_array");
+}
+
+void f() { finalizeDefaultAtomValues<char>(); }
+
+}
+
+namespace PR17877_lambda_declcontext_and_get_cur_lambda_disconnect {
+
+
+template<class T> struct U {
+ int t = 0;
+};
+
+template<class T>
+struct V {
+ U<T> size() const { return U<T>{}; }
+};
+
+template<typename T>
+void Do() {
+ V<int> v{};
+ [=] { v.size(); };
+}
+
+}
+
+namespace inclass_lambdas_within_nested_classes {
+namespace ns1 {
+
+struct X1 {
+ struct X2 {
+ enum { E = [](auto i) { return i; }(3) }; //expected-error{{inside of a constant expression}}\
+ //expected-error{{not an integral constant}}
+ int L = ([] (int i) { return i; })(2);
+ void foo(int i = ([] (int i) { return i; })(2)) { }
+ int B : ([](int i) { return i; })(3); //expected-error{{inside of a constant expression}}\
+ //expected-error{{not an integral constant}}
+ int arr[([](int i) { return i; })(3)]; //expected-error{{inside of a constant expression}}\
+ //expected-error{{must have a constant size}}
+ int (*fp)(int) = [](int i) { return i; };
+ void fooptr(int (*fp)(char) = [](char c) { return 0; }) { }
+ int L2 = ([](auto i) { return i; })(2);
+ void fooG(int i = ([] (auto i) { return i; })(2)) { }
+ int BG : ([](auto i) { return i; })(3); //expected-error{{inside of a constant expression}} \
+ //expected-error{{not an integral constant}}
+ int arrG[([](auto i) { return i; })(3)]; //expected-error{{inside of a constant expression}}\
+ //expected-error{{must have a constant size}}
+ int (*fpG)(int) = [](auto i) { return i; };
+ void fooptrG(int (*fp)(char) = [](auto c) { return 0; }) { }
+ };
+};
+} //end ns
+
+namespace ns2 {
+struct X1 {
+ template<class T>
+ struct X2 {
+ int L = ([] (T i) { return i; })(2);
+ void foo(int i = ([] (int i) { return i; })(2)) { }
+ int B : ([](T i) { return i; })(3); //expected-error{{inside of a constant expression}}\
+ //expected-error{{not an integral constant}}
+ int arr[([](T i) { return i; })(3)]; //expected-error{{inside of a constant expression}}\
+ //expected-error{{must have a constant size}}
+ int (*fp)(T) = [](T i) { return i; };
+ void fooptr(T (*fp)(char) = [](char c) { return 0; }) { }
+ int L2 = ([](auto i) { return i; })(2);
+ void fooG(T i = ([] (auto i) { return i; })(2)) { }
+ int BG : ([](auto i) { return i; })(3); //expected-error{{not an integral constant}}
+ int arrG[([](auto i) { return i; })(3)]; //expected-error{{must have a constant size}}
+ int (*fpG)(T) = [](auto i) { return i; };
+ void fooptrG(T (*fp)(char) = [](auto c) { return 0; }) { }
+ template<class U = char> int fooG2(T (*fp)(U) = [](auto a) { return 0; }) { return 0; }
+ template<class U = char> int fooG3(T (*fp)(U) = [](auto a) { return 0; });
+ };
+};
+template<class T>
+template<class U>
+int X1::X2<T>::fooG3(T (*fp)(U)) { return 0; }
+X1::X2<int> x2; //expected-note 3{{in instantiation of}}
+int run1 = x2.fooG2();
+int run2 = x2.fooG3();
+} // end ns
+
+
+
+} //end ns inclass_lambdas_within_nested_classes \ No newline at end of file
diff --git a/test/SemaCXX/cxx1y-init-captures.cpp b/test/SemaCXX/cxx1y-init-captures.cpp
new file mode 100644
index 0000000..2cb4d31
--- /dev/null
+++ b/test/SemaCXX/cxx1y-init-captures.cpp
@@ -0,0 +1,169 @@
+// RUN: %clang_cc1 -std=c++1y %s -verify -emit-llvm-only
+
+namespace variadic_expansion {
+ int f(int &, char &) { return 0; }
+ template<class ... Ts> char fv(Ts ... ts) { return 0; }
+ // FIXME: why do we get 2 error messages
+ template <typename ... T> void g(T &... t) { //expected-note3{{declared here}}
+ f([&a(t)]()->decltype(auto) {
+ return a;
+ }() ...);
+
+ auto L = [x = f([&a(t)]()->decltype(auto) { return a; }()...)]() { return x; };
+ const int y = 10;
+ auto M = [x = y,
+ &z = y](T& ... t) { };
+ auto N = [x = y,
+ &z = y, n = f(t...),
+ o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...), t...](T& ... s) {
+ fv([&a(t)]()->decltype(auto) {
+ return a;
+ }() ...);
+ };
+ auto N2 = [x = y, //expected-note3{{begins here}}
+ &z = y, n = f(t...),
+ o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...)](T& ... s) {
+ fv([&a(t)]()->decltype(auto) { //expected-error 3{{captured}}
+ return a;
+ }() ...);
+ };
+
+ }
+
+ void h(int i, char c) { g(i, c); } //expected-note{{in instantiation}}
+}
+
+namespace odr_use_within_init_capture {
+
+int test() {
+
+ { // no captures
+ const int x = 10;
+ auto L = [z = x + 2](int a) {
+ auto M = [y = x - 2](char b) {
+ return y;
+ };
+ return M;
+ };
+
+ }
+ { // should not capture
+ const int x = 10;
+ auto L = [&z = x](int a) {
+ return a;;
+ };
+
+ }
+ {
+ const int x = 10;
+ auto L = [k = x](char a) { //expected-note {{declared}}
+ return [](int b) { //expected-note {{begins}}
+ return [j = k](int c) { //expected-error {{cannot be implicitly captured}}
+ return c;
+ };
+ };
+ };
+ }
+ {
+ const int x = 10;
+ auto L = [k = x](char a) {
+ return [=](int b) {
+ return [j = k](int c) {
+ return c;
+ };
+ };
+ };
+ }
+ {
+ const int x = 10;
+ auto L = [k = x](char a) {
+ return [k](int b) {
+ return [j = k](int c) {
+ return c;
+ };
+ };
+ };
+ }
+
+ return 0;
+}
+
+int run = test();
+
+}
+
+namespace odr_use_within_init_capture_template {
+
+template<class T = int>
+int test(T t = T{}) {
+
+ { // no captures
+ const T x = 10;
+ auto L = [z = x](char a) {
+ auto M = [y = x](T b) {
+ return y;
+ };
+ return M;
+ };
+
+ }
+ { // should not capture
+ const T x = 10;
+ auto L = [&z = x](T a) {
+ return a;;
+ };
+
+ }
+ { // will need to capture x in outer lambda
+ const T x = 10; //expected-note {{declared}}
+ auto L = [z = x](char a) { //expected-note {{begins}}
+ auto M = [&y = x](T b) { //expected-error {{cannot be implicitly captured}}
+ return y;
+ };
+ return M;
+ };
+
+ }
+ { // will need to capture x in outer lambda
+ const T x = 10;
+ auto L = [=,z = x](char a) {
+ auto M = [&y = x](T b) {
+ return y;
+ };
+ return M;
+ };
+
+ }
+ { // will need to capture x in outer lambda
+ const T x = 10;
+ auto L = [x, z = x](char a) {
+ auto M = [&y = x](T b) {
+ return y;
+ };
+ return M;
+ };
+ }
+ { // will need to capture x in outer lambda
+ const int x = 10; //expected-note 2{{declared}}
+ auto L = [z = x](char a) { //expected-note 2{{begins}}
+ auto M = [&y = x](T b) { //expected-error 2{{cannot be implicitly captured}}
+ return y;
+ };
+ return M;
+ };
+ }
+ {
+ // no captures
+ const T x = 10;
+ auto L = [z =
+ [z = x, &y = x](char a) { return z + y; }('a')](char a)
+ { return z; };
+
+ }
+
+ return 0;
+}
+
+int run = test(); //expected-note {{instantiation}}
+
+} \ No newline at end of file
diff --git a/test/SemaCXX/cxx1y-sized-deallocation.cpp b/test/SemaCXX/cxx1y-sized-deallocation.cpp
new file mode 100644
index 0000000..81a8eeb
--- /dev/null
+++ b/test/SemaCXX/cxx1y-sized-deallocation.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=c++1y -verify %s -fsized-deallocation -fexceptions -fcxx-exceptions
+
+using size_t = decltype(sizeof(0));
+
+void f(void *p, void *q) {
+ // OK, implicitly declared.
+ operator delete(p, 8);
+ operator delete[](q, 12);
+ static_assert(noexcept(operator delete(p, 8)), "");
+ static_assert(noexcept(operator delete[](q, 12)), "");
+}
+
+void *operator new(size_t bad, size_t idea);
+struct S { S() { throw 0; } };
+void g() {
+ new (123) S; // expected-error {{'new' expression with placement arguments refers to non-placement 'operator delete'}}
+}
diff --git a/test/SemaCXX/cxx1y-user-defined-literals.cpp b/test/SemaCXX/cxx1y-user-defined-literals.cpp
new file mode 100644
index 0000000..fa4ff03
--- /dev/null
+++ b/test/SemaCXX/cxx1y-user-defined-literals.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -std=c++1y %s -include %s -verify
+
+#ifndef INCLUDED
+#define INCLUDED
+
+#pragma clang system_header
+namespace std {
+ using size_t = decltype(sizeof(0));
+
+ struct duration {};
+ duration operator""ns(unsigned long long);
+ duration operator""us(unsigned long long);
+ duration operator""ms(unsigned long long);
+ duration operator""s(unsigned long long);
+ duration operator""min(unsigned long long);
+ duration operator""h(unsigned long long);
+
+ struct string {};
+ string operator""s(const char*, size_t);
+
+ template<typename T> struct complex {};
+ complex<float> operator""if(long double);
+ complex<float> operator""if(unsigned long long);
+ complex<double> operator""i(long double);
+ complex<double> operator""i(unsigned long long);
+ complex<long double> operator""il(long double);
+ complex<long double> operator""il(unsigned long long);
+}
+
+#else
+
+using namespace std;
+duration a = 1ns, b = 1us, c = 1ms, d = 1s, e = 1min, f = 1h;
+string s = "foo"s;
+char error = 'x's; // expected-error {{invalid suffix}} expected-error {{expected ';'}}
+
+int _1z = 1z; // expected-error {{invalid suffix}}
+int _1b = 1b; // expected-error {{invalid digit}}
+
+complex<float> cf1 = 1if, cf2 = 2.if, cf3 = 0x3if;
+complex<double> cd1 = 1i, cd2 = 2.i, cd3 = 0b0110101i;
+complex<long double> cld1 = 1il, cld2 = 2.il, cld3 = 0047il;
+
+#endif
diff --git a/test/SemaCXX/cxx1y-variable-templates_in_class.cpp b/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
new file mode 100644
index 0000000..94d0f16
--- /dev/null
+++ b/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -0,0 +1,299 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s -Wno-c++11-extensions -Wno-c++1y-extensions -DPRECXX11
+// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s
+
+#define CONST const
+
+#ifdef PRECXX11
+#define static_assert(expr, msg) typedef int static_assert[(expr) ? 1 : -1];
+#endif
+
+class A {
+ template<typename T> CONST T wrong; // expected-error {{member 'wrong' declared as a template}}
+ template<typename T> CONST T wrong_init = 5; // expected-error {{member 'wrong_init' declared as a template}}
+ template<typename T, typename T0> static CONST T right = T(100);
+ template<typename T> static CONST T right<T,int> = 5;
+ template<typename T> CONST int right<int,T>; // expected-error {{member 'right' declared as a template}}
+ template<typename T> CONST float right<float,T> = 5; // expected-error {{member 'right' declared as a template}}
+ template<> static CONST int right<int,int> = 7; // expected-error {{explicit specialization of 'right' in class scope}}
+ template<> static CONST float right<float,int>; // expected-error {{explicit specialization of 'right' in class scope}}
+ template static CONST int right<int,int>; // expected-error {{template specialization requires 'template<>'}} \
+ // expected-error {{explicit specialization of 'right' in class scope}}
+};
+
+namespace out_of_line {
+ class B0 {
+ template<typename T, typename T0> static CONST T right = T(100);
+ template<typename T> static CONST T right<T,int> = T(5);
+ };
+ template<> CONST int B0::right<int,int> = 7;
+ template CONST int B0::right<int,int>;
+ template<> CONST int B0::right<int,float>;
+ template CONST int B0::right<int,float>;
+
+ class B1 {
+ template<typename T, typename T0> static CONST T right;
+ template<typename T> static CONST T right<T,int>;
+ };
+ template<typename T, typename T0> CONST T B1::right = T(100);
+ 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> 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'}}
+
+ class B3 {
+ template<typename T, typename T0> static CONST T right = T(100);
+ template<typename T> static CONST T right<T,int> = T(5);
+ };
+ template<typename T, typename T0> CONST T B3::right;
+ template<typename T> CONST T B3::right<T,int>;
+
+ class B4 {
+ template<typename T, typename T0> static CONST T a;
+ template<typename T> static CONST T a<T,int> = T(100);
+ template<typename T, typename T0> static CONST T b = T(100);
+ template<typename T> static CONST T b<T,int>;
+ };
+ template<typename T, typename T0> CONST T B4::a; // expected-error {{default initialization of an object of const type 'const int'}}
+ template<typename T> CONST T B4::a<T,int>;
+ template CONST int B4::a<int,char>; // expected-note {{in instantiation of}}
+ template CONST int B4::a<int,int>;
+
+ template<typename T, typename T0> CONST T B4::b;
+ template<typename T> CONST T B4::b<T,int>; // expected-error {{default initialization of an object of const type 'const int'}}
+ template CONST int B4::b<int,char>;
+ template CONST int B4::b<int,int>; // expected-note {{in instantiation of}}
+}
+
+namespace non_const_init {
+ class A {
+ template<typename T> static T wrong_inst_undefined = T(10); // expected-note {{refers here}}
+ template<typename T> static T wrong_inst_defined = T(10); // expected-error {{non-const static data member must be initialized out of line}}
+ template<typename T> static T wrong_inst_out_of_line;
+ };
+
+ template const int A::wrong_inst_undefined<const int>; // expected-error {{undefined}}
+
+ template<typename T> T A::wrong_inst_defined;
+ template const int A::wrong_inst_defined<const int>;
+ template int A::wrong_inst_defined<int>; // expected-note {{in instantiation of static data member 'non_const_init::A::wrong_inst_defined<int>' requested here}}
+
+ template<typename T> T A::wrong_inst_out_of_line = T(10);
+ template int A::wrong_inst_out_of_line<int>;
+
+ class B {
+ template<typename T> static T wrong_inst; // expected-note {{refers here}}
+ template<typename T> static T wrong_inst<T*> = T(100); // expected-error {{non-const static data member must be initialized out of line}} expected-note {{refers here}}
+
+ template<typename T> static T wrong_inst_fixed;
+ template<typename T> static T wrong_inst_fixed<T*>;
+ };
+ template int B::wrong_inst<int>; // expected-error {{undefined}}
+ // FIXME: It'd be better to produce the 'explicit instantiation of undefined
+ // template' diagnostic here, not the 'must be initialized out of line'
+ // diagnostic.
+ template int B::wrong_inst<int*>; // expected-note {{in instantiation of static data member 'non_const_init::B::wrong_inst<int *>' requested here}}
+ template const int B::wrong_inst<const int*>; // expected-error {{undefined}}
+ template<typename T> T B::wrong_inst_fixed = T(100);
+ template int B::wrong_inst_fixed<int>;
+
+ class C {
+ template<typename T> static CONST T right_inst = T(10); // expected-note {{here}}
+ template<typename T> static CONST T right_inst<T*> = T(100); // expected-note {{here}}
+ };
+ template CONST int C::right_inst<int>; // expected-error {{undefined variable template}}
+ template CONST int C::right_inst<int*>; // expected-error {{undefined variable template}}
+
+ namespace pointers {
+
+ struct C0 {
+ template<typename U> static U Data;
+ template<typename U> static CONST U Data<U*> = U(); // expected-note {{here}}
+
+ template<typename U> static U Data2;
+ template<typename U> static CONST U Data2<U*> = U();
+ };
+ const int c0_test = C0::Data<int*>;
+ static_assert(c0_test == 0, "");
+ template const int C0::Data<int*>; // expected-error {{undefined}}
+
+ template<typename U> const U C0::Data2<U*>;
+ template const int C0::Data2<int*>;
+
+ struct C1a {
+ template<typename U> static U Data;
+ template<typename U> static U* Data<U*>; // Okay, with out-of-line definition
+ };
+ template<typename T> T* C1a::Data<T*> = new T();
+ template int* C1a::Data<int*>;
+
+ struct C1b {
+ template<typename U> static U Data;
+ template<typename U> static CONST U* Data<U*>; // Okay, with out-of-line definition
+ };
+ template<typename T> CONST T* C1b::Data<T*> = (T*)(0);
+ template CONST int* C1b::Data<int*>;
+
+ struct C2a {
+ template<typename U> static int Data;
+ template<typename U> static U* Data<U*> = new U(); // expected-error {{non-const static data member must be initialized out of line}}
+ };
+ template int* C2a::Data<int*>; // expected-note {{in instantiation of static data member 'non_const_init::pointers::C2a::Data<int *>' requested here}}
+
+ struct C2b {
+ template<typename U> static int Data;
+ template<typename U> static U *const Data<U*> = (U*)(0); // expected-error {{static data member of type 'int *const'}}
+ };
+ template<typename U> U *const C2b::Data<U*>;
+ template int *const C2b::Data<int*>; // expected-note {{in instantiation of static data member 'non_const_init::pointers::C2b::Data<int *>' requested here}}
+ }
+}
+
+#ifndef PRECXX11
+namespace constexpred {
+ class A {
+ template<typename T> constexpr T wrong; // expected-error {{member 'wrong' declared as a template}} \
+ // expected-error {{non-static data member cannot be constexpr; did you intend to make it const?}}
+ template<typename T> constexpr T wrong_init = 5; // expected-error {{non-static data member cannot be constexpr; did you intend to make it static?}}
+ template<typename T, typename T0> static constexpr T right = T(100);
+ template<typename T> static constexpr T right<T,int> = 5;
+ template<typename T> constexpr int right<int,T>; // expected-error {{member 'right' declared as a template}} \
+ // expected-error {{non-static data member cannot be constexpr; did you intend to make it const?}}
+ template<typename T> constexpr float right<float,T> = 5; // expected-error {{non-static data member cannot be constexpr; did you intend to make it static?}}
+ template<> static constexpr int right<int,int> = 7; // expected-error {{explicit specialization of 'right' in class scope}}
+ template<> static constexpr float right<float,int>; // expected-error {{explicit specialization of 'right' in class scope}}
+ template static constexpr int right<int,int>; // expected-error {{template specialization requires 'template<>'}} \
+ // expected-error {{explicit specialization of 'right' in class scope}}
+ };
+}
+#endif
+
+namespace in_class_template {
+
+ template<typename T>
+ class D0 {
+ template<typename U> static U Data; // expected-note {{here}}
+ template<typename U> static CONST U Data<U*> = U();
+ };
+ template CONST int D0<float>::Data<int*>;
+ template int D0<float>::Data<int>; // expected-error {{undefined}}
+ template<typename T> template<typename U> const U D0<T>::Data<U*>;
+
+ template<typename T>
+ class D1 {
+ template<typename U> static U Data;
+ template<typename U> static U* Data<U*>;
+ };
+ template<typename T>
+ template<typename U> U* D1<T>::Data<U*> = (U*)(0);
+ template int* D1<float>::Data<int*>; // expected-note {{previous}}
+ template int* D1<float>::Data<int*>; // expected-error {{duplicate explicit instantiation}}
+
+ template<typename T>
+ class D2 {
+ template<typename U> static U Data;
+ template<typename U> static U* Data<U*>;
+ };
+ template<>
+ template<typename U> U* D2<float>::Data<U*> = (U*)(0) + 1;
+ template int* D2<float>::Data<int*>; // expected-note {{previous}}
+ template int* D2<float>::Data<int*>; // expected-error {{duplicate explicit instantiation}}
+
+ template<typename T>
+ struct D3 {
+ template<typename U> static CONST U Data = U(100); // expected-note {{here}}
+ };
+ static_assert(D3<float>::Data<int> == 100, "");
+ template const char D3<float>::Data<char>; // expected-error {{undefined}}
+
+ namespace bug_files {
+ template<typename T>
+ class D0a {
+ template<typename U> static U Data;
+ template<typename U> static CONST U Data<U*> = U(10); // expected-note {{previous definition is here}}
+ };
+ template<>
+ template<typename U> U D0a<float>::Data<U*> = U(100); // expected-error {{redefinition of 'Data'}}
+
+ // FIXME: We should accept this, and the corresponding case for class
+ // templates.
+ //
+ // [temp.class.spec.mfunc]/2: If the primary member template is explicitly
+ // specialized for a given specialization of the enclosing class template,
+ // the partial specializations of the member template are ignored
+ template<typename T>
+ class D1 {
+ template<typename U> static U Data;
+ template<typename U> static CONST U Data<U*> = U(10); // expected-note {{previous definition is here}}
+ };
+ template<>
+ template<typename U> U D1<float>::Data = U(10);
+ template<>
+ template<typename U> U D1<float>::Data<U*> = U(100); // expected-error{{redefinition of 'Data'}}
+ }
+
+ namespace definition_after_outer_instantiation {
+ template<typename A> struct S {
+ template<typename B> static const int V1;
+ template<typename B> static const int V2;
+ };
+ template struct S<int>;
+ template<typename A> template<typename B> const int S<A>::V1 = 123;
+ template<typename A> template<typename B> const int S<A>::V2<B*> = 456;
+
+ static_assert(S<int>::V1<int> == 123, "");
+
+ // FIXME: The first and third case below possibly should be accepted. We're
+ // not picking up partial specializations added after the primary template
+ // is instantiated. This is kind of implied by [temp.class.spec.mfunc]/2,
+ // and matches our behavior for member class templates, but it's not clear
+ // that this is intentional. See PR17294 and core-24030.
+ static_assert(S<int>::V2<int*> == 456, ""); // FIXME expected-error {{}}
+ static_assert(S<int>::V2<int&> == 789, ""); // expected-error {{}}
+
+ template<typename A> template<typename B> const int S<A>::V2<B&> = 789;
+ static_assert(S<int>::V2<int&> == 789, ""); // FIXME expected-error {{}}
+
+ // All is OK if the partial specialization is declared before the implicit
+ // instantiation of the class template specialization.
+ static_assert(S<char>::V1<int> == 123, "");
+ static_assert(S<char>::V2<int*> == 456, "");
+ static_assert(S<char>::V2<int&> == 789, "");
+ }
+
+ namespace incomplete_array {
+ template<typename T> extern T var[];
+ template<typename T> T var[] = { 1, 2, 3 };
+ template<> char var<char>[] = "hello";
+ template<typename T> char var<T*>[] = "pointer";
+
+ static_assert(sizeof(var<int>) == 12, "");
+ static_assert(sizeof(var<char>) == 6, "");
+ static_assert(sizeof(var<void*>) == 8, "");
+
+ template<typename...> struct tuple;
+
+ template<typename T> struct A {
+ template<typename U> static T x[];
+ template<typename U> static T y[];
+
+ template<typename...U> static T y<tuple<U...> >[];
+ };
+
+ int *use_before_definition = A<int>::x<char>;
+ template<typename T> template<typename U> T A<T>::x[sizeof(U)];
+ static_assert(sizeof(A<int>::x<char>) == 4, "");
+
+ 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 in_nested_classes {
+ // TODO:
+}
+
diff --git a/test/SemaCXX/cxx1y-variable-templates_top_level.cpp b/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
new file mode 100644
index 0000000..b6e8762
--- /dev/null
+++ b/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
@@ -0,0 +1,434 @@
+// RUN: %clang_cc1 -verify -fsyntax-only -Wno-c++11-extensions -Wno-c++1y-extensions %s -DPRECXX11
+// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s
+
+#ifdef PRECXX11
+ #define CONST const
+#else
+ #define CONST constexpr
+#endif
+
+template<typename T>
+T pi = T(3.1415926535897932385); // expected-note {{template is declared here}}
+
+template<typename T>
+CONST T cpi = T(3.1415926535897932385); // expected-note {{template is declared here}}
+
+template<typename T> extern CONST T vc;
+#ifndef PRECXX11
+// expected-error@-2 {{constexpr variable declaration must be a definition}}
+#endif
+
+namespace use_in_top_level_funcs {
+
+ void good() {
+ int ipi = pi<int>;
+ int icpi = cpi<int>;
+ double dpi = pi<double>;
+ double dcpi = cpi<double>;
+ }
+
+ void no_deduce() {
+ // template arguments are not deduced for uses of variable templates.
+ int ipi = pi; // expected-error {{cannot refer to variable template 'pi' without a template argument list}}
+ int icpi = cpi; // expected-error {{cannot refer to variable template 'cpi' without a template argument list}}
+ }
+
+ template<typename T>
+ T circular_area(T r) {
+ return pi<T> * r * r;
+ }
+
+ template<typename T>
+ CONST T const_circular_area(T r) {
+ return cpi<T> * r * r;
+ }
+
+ double use_circular_area(double r) {
+ CONST float t = const_circular_area(2.0) - 12;
+#ifndef PRECXX11
+ static_assert(const_circular_area(2) == 12, "");
+ CONST int test = (t > 0) && (t < 1);
+ static_assert(test, "");
+#endif
+ return circular_area(r);
+ }
+}
+
+namespace shadow {
+ void foo() {
+ int ipi0 = pi<int>;
+ int pi;
+ int a = pi;
+ int ipi = pi<int>; // expected-error {{expected '(' for function-style cast or type construction}} \
+ // expected-error {{expected expression}}
+ }
+}
+
+namespace odr_tmpl {
+ namespace pv_cvt {
+ int v; // expected-note {{previous definition is here}}
+ template<typename T> T v; // expected-error {{redefinition of 'v' as different kind of symbol}}
+ }
+ namespace pvt_cv {
+ template<typename T> T v; // expected-note {{previous definition is here}}
+ int v; // expected-error {{redefinition of 'v' as different kind of symbol}}
+ }
+ namespace pvt_cvt {
+ template<typename T> T v0; // expected-note {{previous definition is here}}
+ template<typename T> T v0; // expected-error {{redefinition of 'v0'}}
+
+ 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<int I> int v1; // expected-error {{template parameter has a different kind in template redeclaration}}
+ }
+ namespace pvt_use {
+ template<typename T> T v;
+ v = 10; // expected-error {{C++ requires a type specifier for all declarations}}
+ }
+
+ 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, typename> T v; // expected-error {{too many template parameters in template redeclaration}}
+ }
+
+ namespace pvt_extern {
+ template<typename T> T v = T();
+ template<typename T> extern T v; // redeclaration is allowed \
+ // expected-note {{previous definition is here}}
+ template<typename T> extern int v; // expected-error {{redefinition of 'v' with a different type: 'int' vs 'T'}}
+
+#ifndef PRECXX11
+ template<typename T> extern auto v; // expected-error {{declaration of variable 'v' with type 'auto' requires an initializer}}
+#endif
+
+ template<typename T> T var = T(); // expected-note {{previous definition is here}}
+ extern int var; // expected-error {{redefinition of 'var' as different kind of symbol}}
+ }
+
+#ifndef PRECXX11
+ namespace pvt_auto {
+ template<typename T> auto v0; // expected-error {{declaration of variable 'v0' with type 'auto' requires an initializer}}
+ template<typename T> auto v1 = T(); // expected-note {{previous definition is here}}
+ template<typename T> int v1; // expected-error {{redefinition of 'v1' with a different type: 'int' vs 'auto'}}
+ template<typename T> auto v2 = T(); // expected-note {{previous definition is here}}
+ template<typename T> T v2; // expected-error {{redefinition of 'v2'}}
+ template<typename T> auto v3 = T(); // expected-note {{previous definition is here}}
+ template<typename T> extern T v3; // expected-error {{redefinition of 'v3' with a different type: 'T' vs 'auto'}}
+ template<typename T> auto v4 = T();
+ template<typename T> extern auto v4; // expected-error {{declaration of variable 'v4' with type 'auto' requires an initializer}}
+ }
+#endif
+
+}
+
+namespace explicit_instantiation {
+ template<typename T>
+ T pi0a = T(3.1415926535897932385); // expected-note {{variable template 'pi0a' declared here}}
+ template float pi0a<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0a' does not match expected type 'int'}}
+
+ template<typename T>
+ T pi0b = T(3.1415926535897932385); // expected-note {{variable template 'pi0b' declared here}}
+ template CONST int pi0b<int>; // expected-error {{type 'const int' of explicit instantiation of 'pi0b' does not match expected type 'int'}}
+
+ template<typename T>
+ T pi0c = T(3.1415926535897932385); // expected-note {{variable template 'pi0c' declared here}}
+ template int pi0c<const int>; // expected-error {{type 'int' of explicit instantiation of 'pi0c' does not match expected type 'const int'}}
+
+ template<typename T>
+ T pi0 = T(3.1415926535897932385);
+ template int pi0<int>; // expected-note {{previous explicit instantiation is here}}
+ template int pi0<int>; // expected-error {{duplicate explicit instantiation of 'pi0<int>'}}
+
+ template<typename T>
+ CONST T pi1a = T(3.1415926535897932385); // expected-note {{variable template 'pi1a' declared here}}
+ template int pi1a<int>; // expected-error {{type 'int' of explicit instantiation of 'pi1a' does not match expected type 'const int'}}
+
+ template<typename T>
+ CONST T pi1b = T(3.1415926535897932385); // expected-note {{variable template 'pi1b' declared here}}
+ template int pi1b<const int>; // expected-error {{type 'int' of explicit instantiation of 'pi1b' does not match expected type 'const const int'}}
+
+ template<typename T>
+ CONST T pi1 = T(3.1415926535897932385);
+ template CONST int pi1<int>; // expected-note {{previous explicit instantiation is here}}
+ template CONST int pi1<int>; // expected-error {{duplicate explicit instantiation of 'pi1<int>'}}
+
+#ifndef PRECXX11
+ namespace auto_var {
+ template<typename T> auto var0 = T();
+ template auto var0<int>; // expected-error {{'auto' variable template instantiation is not allowed}}
+
+ template<typename T> auto var = T();
+ template int var<int>;
+ }
+#endif
+
+ template<typename=int> int missing_args; // expected-note {{here}}
+ template int missing_args; // expected-error {{must specify a template argument list}}
+
+ namespace extern_var {
+ // TODO:
+ }
+}
+
+namespace explicit_specialization {
+
+ namespace good {
+ template<typename T1, typename T2>
+ CONST int pi2 = 1;
+
+ template<typename T>
+ CONST int pi2<T,int> = 2;
+
+ template<typename T>
+ CONST int pi2<int,T> = 3;
+
+ template<> CONST int pi2<int,int> = 4;
+
+#ifndef PRECXX11
+ void foo() {
+ static_assert(pi2<int,int> == 4, "");
+ static_assert(pi2<float,int> == 2, "");
+ static_assert(pi2<int,float> == 3, "");
+ static_assert(pi2<int,float> == pi2<int,double>, "");
+ static_assert(pi2<float,float> == 1, "");
+ static_assert(pi2<float,float> == pi2<float,double>, "");
+ }
+#endif
+ }
+
+ namespace ambiguous {
+
+ template<typename T1, typename T2>
+ CONST int pi2 = 1;
+
+ template<typename T>
+ CONST int pi2<T,int> = 2; // expected-note {{partial specialization matches [with T = int]}}
+
+ template<typename T>
+ CONST int pi2<int,T> = 3; // expected-note {{partial specialization matches [with T = int]}}
+
+ void foo() {
+ int a = pi2<int,int>; // expected-error {{ambiguous partial specializations of 'pi2<int, int>'}}
+ }
+ }
+
+ namespace type_changes {
+
+ template<typename T>
+ T pi0 = T(3.1415926535897932385);
+
+ template<> float pi0<int> = 10;
+ template<> int pi0<const int> = 10;
+
+ template<typename T>
+ T pi1 = T(3.1415926535897932385);
+ template<> CONST int pi1<int> = 10;
+
+ template<typename T>
+ T pi2 = T(3.1415926535897932385);
+ template<> int pi2<const int> = 10;
+
+ template<typename T>
+ CONST T pi4 = T(3.1415926535897932385);
+ template<> int pi4<int> = 10;
+ }
+
+ namespace redefinition {
+ template<typename T>
+ T pi0 = T(3.1415926535897932385);
+
+ template<> int pi0<int> = 10; // expected-note 3{{previous definition is here}}
+#ifndef PRECXX11
+// expected-note@-2 {{previous definition is here}}
+#endif
+ template<> int pi0<int> = 10; // expected-error {{redefinition of 'pi0<int>'}}
+ template<> CONST int pi0<int> = 10; // expected-error {{redefinition of 'pi0' with a different type: 'const int' vs 'int'}}
+ template<> float pi0<int> = 10; // expected-error {{redefinition of 'pi0' with a different type: 'float' vs 'int'}}
+#ifndef PRECXX11
+ template<> auto pi0<int> = 10; // expected-error {{redefinition of 'pi0<int>'}}
+#endif
+
+
+ template<typename T>
+ CONST T pi1 = T(3.1415926535897932385);
+
+ template<> CONST int pi1<int> = 10; // expected-note {{previous definition is here}}
+ template<> CONST int pi1<int> = 10; // expected-error {{redefinition of 'pi1<int>'}}
+ }
+
+ namespace before_instantiation {
+ template<typename T>
+ T pi0 = T(3.1415926535897932385); // expected-note {{variable template 'pi0' declared here}}
+
+ template<> int pi0<int> = 10;
+ template int pi0<int>;
+ template float pi0<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0' does not match expected type}}
+
+ template<typename T1, typename T2>
+ CONST int pi2 = 1;
+
+ template<typename T> CONST int pi2<T,int> = 2;
+ template CONST int pi2<int,int>;
+ }
+ namespace after_instantiation {
+ template<typename T>
+ T pi0 = T(3.1415926535897932385);
+
+ template int pi0<int>; // expected-note 2{{explicit instantiation first required here}}
+ template<> int pi0<int> = 10; // expected-error {{explicit specialization of 'pi0' after instantiation}}
+ template<> float pi0<int>; // expected-error {{explicit specialization of 'pi0' after instantiation}}
+
+ template<typename T1, typename T2>
+ CONST int pi2 = 1;
+
+ template CONST int pi2<int,int>;
+ template<typename T> CONST int pi2<T,int> = 2;
+ }
+
+#ifndef PRECXX11
+ namespace auto_var {
+ template<typename T, typename> auto var0 = T();
+ template<typename T> auto var0<T,int> = T();
+ template<> auto var0<int,int> = 7;
+
+ template<typename T, typename> auto var = T();
+ template<typename T> T var<T,int> = T(5);
+ template<> int var<int,int> = 7;
+
+ void foo() {
+ int i0 = var0<int,int>;
+ int b = var<int,int>;
+ }
+ }
+#endif
+
+ namespace extern_var {
+ // TODO:
+ }
+
+ namespace diff_type {
+ // TODO:
+ template<typename T> T* var = new T();
+#ifndef PRECXX11
+ template<typename T> auto var<T*> = T(); // expected-note {{previous definition is here}}
+ template<typename T> T var<T*> = T(); // expected-error {{redefinition of 'var' with a different type: 'T' vs 'auto'}}
+#endif
+ }
+}
+
+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}}
+#endif
+ int k = v<char>; // expected-note {{in instantiation of variable template specialization 'narrowing::v<char>' requested here}}
+}
+
+namespace use_in_structs {
+ // TODO:
+}
+
+namespace attributes {
+ // TODO:
+}
+
+#ifndef PRECXX11
+namespace arrays {
+ template<typename T>
+ T* arr = new T[10]{T(10), T(23)};
+
+ float f = 10.5;
+ template<> float* arr<float> = &f;
+
+ void bar() {
+ int *iarr = arr<int>;
+ iarr[0] = 1;
+ iarr[2] = 3;
+ iarr[6] = -2;
+
+ float ff = *arr<float>;
+ float nof = arr<float>[3]; // No bounds-check in C++
+ }
+}
+#endif
+
+namespace nested {
+
+ namespace n0a {
+ template<typename T>
+ T pi0a = T(3.1415926535897932385);
+ }
+
+ using namespace n0a;
+ int i0a = pi0a<int>;
+
+ template float pi0a<float>;
+ float f0a = pi0a<float>;
+
+ template<> double pi0a<double> = 5.2;
+ double d0a = pi0a<double>;
+
+ namespace n0b {
+ template<typename T>
+ T pi0b = T(3.1415926535897932385);
+ }
+
+ int i0b = n0b::pi0b<int>;
+
+ template float n0b::pi0b<float>;
+ float f0b = n0b::pi0b<float>;
+
+ template<> double n0b::pi0b<double> = 5.2;
+ double d0b = n0b::pi0b<double>;
+
+ namespace n1 {
+ template<typename T>
+ T pi1a = T(3.1415926535897932385);
+#ifndef PRECXX11
+// expected-note@-2 {{explicit instantiation refers here}}
+#endif
+
+ template<typename T>
+ T pi1b = T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}}
+#ifndef PRECXX11
+// expected-note@-2 {{explicit instantiation refers here}}
+#endif
+ }
+
+ namespace use_n1a {
+ using namespace n1;
+ int i1 = pi1a<int>;
+
+ template float pi1a<float>;
+#ifndef PRECXX11
+// expected-error@-2 {{explicit instantiation of 'pi1a<float>' not in a namespace enclosing 'n1'}}
+#endif
+ float f1 = pi1a<float>;
+
+ template<> double pi1a<double> = 5.2; // expected-error {{no variable template matches specialization}}
+ double d1 = pi1a<double>;
+ }
+
+ namespace use_n1b {
+ int i1 = n1::pi1b<int>;
+
+ template float n1::pi1b<float>;
+#ifndef PRECXX11
+// expected-error@-2 {{explicit instantiation of 'pi1b<float>' not in a namespace enclosing 'n1'}}
+#endif
+ float f1 = n1::pi1b<float>;
+
+ template<> double n1::pi1b<double> = 5.2; // expected-error {{cannot define or redeclare 'pi1b' here because namespace 'use_n1b' does not enclose namespace 'n1'}} \
+ // expected-error {{variable template specialization of 'pi1b' must originally be declared in namespace 'n1'}}
+ double d1 = n1::pi1b<double>;
+ }
+}
+
diff --git a/test/SemaCXX/cxx98-compat-pedantic.cpp b/test/SemaCXX/cxx98-compat-pedantic.cpp
index 208ea4c..b74dcb4 100644
--- a/test/SemaCXX/cxx98-compat-pedantic.cpp
+++ b/test/SemaCXX/cxx98-compat-pedantic.cpp
@@ -1,9 +1,11 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++1y -DCXX1Y -Wc++98-compat-pedantic -verify %s
-// RUN: %clang_cc1 -fsyntax-only -std=c++1y -DCXX1Y -Wc++98-compat -Werror %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++1y -DCXX1Y -Wc++98-compat-pedantic -verify %s -DCXX1Y2
+// RUN: %clang_cc1 -fsyntax-only -std=c++1y -DCXX1Y -Wc++98-compat -Werror %s -DCXX1Y2
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat-pedantic -verify %s
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -Werror %s
// RUN: %clang_cc1 -fsyntax-only -std=c++98 -Werror %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++1y -Wc++98-compat-pedantic -verify %s -Wno-c++98-c++11-compat-pedantic -DCXX1Y2
+
// -Wc++98-compat-pedantic warns on C++11 features which we accept without a
// warning in C++98 mode.
@@ -30,7 +32,12 @@ void *FnVoidPtr = (void*)&dlsym; // expected-warning {{cast between pointer-to-f
struct ConvertToInt {
operator int();
};
-int *ArraySizeConversion = new int[ConvertToInt()]; // expected-warning {{implicit conversion from array size expression of type 'ConvertToInt' to integral type 'int' is incompatible with C++98}}
+int *ArraySizeConversion = new int[ConvertToInt()];
+#ifdef CXX1Y2
+// expected-warning@-2 {{implicit conversion from array size expression of type 'ConvertToInt' to integral type 'size_t' is incompatible with C++98}}
+#else
+// expected-warning@-4 {{implicit conversion from array size expression of type 'ConvertToInt' to integral type 'int' is incompatible with C++98}}
+#endif
template<typename T> class ExternTemplate {};
extern template class ExternTemplate<int>; // expected-warning {{extern templates are incompatible with C++98}}
@@ -44,8 +51,3 @@ int k = 0b1001;
#ifdef CXX1Y
// expected-warning@-2 {{binary integer literals are incompatible with C++ standards before C++1y}}
#endif
-
-void f(int n) { int a[n]; }
-#ifdef CXX1Y
-// expected-warning@-2 {{arrays of runtime bound are incompatible with C++ standards before C++1y}}
-#endif
diff --git a/test/SemaCXX/cxx98-compat.cpp b/test/SemaCXX/cxx98-compat.cpp
index 7d36770..9690638 100644
--- a/test/SemaCXX/cxx98-compat.cpp
+++ b/test/SemaCXX/cxx98-compat.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -verify %s
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++1y -Wc++98-compat -verify %s -DCXX1YCOMPAT
namespace std {
struct type_info;
@@ -73,7 +73,7 @@ int InitList(int i = {}) { // expected-warning {{generalized initializer lists a
Ctor c2 = { 3.0, 4l }; // expected-warning {{constructor call from initializer list is incompatible with C++98}}
InitListCtor ilc = { true, false }; // expected-warning {{initialization of initializer_list object is incompatible with C++98}}
const int &r = { 0 }; // expected-warning {{reference initialized from initializer list is incompatible with C++98}}
- struct { int a; const int &r; } rr = { 0, {{0}} }; // expected-warning {{reference initialized from initializer list is incompatible with C++98}}
+ struct { int a; const int &r; } rr = { 0, {0} }; // expected-warning {{reference initialized from initializer list is incompatible with C++98}}
return { 0 }; // expected-warning {{generalized initializer lists are incompatible with C++98}}
}
struct DelayedDefaultArgumentParseInitList {
@@ -147,16 +147,12 @@ bool no_except_expr = noexcept(1 + 1); // expected-warning {{noexcept expression
void *null = nullptr; // expected-warning {{'nullptr' is incompatible with C++98}}
static_assert(true, "!"); // expected-warning {{static_assert declarations are incompatible with C++98}}
-// FIXME: Reintroduce this test if support for inheriting constructors is
-// implemented.
-#if 0
struct InhCtorBase {
InhCtorBase(int);
};
struct InhCtorDerived : InhCtorBase {
- using InhCtorBase::InhCtorBase; // xpected-warning {{inheriting constructors are incompatible with C++98}}
+ using InhCtorBase::InhCtorBase; // expected-warning {{inheriting constructors are incompatible with C++98}}
};
-#endif
struct FriendMember {
static void MemberFn();
@@ -382,3 +378,79 @@ namespace rdar11736429 {
X x; // expected-warning{{union member 'x' with a non-trivial constructor is incompatible with C++98}}
};
}
+
+template<typename T> 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> 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 {
+ 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
+
+};
+
+struct B { template<typename T> static T v; };
+#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> T B::v = 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> 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>;
+
+#ifdef CXX1YCOMPAT
+int digit_seps = 123'456; // expected-warning {{digit separators are incompatible with C++ standards before C++1y}}
+#endif
diff --git a/test/SemaCXX/dcl_ambig_res.cpp b/test/SemaCXX/dcl_ambig_res.cpp
index 97780e4..c0f1e2e 100644
--- a/test/SemaCXX/dcl_ambig_res.cpp
+++ b/test/SemaCXX/dcl_ambig_res.cpp
@@ -44,9 +44,7 @@ S4<int(1)> y; // expected-error{{must be a type}}
void foo5()
{
(void)sizeof(int(1)); //expression
- // FIXME: should we make this an error rather than a warning?
- // (It affects SFINAE)
- (void)sizeof(int()); // expected-warning{{function type}}
+ (void)sizeof(int()); // expected-error{{function type}}
}
// [dcl.ambig.res]p6:
diff --git a/test/SemaCXX/decl-expr-ambiguity.cpp b/test/SemaCXX/decl-expr-ambiguity.cpp
index 87fd2da..8164b2b 100644
--- a/test/SemaCXX/decl-expr-ambiguity.cpp
+++ b/test/SemaCXX/decl-expr-ambiguity.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -Wno-int-to-pointer-cast -fsyntax-only -verify -pedantic-errors %s
+// RUN: %clang_cc1 -Wno-int-to-pointer-cast -fsyntax-only -verify -pedantic-errors -x objective-c++ %s
void f() {
int a;
diff --git a/test/SemaCXX/decl-init-ref.cpp b/test/SemaCXX/decl-init-ref.cpp
index 4c635c1..2d0c9cb 100644
--- a/test/SemaCXX/decl-init-ref.cpp
+++ b/test/SemaCXX/decl-init-ref.cpp
@@ -26,4 +26,13 @@ int main() {
}
struct PR6139 { A (&x)[1]; };
-PR6139 x = {{A()}}; // expected-error{{non-const lvalue reference to type 'A [1]' cannot bind to a temporary of type 'A'}}
+PR6139 x = {{A()}}; // expected-error{{non-const lvalue reference to type 'A [1]' cannot bind to an initializer list temporary}}
+
+struct PR6139b { A (&x)[1]; };
+PR6139b y = {A()}; // expected-error{{non-const lvalue reference to type 'A [1]' cannot bind to a temporary of type 'A'}}
+
+namespace PR16502 {
+ struct A { int &&temporary; int x, y; };
+ int f();
+ const A &c = { 10, ++c.temporary };
+}
diff --git a/test/SemaCXX/decl-microsoft-call-conv.cpp b/test/SemaCXX/decl-microsoft-call-conv.cpp
index 3175af7..9f14632 100644
--- a/test/SemaCXX/decl-microsoft-call-conv.cpp
+++ b/test/SemaCXX/decl-microsoft-call-conv.cpp
@@ -1,21 +1,24 @@
// RUN: %clang_cc1 -triple i686-pc-win32 -cxx-abi microsoft -fms-extensions -verify %s
+typedef void void_fun_t();
+typedef void __cdecl cdecl_fun_t();
+
// Pointers to free functions
-void free_func_default();
-void __cdecl free_func_cdecl();
-void __stdcall free_func_stdcall(); // expected-note {{previous declaration is here}}
+void free_func_default(); // expected-note 2 {{previous declaration is here}}
+void __cdecl free_func_cdecl(); // expected-note 2 {{previous declaration is here}}
+void __stdcall free_func_stdcall(); // expected-note 2 {{previous declaration is here}}
void __fastcall free_func_fastcall(); // expected-note 2 {{previous declaration is here}}
-void __cdecl free_func_default(); // expected-note 2 {{previous declaration is here}}
+void __cdecl free_func_default();
void __stdcall free_func_default(); // expected-error {{function declared 'stdcall' here was previously declared without calling convention}}
void __fastcall free_func_default(); // expected-error {{function declared 'fastcall' here was previously declared without calling convention}}
-void free_func_cdecl(); // expected-note 2 {{previous declaration is here}}
+void free_func_cdecl();
void __stdcall free_func_cdecl(); // expected-error {{function declared 'stdcall' here was previously declared 'cdecl'}}
void __fastcall free_func_cdecl(); // expected-error {{function declared 'fastcall' here was previously declared 'cdecl'}}
+void free_func_stdcall();
void __cdecl free_func_stdcall(); // expected-error {{function declared 'cdecl' here was previously declared 'stdcall'}}
-void free_func_stdcall(); // expected-note {{previous declaration is here}}
void __fastcall free_func_stdcall(); // expected-error {{function declared 'fastcall' here was previously declared 'stdcall'}}
void __cdecl free_func_fastcall(); // expected-error {{function declared 'cdecl' here was previously declared 'fastcall'}}
@@ -29,6 +32,8 @@ void __cdecl free_func_default(int *);
void __thiscall free_func_cdecl(char *);
void __cdecl free_func_cdecl(double);
+typedef void void_fun_t();
+typedef void __cdecl cdecl_fun_t();
// Pointers to member functions
struct S {
@@ -38,10 +43,17 @@ struct S {
void __cdecl member_cdecl2(); // expected-note {{previous declaration is here}}
void __thiscall member_thiscall1();
void __thiscall member_thiscall2(); // expected-note {{previous declaration is here}}
-
+
+ // Typedefs carrying the __cdecl convention are adjusted to __thiscall.
+ void_fun_t member_typedef_default; // expected-note {{previous declaration is here}}
+ cdecl_fun_t member_typedef_cdecl1; // expected-note {{previous declaration is here}}
+ cdecl_fun_t __cdecl member_typedef_cdecl2;
+ void_fun_t __stdcall member_typedef_stdcall;
+
// Static member functions can't be __thiscall
static void static_member_default1();
- static void static_member_default2(); // expected-note {{previous declaration is here}}
+ static void static_member_default2();
+ static void static_member_default3(); // expected-note {{previous declaration is here}}
static void __cdecl static_member_cdecl1();
static void __cdecl static_member_cdecl2(); // expected-note {{previous declaration is here}}
static void __stdcall static_member_stdcall1();
@@ -58,29 +70,124 @@ struct S {
void __cdecl S::member_default1() {} // expected-error {{function declared 'cdecl' here was previously declared without calling convention}}
void __thiscall S::member_default2() {}
+void __cdecl S::member_typedef_default() {} // expected-error {{function declared 'cdecl' here was previously declared without calling convention}}
+void __cdecl S::member_typedef_cdecl1() {} // expected-error {{function declared 'cdecl' here was previously declared without calling convention}}
+void __cdecl S::member_typedef_cdecl2() {}
+void __stdcall S::member_typedef_stdcall() {}
+
void S::member_cdecl1() {}
void __thiscall S::member_cdecl2() {} // expected-error {{function declared 'thiscall' here was previously declared 'cdecl'}}
void S::member_thiscall1() {}
void __cdecl S::member_thiscall2() {} // expected-error {{function declared 'cdecl' here was previously declared 'thiscall'}}
-void __cdecl S::static_member_default1() {}
-void __stdcall S::static_member_default2() {} // expected-error {{function declared 'stdcall' here was previously declared without calling convention}}
+void S::static_member_default1() {}
+void __cdecl S::static_member_default2() {}
+void __stdcall S::static_member_default3() {} // expected-error {{function declared 'stdcall' here was previously declared without calling convention}}
void S::static_member_cdecl1() {}
void __stdcall S::static_member_cdecl2() {} // expected-error {{function declared 'stdcall' here was previously declared 'cdecl'}}
-void __cdecl S::member_variadic_default(int x, ...) {
- (void)x;
+void __cdecl S::member_variadic_default(int x, ...) { (void)x; }
+void S::member_variadic_cdecl(int x, ...) { (void)x; }
+
+void __cdecl S::static_member_variadic_default(int x, ...) { (void)x; }
+void S::static_member_variadic_cdecl(int x, ...) { (void)x; }
+
+// Declare a template using a calling convention.
+template <class CharT> inline int __cdecl mystrlen(const CharT *str) {
+ int i;
+ for (i = 0; str[i]; i++) { }
+ return i;
}
-void S::member_variadic_cdecl(int x, ...) {
- (void)x;
+extern int sse_strlen(const char *str);
+template <> inline int __cdecl mystrlen(const char *str) {
+ return sse_strlen(str);
+}
+void use_tmpl(const char *str, const int *ints) {
+ mystrlen(str);
+ mystrlen(ints);
+}
+
+struct MixedCCStaticOverload {
+ static void overloaded(int a);
+ static void __stdcall overloaded(short a);
+};
+
+void MixedCCStaticOverload::overloaded(int a) {}
+void MixedCCStaticOverload::overloaded(short a) {}
+
+// Friend function decls are cdecl by default, not thiscall. Friend method
+// decls should always be redeclarations, because the class cannot be
+// incomplete.
+struct FriendClass {
+ void friend_method() {}
+};
+void __stdcall friend_stdcall1() {}
+class MakeFriendDecls {
+ int x;
+ friend void FriendClass::friend_method();
+ friend void friend_default();
+ friend void friend_stdcall1();
+ friend void __stdcall friend_stdcall2();
+ friend void friend_stdcall3(); // expected-note {{previous declaration is here}}
+};
+void friend_default() {}
+void __stdcall friend_stdcall3() {} // expected-error {{function declared 'stdcall' here was previously declared without calling convention}}
+void __stdcall friend_stdcall2() {}
+
+// Test functions with multiple attributes.
+void __attribute__((noreturn)) __stdcall __attribute__((regparm(1))) multi_attribute(int x);
+void multi_attribute(int x) { __builtin_unreachable(); }
+
+
+// expected-error@+2 {{stdcall and cdecl attributes are not compatible}}
+// expected-error@+1 {{fastcall and cdecl attributes are not compatible}}
+void __cdecl __cdecl __stdcall __cdecl __fastcall multi_cc(int x);
+
+template <typename T> void __stdcall StdcallTemplate(T) {}
+template <> void StdcallTemplate<int>(int) {}
+template <> void __stdcall StdcallTemplate<short>(short) {}
+
+// FIXME: Note the template, not the implicit instantiation.
+// expected-error@+2 {{function declared 'cdecl' here was previously declared 'stdcall}}
+// expected-note@+1 {{previous declaration is here}}
+template <> void __cdecl StdcallTemplate<long>(long) {}
+
+struct ExactlyInt {
+ template <typename T> static int cast_to_int(T) {
+ return T::this_is_not_an_int();
+ }
+};
+template <> inline int ExactlyInt::cast_to_int<int>(int x) { return x; }
+
+namespace test2 {
+ class foo {
+ template <typename T> void bar(T v);
+ };
+ extern template void foo::bar(const void *);
}
-void __cdecl S::static_member_variadic_default(int x, ...) {
- (void)x;
+namespace test3 {
+ struct foo {
+ typedef void bar();
+ };
+ bool zed(foo::bar *);
+ void bah() {}
+ void baz() { zed(bah); }
}
-void S::static_member_variadic_cdecl(int x, ...) {
- (void)x;
+
+namespace test4 {
+ class foo {
+ template <typename T> static void bar(T v);
+ };
+ extern template void foo::bar(const void *);
}
+namespace test5 {
+ template <class T>
+ class valarray {
+ void bar();
+ };
+ extern template void valarray<int>::bar();
+}
diff --git a/test/SemaCXX/decltype.cpp b/test/SemaCXX/decltype.cpp
index ccde3dc..d6e85d2 100644
--- a/test/SemaCXX/decltype.cpp
+++ b/test/SemaCXX/decltype.cpp
@@ -37,6 +37,14 @@ struct C {
// expected-error {{expected ')'}} expected-note {{to match this '('}}
};
+namespace PR16529 {
+ struct U {};
+ template <typename T> struct S {
+ static decltype(T{}, U{}) &f();
+ };
+ U &r = S<int>::f();
+}
+
template<typename>
class conditional {
};
diff --git a/test/SemaCXX/default-assignment-operator.cpp b/test/SemaCXX/default-assignment-operator.cpp
index 668c600..7ef6f77 100644
--- a/test/SemaCXX/default-assignment-operator.cpp
+++ b/test/SemaCXX/default-assignment-operator.cpp
@@ -1,12 +1,12 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-class Base { // expected-error {{cannot define the implicit default assignment operator for 'Base', because non-static reference member 'ref' can't use default assignment operator}} \
+class Base { // expected-error {{cannot define the implicit copy assignment operator for 'Base', because non-static reference member 'ref' can't use copy assignment operator}} \
// expected-warning{{class 'Base' does not declare any constructor to initialize its non-modifiable members}}
int &ref; // expected-note {{declared here}} \
// expected-note{{reference member 'ref' will never be initialized}}
};
-class X : Base { // // expected-error {{cannot define the implicit default assignment operator for 'X', because non-static const member 'cint' can't use default assignment operator}} \
+class X : Base { // // expected-error {{cannot define the implicit copy assignment operator for 'X', because non-static const member 'cint' can't use copy assignment operator}} \
// expected-note{{assignment operator for 'Base' first required here}}
public:
X();
@@ -73,7 +73,7 @@ void i() {
// Test5
-class E1 { // expected-error{{cannot define the implicit default assignment operator for 'E1', because non-static const member 'a' can't use default assignment operator}}
+class E1 { // expected-error{{cannot define the implicit copy assignment operator for 'E1', because non-static const member 'a' can't use copy assignment operator}}
public:
const int a; // expected-note{{declared here}}
@@ -101,7 +101,7 @@ namespace ProtectedCheck {
X x;
};
- void f(Z z) { z = z; } // expected-note{{implicit default copy assignment operator}}
+ void f(Z z) { z = z; } // expected-note{{implicit copy assignment operator}}
}
diff --git a/test/SemaCXX/default1.cpp b/test/SemaCXX/default1.cpp
index c8c197e..b661776 100644
--- a/test/SemaCXX/default1.cpp
+++ b/test/SemaCXX/default1.cpp
@@ -21,7 +21,7 @@ struct X {
X(int);
};
-void j(X x = 17);
+void j(X x = 17); // expected-note{{'::j' declared here}}
struct Y { // expected-note 2{{candidate}}
explicit Y(int);
@@ -46,8 +46,13 @@ int l () {
int i () {
void j (int f = 4);
{
- void j (int f); // expected-note{{'j' declared here}}
- j(); // expected-error{{too few arguments to function call, single argument 'f' was not specified}}
+ void j (int f);
+ j(); // expected-error{{too few arguments to function call, expected 1, have 0; did you mean '::j'?}}
+ }
+ void jj (int f = 4);
+ {
+ void jj (int f); // expected-note{{'jj' declared here}}
+ jj(); // expected-error{{too few arguments to function call, single argument 'f' was not specified}}
}
}
diff --git a/test/SemaCXX/deprecated.cpp b/test/SemaCXX/deprecated.cpp
new file mode 100644
index 0000000..0335a80
--- /dev/null
+++ b/test/SemaCXX/deprecated.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -std=c++98 %s -Wdeprecated -verify -triple x86_64-linux-gnu
+// RUN: %clang_cc1 -std=c++11 %s -Wdeprecated -verify -triple x86_64-linux-gnu
+// RUN: %clang_cc1 -std=c++1y %s -Wdeprecated -verify -triple x86_64-linux-gnu
+
+// RUN: %clang_cc1 -std=c++1y %s -Wdeprecated -verify -triple x86_64-linux-gnu -Wno-deprecated-register -DNO_DEPRECATED_FLAGS
+
+#include "Inputs/register.h"
+
+void f() throw();
+void g() throw(int);
+void h() throw(...);
+#if __cplusplus >= 201103L
+// expected-warning@-4 {{dynamic exception specifications are deprecated}} expected-note@-4 {{use 'noexcept' instead}}
+// expected-warning@-4 {{dynamic exception specifications are deprecated}} expected-note@-4 {{use 'noexcept(false)' instead}}
+// expected-warning@-4 {{dynamic exception specifications are deprecated}} expected-note@-4 {{use 'noexcept(false)' instead}}
+#endif
+
+void stuff() {
+ register int n;
+#if __cplusplus >= 201103L && !defined(NO_DEPRECATED_FLAGS)
+ // expected-warning@-2 {{'register' storage class specifier is deprecated}}
+#endif
+
+ 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}}
+}
+
+struct S { int n; };
+struct T : private S {
+ S::n;
+#if __cplusplus < 201103L
+ // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
+#else
+ // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
+#endif
+};
+
+#if __cplusplus >= 201103L
+namespace DeprecatedCopy {
+ struct Assign {
+ Assign &operator=(const Assign&); // expected-warning {{definition of implicit copy constructor for 'Assign' is deprecated because it has a user-declared copy assignment operator}}
+ };
+ Assign a1, a2(a1); // expected-note {{implicit copy constructor for 'Assign' first required here}}
+
+ struct Ctor {
+ Ctor();
+ Ctor(const Ctor&); // expected-warning {{definition of implicit copy assignment operator for 'Ctor' is deprecated because it has a user-declared copy constructor}}
+ };
+ Ctor b1, b2;
+ void f() { b1 = b2; } // expected-note {{implicit copy assignment operator for 'Ctor' first required here}}
+
+ struct Dtor {
+ ~Dtor();
+ // expected-warning@-1 {{definition of implicit copy constructor for 'Dtor' is deprecated because it has a user-declared destructor}}
+ // expected-warning@-2 {{definition of implicit copy assignment operator for 'Dtor' is deprecated because it has a user-declared destructor}}
+ };
+ Dtor c1, c2(c1); // expected-note {{implicit copy constructor for 'Dtor' first required here}}
+ void g() { c1 = c2; } // expected-note {{implicit copy assignment operator for 'Dtor' first required here}}
+}
+#endif
diff --git a/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp
index f3c6ab0..e511be0 100644
--- a/test/SemaCXX/destructor.cpp
+++ b/test/SemaCXX/destructor.cpp
@@ -363,3 +363,7 @@ namespace PR7900 {
(&b)->~A(); // expected-error{{destructor type 'PR7900::A' in object destruction expression does not match the type 'PR7900::B' of the object being destroyed}}
}
}
+
+namespace PR16892 {
+ auto p = &A::~A; // expected-error{{taking the address of a destructor}}
+}
diff --git a/test/SemaCXX/dynamic-cast.cpp b/test/SemaCXX/dynamic-cast.cpp
index b73e8c5..b605194 100644
--- a/test/SemaCXX/dynamic-cast.cpp
+++ b/test/SemaCXX/dynamic-cast.cpp
@@ -37,6 +37,8 @@ void basic_bad()
(void)dynamic_cast<Incomplete*>((A*)0); // expected-error {{'Incomplete' is an incomplete type}}
// incomplete -> ptr
(void)dynamic_cast<A*>((Incomplete*)0); // expected-error {{'Incomplete' is an incomplete type}}
+ // rvalue -> lvalue
+ (void)dynamic_cast<A&>(A()); // expected-error {{dynamic_cast from rvalue to reference type 'A &'}}
}
void same()
diff --git a/test/SemaCXX/enum-increment.cpp b/test/SemaCXX/enum-increment.cpp
new file mode 100644
index 0000000..dc1a921
--- /dev/null
+++ b/test/SemaCXX/enum-increment.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify
+
+enum A { A1, A2, A3 };
+void test() {
+ A a;
+ a++; // expected-error{{cannot increment expression of enum type 'A'}}
+ a--; // expected-error{{cannot decrement expression of enum type 'A'}}
+ ++a; // expected-error{{cannot increment expression of enum type 'A'}}
+ --a; // expected-error{{cannot decrement expression of enum type 'A'}}
+}
+
+enum B {B1, B2};
+inline B &operator++ (B &b) { b = B((int)b+1); return b; }
+inline B operator++ (B &b, int) { B ret = b; ++b; return b; }
+
+void foo(enum B b) { ++b; b++; }
diff --git a/test/SemaCXX/enum-scoped.cpp b/test/SemaCXX/enum-scoped.cpp
index d01000d..b4aad18b 100644
--- a/test/SemaCXX/enum-scoped.cpp
+++ b/test/SemaCXX/enum-scoped.cpp
@@ -266,3 +266,33 @@ namespace PR15633 {
struct B { enum class E; };
template<typename T> enum class B::E { e }; // expected-error {{enumeration cannot be a template}}
}
+
+namespace PR16900 {
+ enum class A;
+ A f(A a) { return -a; } // expected-error {{invalid argument type 'PR16900::A' to unary expression}}
+}
+
+namespace rdar15124329 {
+ enum class B : bool { F, T };
+
+ const rdar15124329::B T1 = B::T;
+ typedef B C; const C T2 = B::T;
+
+ static_assert(T1 != B::F, "");
+ static_assert(T2 == B::T, "");
+}
+
+namespace PR18044 {
+ enum class E { a };
+
+ int E::e = 0; // expected-error {{does not refer into a class}}
+ void E::f() {} // expected-error {{does not refer into a class}}
+ struct E::S {}; // expected-error {{no struct named 'S'}}
+ struct T : E::S {}; // expected-error {{expected class name}}
+ enum E::E {}; // expected-error {{no enum named 'E'}}
+ int E::*p; // expected-error {{does not point into a class}}
+ using E::f; // expected-error {{no member named 'f'}}
+
+ using E::a; // ok!
+ E b = a;
+}
diff --git a/test/SemaCXX/enum-unscoped-nonexistent.cpp b/test/SemaCXX/enum-unscoped-nonexistent.cpp
index e9da38f..7da9a96 100644
--- a/test/SemaCXX/enum-unscoped-nonexistent.cpp
+++ b/test/SemaCXX/enum-unscoped-nonexistent.cpp
@@ -6,7 +6,7 @@ struct Base {
template<typename T> struct S : Base {
enum E : int;
constexpr int f() const;
- constexpr int g() const; // expected-note {{declared here}}
+ constexpr int g() const;
void h();
};
template<> enum S<char>::E : int {}; // expected-note {{enum 'S<char>::E' was explicitly specialized here}}
@@ -23,7 +23,7 @@ static_assert(S<int>().f() == 1, "");
// The unqualified-id here names a member of the current instantiation, which
// bizarrely might not exist in some instantiations.
template<typename T> constexpr int S<T>::g() const { return b; } // expected-error {{enumerator 'b' does not exist in instantiation of 'S<char>'}}
-static_assert(S<char>().g() == 1, ""); // expected-note {{here}} expected-error {{not an integral constant expression}} expected-note {{undefined}}
+static_assert(S<char>().g() == 1, ""); // expected-note {{here}} expected-error {{not an integral constant expression}}
static_assert(S<short>().g() == 2, "");
static_assert(S<long>().g() == 8, "");
diff --git a/test/SemaCXX/err_init_conversion_failed.cpp b/test/SemaCXX/err_init_conversion_failed.cpp
new file mode 100644
index 0000000..0652e7a
--- /dev/null
+++ b/test/SemaCXX/err_init_conversion_failed.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void test0() {
+ char variable = (void)0;
+ // expected-error@-1{{cannot initialize a variable}}
+}
+
+void test1(int x = (void)0) {}
+ // expected-error@-1{{cannot initialize a parameter}}
+ // expected-note@-2{{here}}
+
+int test2() {
+ return (void)0;
+ // expected-error@-1{{cannot initialize return object}}
+}
+
+struct S4 {
+ S4() : x((void)0) {};
+ // expected-error@-1{{cannot initialize a member subobject}}
+ int x;
+};
+
+void test5() {
+ int foo[2] = {1, (void)0};
+ // expected-error@-1{{cannot initialize an array element}}
+}
+
+void test6() {
+ new int((void)0);
+ // expected-error@-1{{cannot initialize a new value}}
+}
+
+typedef short short2 __attribute__ ((__vector_size__ (2)));
+void test10() {
+ short2 V = { (void)0 };
+ // expected-error@-1{{cannot initialize a vector element}}
+}
+
+typedef float float2 __attribute__((ext_vector_type(2)));
+typedef float float4 __attribute__((ext_vector_type(4)));
+
+void test14(const float2 in, const float2 out) {
+ const float4 V = (float4){ in, out };
+ // expected-error@-1{{cannot initialize a compound literal initializer}}
+}
diff --git a/test/SemaCXX/explicit.cpp b/test/SemaCXX/explicit.cpp
index 5ce2cf1..1c4d770 100644
--- a/test/SemaCXX/explicit.cpp
+++ b/test/SemaCXX/explicit.cpp
@@ -4,11 +4,11 @@ struct A {
A(int);
};
-struct B {
+struct B { // expected-note+ {{candidate}}
explicit B(int);
};
-B::B(int) { }
+B::B(int) { } // expected-note+ {{here}}
struct C {
void f(const A&);
@@ -18,6 +18,22 @@ struct C {
void f(C c) {
c.f(10);
}
+
+A a0 = 0;
+A a1(0);
+A &&a2 = 0;
+A &&a3(0);
+A a4{0};
+A &&a5 = {0};
+A &&a6{0};
+
+B b0 = 0; // expected-error {{no viable conversion}}
+B b1(0);
+B &&b2 = 0; // expected-error {{could not bind}}
+B &&b3(0); // expected-error {{could not bind}}
+B b4{0};
+B &&b5 = {0}; // expected-error {{chosen constructor is explicit}}
+B &&b6{0};
}
namespace Conversion {
@@ -40,12 +56,11 @@ namespace Conversion {
void testExplicit()
{
// Taken from 12.3.2p2
- class Y { }; // expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Z' to 'const Y &' for 1st argument}} \
- expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Z' to 'Y &&' for 1st argument}} \
- expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Z' to 'const Y &' for 1st argument}} \
- expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Z' to 'Y &&' for 1st argument}}
+ class X { X(); }; // expected-note+ {{candidate constructor}}
+ class Y { }; // expected-note+ {{candidate constructor (the implicit}}
struct Z {
+ explicit operator X() const;
explicit operator Y() const;
explicit operator int() const;
};
@@ -53,6 +68,7 @@ namespace Conversion {
Z z;
// 13.3.1.4p1 & 8.5p16:
Y y2 = z; // expected-error {{no viable conversion from 'Z' to 'Y'}}
+ Y y2b(z);
Y y3 = (Y)z;
Y y4 = Y(z);
Y y5 = static_cast<Y>(z);
@@ -63,7 +79,24 @@ namespace Conversion {
int i4(z);
// 13.3.1.6p1 & 8.5.3p5:
const Y& y6 = z; // expected-error {{no viable conversion from 'Z' to 'const Y'}}
- const int& y7(z);
+ const int& y7 = z; // expected-error {{no viable conversion from 'Z' to 'const int'}}
+ const Y& y8(z);
+ const int& y9(z);
+
+ // Y is an aggregate, so aggregate-initialization is performed and the
+ // conversion function is not considered.
+ const Y y10{z}; // expected-error {{excess elements}}
+ const Y& y11{z}; // expected-error {{no viable conversion from 'Z' to 'const Y'}}
+ const int& y12{z};
+
+ // X is not an aggregate, so constructors are considered.
+ // However, by 13.3.3.1/4, only standard conversion sequences and
+ // ellipsis conversion sequences are considered here, so this is not
+ // allowed.
+ // FIXME: It's not really clear that this is a sensible restriction for this
+ // case. g++ allows this, EDG does not.
+ const X x1{z}; // expected-error {{no matching constructor}}
+ const X& x2{z}; // expected-error {{no matching constructor}}
}
void testBool() {
@@ -119,6 +152,40 @@ namespace Conversion {
// 6.5.3:
for (;b;) {}
for (;n;) {}
+
+ // 13.3.1.5p1:
+ bool direct1(b);
+ bool direct2(n);
+ int direct3(b);
+ int direct4(n); // expected-error {{no viable conversion}}
+ const bool &direct5(b);
+ const bool &direct6(n);
+ const int &direct7(b);
+ const int &direct8(n); // expected-error {{no viable conversion}}
+ bool directList1{b};
+ bool directList2{n};
+ int directList3{b};
+ int directList4{n}; // expected-error {{no viable conversion}}
+ const bool &directList5{b};
+ const bool &directList6{n};
+ const int &directList7{b};
+ const int &directList8{n}; // expected-error {{no viable conversion}}
+ bool copy1 = b;
+ bool copy2 = n; // expected-error {{no viable conversion}}
+ int copy3 = b;
+ int copy4 = n; // expected-error {{no viable conversion}}
+ const bool &copy5 = b;
+ const bool &copy6 = n; // expected-error {{no viable conversion}}
+ const int &copy7 = b;
+ const int &copy8 = n; // expected-error {{no viable conversion}}
+ bool copyList1 = {b};
+ bool copyList2 = {n}; // expected-error {{no viable conversion}}
+ int copyList3 = {b};
+ int copyList4 = {n}; // expected-error {{no viable conversion}}
+ const bool &copyList5 = {b};
+ const bool &copyList6 = {n}; // expected-error {{no viable conversion}}
+ const int &copyList7 = {b};
+ const int &copyList8 = {n}; // expected-error {{no viable conversion}}
}
void testNew()
@@ -145,14 +212,14 @@ namespace Conversion {
operator int*();
};
struct NotPtr {
- explicit operator int*();
+ explicit operator int*(); // expected-note {{conversion}}
};
Ptr p;
NotPtr np;
delete p;
- delete np; // expected-error {{cannot delete expression of type 'NotPtr'}}
+ delete np; // expected-error {{converting delete expression from type 'NotPtr' to type 'int *' invokes an explicit conversion function}}
}
void testFunctionPointer()
@@ -173,3 +240,9 @@ namespace Conversion {
nfp(1); // expected-error {{type 'NotFP' does not provide a call operator}}
}
}
+
+namespace pr8264 {
+ struct Test {
+ explicit explicit Test(int x); // expected-warning{{duplicate 'explicit' declaration specifier}}
+ };
+}
diff --git a/test/SemaCXX/expression-traits.cpp b/test/SemaCXX/expression-traits.cpp
index 2767d4a..3a00687 100644
--- a/test/SemaCXX/expression-traits.cpp
+++ b/test/SemaCXX/expression-traits.cpp
@@ -189,12 +189,12 @@ struct Class : BaseClass
static int& NestedFuncTemplate() { return variable; } // expected-note{{possible target for call}}
template <class T>
- int& NestedMemfunTemplate() { return variable; }
+ int& NestedMemfunTemplate() { return variable; } // expected-note{{possible target for call}}
int operator*() const;
template <class T>
- int operator+(T) const;
+ int operator+(T) const; // expected-note{{possible target for call}}
int NonstaticMemberFunction();
static int StaticMemberFunction();
diff --git a/test/SemaCXX/extern-c.cpp b/test/SemaCXX/extern-c.cpp
index c55b10d..dfbf386 100644
--- a/test/SemaCXX/extern-c.cpp
+++ b/test/SemaCXX/extern-c.cpp
@@ -2,25 +2,25 @@
namespace test1 {
extern "C" {
- void f() {
- void test1_g(int); // expected-note {{previous declaration is here}}
+ void test1_f() {
+ void test1_g(int);
}
}
}
-int test1_g(int); // expected-error {{functions that differ only in their return type cannot be overloaded}}
+int test1_g(int);
namespace test2 {
extern "C" {
- void f() {
- extern int test2_x; // expected-note {{previous definition is here}}
+ void test2_f() {
+ extern int test2_x; // expected-note {{declared with C language linkage here}}
}
}
}
-float test2_x; // expected-error {{redefinition of 'test2_x' with a different type: 'float' vs 'int'}}
+float test2_x; // expected-error {{declaration of 'test2_x' in global scope conflicts with declaration with C language linkage}}
namespace test3 {
extern "C" {
- void f() {
+ void test3_f() {
extern int test3_b; // expected-note {{previous definition is here}}
}
}
@@ -29,20 +29,40 @@ namespace test3 {
}
}
+namespace N {
+ extern "C" {
+ void test4_f() {
+ extern int test4_b; // expected-note {{declared with C language linkage here}}
+ }
+ }
+}
+static float test4_b; // expected-error {{declaration of 'test4_b' in global scope conflicts with declaration with C language linkage}}
+
extern "C" {
- void test4_f() {
- extern int test4_b; // expected-note {{previous definition is here}}
+ void test4c_f() {
+ extern int test4_c; // expected-note {{previous}}
+ }
+}
+static float test4_c; // expected-error {{redefinition of 'test4_c' with a different type: 'float' vs 'int'}}
+
+namespace N {
+ extern "C" {
+ void test5_f() {
+ extern int test5_b; // expected-note {{declared with C language linkage here}}
+ }
}
}
-static float test4_b; // expected-error {{redefinition of 'test4_b' with a different type: 'float' vs 'int'}}
+extern "C" {
+ static float test5_b; // expected-error {{declaration of 'test5_b' in global scope conflicts with declaration with C language linkage}}
+}
extern "C" {
- void test5_f() {
- extern int test5_b; // expected-note {{previous definition is here}}
+ void test5c_f() {
+ extern int test5_c; // expected-note {{previous}}
}
}
extern "C" {
- static float test5_b; // expected-error {{redefinition of 'test5_b' with a different type: 'float' vs 'int'}}
+ static float test5_c; // expected-error {{redefinition of 'test5_c' with a different type: 'float' vs 'int'}}
}
extern "C" {
@@ -56,3 +76,131 @@ namespace foo {
extern float test6_b;
}
}
+
+namespace linkage {
+ namespace redecl {
+ extern "C" {
+ static void linkage_redecl();
+ static void linkage_redecl(int);
+ void linkage_redecl(); // ok, still not extern "C"
+ void linkage_redecl(int); // ok, still not extern "C"
+ void linkage_redecl(float); // expected-note {{previous}}
+ void linkage_redecl(double); // expected-error {{conflicting types}}
+ }
+ }
+ namespace from_outer {
+ void linkage_from_outer_1(); // expected-note {{previous}}
+ void linkage_from_outer_2(); // expected-note {{previous}}
+ extern "C" {
+ void linkage_from_outer_1(int);
+ void linkage_from_outer_1(); // expected-error {{different language linkage}}
+ void linkage_from_outer_2(); // expected-error {{different language linkage}}
+ }
+ }
+ namespace mixed {
+ extern "C" {
+ void linkage_mixed_1();
+ static void linkage_mixed_1(int);
+
+ static void linkage_mixed_2(int);
+ void linkage_mixed_2();
+ }
+ }
+ namespace across_scopes {
+ namespace X {
+ extern "C" void linkage_across_scopes_f() {
+ void linkage_across_scopes_g(); // expected-note {{previous}}
+ }
+ }
+ namespace Y {
+ extern "C" void linkage_across_scopes_g(int); // expected-error {{conflicting}}
+ }
+ }
+}
+
+int lookup_in_global_f; // expected-note {{here}}
+namespace lookup_in_global {
+ void lookup_in_global_f();
+ void lookup_in_global_g();
+ extern "C" {
+ void lookup_in_global_f(int); // expected-error {{conflicts with declaration in global scope}}
+ void lookup_in_global_g(int); // expected-note {{here}}
+ }
+}
+int lookup_in_global_g; // expected-error {{conflicts with declaration with C language linkage}}
+
+namespace N1 {
+ extern "C" int different_kind_1; // expected-note {{here}}
+ extern "C" void different_kind_2(); // expected-note {{here}}
+}
+namespace N2 {
+ extern "C" void different_kind_1(); // expected-error {{different kind of symbol}}
+ extern "C" int different_kind_2; // expected-error {{different kind of symbol}}
+}
+
+// We allow all these even though the standard says they are ill-formed.
+extern "C" {
+ struct stat {}; // expected-warning{{empty struct has size 0 in C, size 1 in C++}}
+ void stat(struct stat);
+}
+namespace X {
+ extern "C" {
+ void stat(struct ::stat);
+ }
+}
+int stat(int *p);
+void global_fn_vs_extern_c_var_1();
+namespace X {
+ extern "C" int global_fn_vs_extern_c_var_1;
+ extern "C" int global_fn_vs_extern_c_var_2;
+}
+void global_fn_vs_extern_c_var_2();
+void global_fn_vs_extern_c_fn_1();
+namespace X {
+ extern "C" int global_fn_vs_extern_c_fn_1(int);
+ extern "C" int global_fn_vs_extern_c_fn_2(int);
+}
+void global_fn_vs_extern_c_fn_2();
+extern "C" void name_with_using_decl_1(int);
+namespace using_decl {
+ void name_with_using_decl_1();
+ void name_with_using_decl_2();
+ void name_with_using_decl_3();
+}
+using using_decl::name_with_using_decl_1;
+using using_decl::name_with_using_decl_2;
+extern "C" void name_with_using_decl_2(int);
+extern "C" void name_with_using_decl_3(int);
+using using_decl::name_with_using_decl_3;
+
+// We do not allow a global variable and an extern "C" function to have the same
+// name, because such entities may have the same mangled name.
+int global_var_vs_extern_c_fn_1; // expected-note {{here}}
+namespace X {
+ extern "C" void global_var_vs_extern_c_fn_1(); // expected-error {{conflicts with declaration in global scope}}
+ extern "C" void global_var_vs_extern_c_fn_2(); // expected-note {{here}}
+}
+int global_var_vs_extern_c_fn_2; // expected-error {{conflicts with declaration with C language linkage}}
+int global_var_vs_extern_c_var_1; // expected-note {{here}}
+namespace X {
+ extern "C" double global_var_vs_extern_c_var_1; // expected-error {{conflicts with declaration in global scope}}
+ extern "C" double global_var_vs_extern_c_var_2; // expected-note {{here}}
+}
+int global_var_vs_extern_c_var_2; // expected-error {{conflicts with declaration with C language linkage}}
+
+template <class T> struct pr5065_n1 {};
+extern "C" {
+ union pr5065_1 {}; // expected-warning{{empty union has size 0 in C, size 1 in C++}}
+ struct pr5065_2 { int: 0; }; // expected-warning{{struct has size 0 in C, size 1 in C++}}
+ struct pr5065_3 {}; // expected-warning{{empty struct has size 0 in C, size 1 in C++}}
+ struct pr5065_4 { // expected-warning{{empty struct has size 0 in C, size 1 in C++}}
+ struct Inner {}; // expected-warning{{empty struct has size 0 in C, size 1 in C++}}
+ };
+ // These should not warn
+ class pr5065_n3 {};
+ pr5065_n1<int> pr5065_v;
+ struct pr5065_n4 { void m() {} };
+ struct pr5065_n5 : public pr5065_3 {};
+ struct pr5065_n6 : public virtual pr5065_3 {};
+}
+struct pr5065_n7 {};
diff --git a/test/SemaCXX/flexible-array-test.cpp b/test/SemaCXX/flexible-array-test.cpp
index e6c3132..f287711 100644
--- a/test/SemaCXX/flexible-array-test.cpp
+++ b/test/SemaCXX/flexible-array-test.cpp
@@ -66,4 +66,8 @@ struct Storage : StorageBase {
int data[];
};
+struct VirtStorage : virtual StorageBase {
+ int data[]; // expected-error {{flexible array member 'data' not allowed in struct which has a virtual base class}}
+};
+
}
diff --git a/test/SemaCXX/for-range-examples.cpp b/test/SemaCXX/for-range-examples.cpp
index 953c98b..b3cf9c3 100644
--- a/test/SemaCXX/for-range-examples.cpp
+++ b/test/SemaCXX/for-range-examples.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
namespace value_range_detail {
template<typename T>
@@ -180,3 +180,32 @@ namespace test4 {
for (y : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}}
}
}
+
+namespace test5 {
+ // Test error-recovery.
+ void f() {
+ for (auto x : undeclared_identifier) // expected-error {{undeclared identifier}}
+ for (auto y : x->foo)
+ y->bar();
+ for (auto x : 123) // expected-error {{no viable 'begin'}}
+ x->foo();
+ }
+}
+
+namespace test6 {
+ void foo(int arr[]) { // expected-note {{declared here}}
+ for (auto i : arr) { }
+ // expected-error@-1 {{cannot build range expression with array function parameter 'arr' since parameter with array type 'int []' is treated as pointer type 'int *'}}
+ }
+
+ struct vector {
+ int *begin() { return 0; }
+ int *end() { return 0; }
+ };
+
+ void foo(vector arr[]) { // expected-note {{declared here}}
+ // Don't suggest to dereference arr.
+ for (auto i : arr) { }
+ // 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 *'}}
+ }
+}
diff --git a/test/SemaCXX/format-strings-0x.cpp b/test/SemaCXX/format-strings-0x.cpp
index 7b3aef1..7e41c7f 100644
--- a/test/SemaCXX/format-strings-0x.cpp
+++ b/test/SemaCXX/format-strings-0x.cpp
@@ -24,4 +24,8 @@ void f(char **sp, float *fp) {
\u1234\U0010fffe
%d)foo" // expected-warning {{more '%' conversions than data arguments}}
);
+
+ printf("init list: %d", { 0 }); // expected-error {{cannot pass initializer list to variadic function; expected type from format string was 'int'}}
+ printf("void: %d", f(sp, fp)); // expected-error {{cannot pass expression of type 'void' to variadic function; expected type from format string was 'int'}}
+ printf(0, { 0 }); // expected-error {{cannot pass initializer list to variadic function}}
}
diff --git a/test/SemaCXX/friend.cpp b/test/SemaCXX/friend.cpp
index b401a06..aed2ab2 100644
--- a/test/SemaCXX/friend.cpp
+++ b/test/SemaCXX/friend.cpp
@@ -44,7 +44,7 @@ namespace test2 {
// PR5134
namespace test3 {
class Foo {
- friend const int getInt(int inInt = 0);
+ friend const int getInt(int inInt = 0) {}
};
}
@@ -134,7 +134,7 @@ namespace test6_3 {
namespace test7 {
extern "C" {
class X {
- friend int f() { return 42; }
+ friend int test7_f() { return 42; }
};
}
}
@@ -154,3 +154,137 @@ namespace test8 {
friend void B::f(); // expected-error {{cannot befriend target of using declaration}}
};
}
+
+// PR16423
+namespace test9 {
+ class C {
+ };
+ struct A {
+ friend void C::f(int, int, int) {} // expected-error {{no function named 'f' with type 'void (int, int, int)' was found in the specified scope}}
+ };
+}
+
+namespace test10 {
+ struct X {};
+ extern void f10_a();
+ extern void f10_a(X);
+ struct A {
+ friend void f10_a();
+ friend void f10_b();
+ friend void f10_c();
+ friend void f10_d();
+ friend void f10_a(X);
+ friend void f10_b(X);
+ friend void f10_c(X);
+ friend void f10_d(X);
+ };
+ extern void f10_b();
+ extern void f10_b(X);
+ struct B {
+ friend void f10_a();
+ friend void f10_b();
+ friend void f10_c();
+ friend void f10_d();
+ friend void f10_a(X);
+ friend void f10_b(X);
+ friend void f10_c(X);
+ friend void f10_d(X);
+ };
+ extern void f10_c();
+ extern void f10_c(X);
+
+ // FIXME: Give a better diagnostic for the case where a function exists but is
+ // not visible.
+ void g(X x) {
+ f10_a();
+ f10_b();
+ f10_c();
+ f10_d(); // expected-error {{undeclared identifier}}
+
+ ::test10::f10_a();
+ ::test10::f10_b();
+ ::test10::f10_c();
+ ::test10::f10_d(); // expected-error {{no member named 'f10_d'}}
+
+ f10_a(x);
+ f10_b(x);
+ f10_c(x);
+ f10_d(x); // PR16597: expected-error {{undeclared identifier}}
+
+ ::test10::f10_a(x);
+ ::test10::f10_b(x);
+ ::test10::f10_c(x);
+ ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}}
+ }
+
+ struct Y : X {
+ friend void f10_d();
+ friend void f10_d(X);
+ };
+
+ struct Z {
+ operator X();
+ friend void f10_d();
+ friend void f10_d(X);
+ };
+
+ void g(X x, Y y, Z z) {
+ f10_d(); // expected-error {{undeclared identifier}}
+ ::test10::f10_d(); // expected-error {{no member named 'f10_d'}}
+
+ // f10_d is visible to ADL in the second and third cases.
+ f10_d(x); // expected-error {{undeclared identifier}}
+ f10_d(y);
+ f10_d(z);
+
+ // No ADL here.
+ ::test10::f10_d(x); // expected-error {{no type named 'f10_d'}}
+ ::test10::f10_d(y); // expected-error {{no type named 'f10_d'}}
+ ::test10::f10_d(z); // expected-error {{no type named 'f10_d'}}
+ }
+
+ void local_externs(X x, Y y) {
+ extern void f10_d();
+ extern void f10_d(X);
+ f10_d();
+ f10_d(x);
+ // FIXME: This lookup should fail, because the local extern declaration
+ // should suppress ADL.
+ f10_d(y);
+ {
+ int f10_d;
+ f10_d(); // expected-error {{not a function}}
+ f10_d(x); // expected-error {{not a function}}
+ f10_d(y); // expected-error {{not a function}}
+ }
+ }
+
+ void i(X x, Y y) {
+ f10_d(); // expected-error {{undeclared identifier}}
+ f10_d(x); // expected-error {{undeclared identifier}}
+ f10_d(y);
+ }
+
+ struct C {
+ friend void f10_d();
+ friend void f10_d(X);
+ };
+
+ void j(X x, Y y) {
+ f10_d(); // expected-error {{undeclared identifier}}
+ f10_d(x); // expected-error {{undeclared identifier}}
+ f10_d(y);
+ }
+
+ extern void f10_d();
+ extern void f10_d(X);
+ void k(X x, Y y, Z z) {
+ // All OK now.
+ f10_d();
+ f10_d(x);
+ ::test10::f10_d();
+ ::test10::f10_d(x);
+ ::test10::f10_d(y);
+ ::test10::f10_d(z);
+ }
+}
diff --git a/test/SemaCXX/function-pointer-arguments.cpp b/test/SemaCXX/function-pointer-arguments.cpp
new file mode 100644
index 0000000..9f3fb0a
--- /dev/null
+++ b/test/SemaCXX/function-pointer-arguments.cpp
@@ -0,0 +1,52 @@
+//RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace PR16570 {
+ int f1(int, int);
+ int f2(const int, int);
+ int f3(int&, int);
+ int f4(const int&, int);
+
+ void good() {
+ int(*g1)(int, int) = f1;
+ int(*g2)(const int, int) = f1;
+ int(*g3)(volatile int, int) = f1;
+ int(*g4)(int, int) = f2;
+ int(*g5)(const int, int) = f2;
+ int(*g6)(volatile int, int) = f2;
+ int(*g7)(int&, int) = f3;
+ int(*g8)(const int&, int) = f4;
+ }
+
+ void bad() {
+ void (*g1)(int, int) = f1;
+ // expected-error@-1 {{different return type ('void' vs 'int'}}
+ const int (*g2)(int, int) = f1;
+ // expected-error@-1 {{different return type ('const int' vs 'int')}}
+
+ int (*g3)(char, int) = f1;
+ // expected-error@-1 {{type mismatch at 1st parameter ('char' vs 'int')}}
+ int (*g4)(int, char) = f1;
+ // expected-error@-1 {{type mismatch at 2nd parameter ('char' vs 'int')}}
+
+ int (*g5)(int) = f1;
+ // expected-error@-1 {{different number of parameters (1 vs 2)}}
+
+ int (*g6)(int, int, int) = f1;
+ // expected-error@-1 {{different number of parameters (3 vs 2)}}
+
+ int (*g7)(const int, char) = f1;
+ // expected-error@-1 {{type mismatch at 2nd parameter ('char' vs 'int')}}
+ int (*g8)(int, char) = f2;
+ // expected-error@-1 {{type mismatch at 2nd parameter ('char' vs 'int')}}
+ int (*g9)(const int&, char) = f3;
+ // expected-error@-1 {{type mismatch at 1st parameter ('const int &' vs 'int &')}}
+ int (*g10)(int&, char) = f4;
+ // expected-error@-1 {{type mismatch at 1st parameter ('int &' vs 'const int &')}}
+ }
+
+ typedef void (*F)(const char * __restrict__, int);
+ void g(const char *, unsigned);
+ F f = g;
+ // expected-error@-1 {{type mismatch at 2nd parameter ('int' vs 'unsigned int')}}
+
+}
diff --git a/test/SemaCXX/function-redecl.cpp b/test/SemaCXX/function-redecl.cpp
index b9d1f23..2bc0d90 100644
--- a/test/SemaCXX/function-redecl.cpp
+++ b/test/SemaCXX/function-redecl.cpp
@@ -4,22 +4,24 @@ int foo(int);
namespace N {
void f1() {
void foo(int); // okay
+ void bar(int); // expected-note 2{{previous declaration is here}}
}
- // FIXME: we shouldn't even need this declaration to detect errors
- // below.
- void foo(int); // expected-note{{previous declaration is here}}
+ void foo(int); // expected-note 2{{previous declaration is here}}
void f2() {
- int foo(int); // expected-error{{functions that differ only in their return type cannot be overloaded}}
+ int foo(int); // expected-error {{functions that differ only in their return type cannot be overloaded}}
+ int bar(int); // expected-error {{functions that differ only in their return type cannot be overloaded}}
+ int baz(int); // expected-note {{previous declaration is here}}
{
int foo;
+ int bar;
+ int baz;
{
- // FIXME: should diagnose this because it's incompatible with
- // N::foo. However, name lookup isn't properly "skipping" the
- // "int foo" above.
- float foo(int);
+ float foo(int); // expected-error {{functions that differ only in their return type cannot be overloaded}}
+ float bar(int); // expected-error {{functions that differ only in their return type cannot be overloaded}}
+ float baz(int); // expected-error {{functions that differ only in their return type cannot be overloaded}}
}
}
}
diff --git a/test/SemaCXX/function-type-qual.cpp b/test/SemaCXX/function-type-qual.cpp
index ccb5747..613ac9b 100644
--- a/test/SemaCXX/function-type-qual.cpp
+++ b/test/SemaCXX/function-type-qual.cpp
@@ -29,3 +29,11 @@ cfn C::*mpg;
// Don't crash!
void (PR14171)() const; // expected-error {{non-member function cannot have 'const' qualifier}}
+
+// Test template instantiation of decayed array types. Not really related to
+// type quals.
+template <typename T> void arrayDecay(const T a[]) { }
+void instantiateArrayDecay() {
+ int a[1];
+ arrayDecay(a);
+}
diff --git a/test/SemaCXX/gnu-flags.cpp b/test/SemaCXX/gnu-flags.cpp
new file mode 100644
index 0000000..05770c5
--- /dev/null
+++ b/test/SemaCXX/gnu-flags.cpp
@@ -0,0 +1,76 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DNONE -Wno-gnu
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DALL -Wgnu
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DALL -Wno-gnu \
+// RUN: -Wgnu-anonymous-struct -Wredeclared-class-member \
+// RUN: -Wgnu-flexible-array-union-member -Wgnu-folding-constant \
+// RUN: -Wgnu-empty-struct
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DNONE -Wgnu \
+// RUN: -Wno-gnu-anonymous-struct -Wno-redeclared-class-member \
+// RUN: -Wno-gnu-flexible-array-union-member -Wno-gnu-folding-constant \
+// RUN: -Wno-gnu-empty-struct
+// Additional disabled tests:
+// %clang_cc1 -fsyntax-only -verify %s -DANONYMOUSSTRUCT -Wno-gnu -Wgnu-anonymous-struct
+// %clang_cc1 -fsyntax-only -verify %s -DREDECLAREDCLASSMEMBER -Wno-gnu -Wredeclared-class-member
+// %clang_cc1 -fsyntax-only -verify %s -DFLEXIBLEARRAYUNIONMEMBER -Wno-gnu -Wgnu-flexible-array-union-member
+// %clang_cc1 -fsyntax-only -verify %s -DFOLDINGCONSTANT -Wno-gnu -Wgnu-folding-constant
+// %clang_cc1 -fsyntax-only -verify %s -DEMPTYSTRUCT -Wno-gnu -Wgnu-empty-struct
+
+#if NONE
+// expected-no-diagnostics
+#endif
+
+
+#if ALL || ANONYMOUSSTRUCT
+// expected-warning@+5 {{anonymous structs are a GNU extension}}
+#endif
+
+struct as {
+ int x;
+ struct {
+ int a;
+ float b;
+ };
+};
+
+
+#if ALL || REDECLAREDCLASSMEMBER
+// expected-note@+6 {{previous declaration is here}}
+// expected-warning@+6 {{class member cannot be redeclared}}
+#endif
+
+namespace rcm {
+ class A {
+ class X;
+ class X;
+ class X {};
+ };
+}
+
+
+#if ALL || FLEXIBLEARRAYUNIONMEMBER
+// expected-warning@+6 {{flexible array member 'c1' in a union is a GNU extension}}
+#endif
+
+struct faum {
+ int l;
+ union {
+ int c1[];
+ };
+};
+
+
+#if ALL || FOLDINGCONSTANT
+// expected-warning@+4 {{in-class initializer for static data member is not a constant expression; folding it to a constant is a GNU extension}}
+#endif
+
+struct fic {
+ static const int B = int(0.75 * 1000 * 1000);
+};
+
+
+#if ALL || EMPTYSTRUCT
+// expected-warning@+3 {{flexible array member 'a' in otherwise empty struct is a GNU extension}}
+#endif
+
+struct ofam {int a[];};
+
diff --git a/test/SemaCXX/i-c-e-cxx.cpp b/test/SemaCXX/i-c-e-cxx.cpp
index c80323c..39c6b1f 100644
--- a/test/SemaCXX/i-c-e-cxx.cpp
+++ b/test/SemaCXX/i-c-e-cxx.cpp
@@ -16,7 +16,7 @@ void f() {
}
int a() {
- const int t=t; // expected-note {{declared here}}
+ const int t=t; // expected-note {{declared here}} expected-note {{read of object outside its lifetime}}
switch(1) { // expected-warning {{no case matching constant switch condition '1'}}
case t:; // expected-error {{not an integral constant expression}} expected-note {{initializer of 't' is not a constant expression}}
}
diff --git a/test/SemaCXX/implicit-virtual-member-functions.cpp b/test/SemaCXX/implicit-virtual-member-functions.cpp
index f6082e5..cd547f5 100644
--- a/test/SemaCXX/implicit-virtual-member-functions.cpp
+++ b/test/SemaCXX/implicit-virtual-member-functions.cpp
@@ -9,7 +9,7 @@ struct B : A { // expected-error {{no suitable member 'operator delete' in 'B'}}
void operator delete (void *, int); // expected-note {{'operator delete' declared here}}
};
-void B::f() { // expected-note {{implicit default destructor for 'B' first required here}}
+void B::f() { // expected-note {{implicit destructor for 'B' first required here}}
}
struct C : A { // expected-error {{no suitable member 'operator delete' in 'C'}}
@@ -17,13 +17,13 @@ struct C : A { // expected-error {{no suitable member 'operator delete' in 'C'}}
void operator delete(void *, int); // expected-note {{'operator delete' declared here}}
};
-C::C() { } // expected-note {{implicit default destructor for 'C' first required here}}
+C::C() { } // expected-note {{implicit destructor for 'C' first required here}}
struct D : A { // expected-error {{no suitable member 'operator delete' in 'D'}}
void operator delete(void *, int); // expected-note {{'operator delete' declared here}}
};
void f() {
- new D; // expected-note {{implicit default destructor for 'D' first required here}}
+ new D; // expected-note {{implicit destructor for 'D' first required here}}
}
diff --git a/test/SemaCXX/inherit.cpp b/test/SemaCXX/inherit.cpp
index a926c81..abeed9a 100644
--- a/test/SemaCXX/inherit.cpp
+++ b/test/SemaCXX/inherit.cpp
@@ -30,3 +30,6 @@ typedef G_copy G_copy_3;
class H : G_copy, A, G_copy_2, // expected-error{{base class 'G_copy' (aka 'G') specified more than once as a direct base class}}
public G_copy_3 { }; // expected-error{{base class 'G_copy' (aka 'G') specified more than once as a direct base class}}
+
+struct J { char c; int i[]; };
+struct K : J { }; // expected-error{{base class 'J' has a flexible array member}}
diff --git a/test/SemaCXX/init-priority-attr.cpp b/test/SemaCXX/init-priority-attr.cpp
index 6facebf..a91eb60 100644
--- a/test/SemaCXX/init-priority-attr.cpp
+++ b/test/SemaCXX/init-priority-attr.cpp
@@ -19,11 +19,11 @@ extern Two koo[];
Two foo __attribute__((init_priority(101))) ( 5, 6 );
-Two goo __attribute__((init_priority(2,3))) ( 5, 6 ); // expected-error {{attribute takes one argument}}
+Two goo __attribute__((init_priority(2,3))) ( 5, 6 ); // expected-error {{'init_priority' attribute takes one argument}}
Two coo[2] __attribute__((init_priority(3))); // expected-error {{init_priority attribute requires integer constant between 101 and 65535 inclusive}}
-Two koo[4] __attribute__((init_priority(1.13))); // expected-error {{'init_priority' attribute requires integer constant}}
+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}}
diff --git a/test/SemaCXX/lambda-expressions.cpp b/test/SemaCXX/lambda-expressions.cpp
index a333f38..e290424 100644
--- a/test/SemaCXX/lambda-expressions.cpp
+++ b/test/SemaCXX/lambda-expressions.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -std=c++0x -Wno-unused-value -fsyntax-only -verify -fblocks %s
+// RUN: %clang_cc1 -std=c++11 -Wno-unused-value -fsyntax-only -verify -fblocks %s
+// RUN: %clang_cc1 -std=c++1y -Wno-unused-value -fsyntax-only -verify -fblocks %s
namespace std { class type_info; };
@@ -109,27 +110,30 @@ namespace PR12031 {
}
}
-namespace NullPtr {
+namespace Array {
int &f(int *p);
char &f(...);
void g() {
- int n = 0;
+ int n = -1;
[=] {
- char &k = f(n); // not a null pointer constant
+ int arr[n]; // VLA
} ();
- const int m = 0;
- [=] {
- int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
+ const int m = -1;
+ [] {
+ int arr[m]; // expected-error{{negative size}}
} ();
- [=] () -> bool {
- int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
- return &m == 0;
+ [&] {
+ int arr[m]; // expected-error{{negative size}}
+ } ();
+
+ [=] {
+ int arr[m]; // expected-error{{negative size}}
} ();
[m] {
- int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
+ int arr[m]; // expected-error{{negative size}}
} ();
}
}
@@ -240,3 +244,42 @@ namespace PR13854 {
namespace PR14518 {
auto f = [](void) { return __func__; }; // no-warning
}
+
+namespace PR16708 {
+ auto L = []() {
+ auto ret = 0;
+ return ret;
+ return 0;
+ };
+}
+
+namespace TypeDeduction {
+ struct S {};
+ void f() {
+ const S s {};
+ S &&t = [&] { return s; } ();
+#if __cplusplus <= 201103L
+ // expected-error@-2 {{drops qualifiers}}
+#else
+ S &&u = [&] () -> auto { return s; } ();
+#endif
+ }
+}
+
+
+namespace lambdas_in_NSDMIs {
+ template<class T>
+ struct L {
+ T t{};
+ T t2 = ([](int a) { return [](int b) { return b; };})(t)(t);
+ };
+ L<int> l;
+
+ namespace non_template {
+ struct L {
+ int t = 0;
+ int t2 = ([](int a) { return [](int b) { return b; };})(t)(t);
+ };
+ L l;
+ }
+} \ No newline at end of file
diff --git a/test/SemaCXX/libstdcxx_pointer_return_false_hack.cpp b/test/SemaCXX/libstdcxx_pointer_return_false_hack.cpp
new file mode 100644
index 0000000..17e1548
--- /dev/null
+++ b/test/SemaCXX/libstdcxx_pointer_return_false_hack.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify
+
+// This is a test for an egregious hack in Clang that works around
+// an issue with libstdc++-4.2's <tr1/hashtable> implementation.
+// The code in question returns 'false' from a function with a pointer
+// return type, which is ill-formed in C++11.
+
+#ifdef BE_THE_HEADER
+
+#pragma GCC system_header
+namespace std {
+ namespace tr1 {
+ template<typename T> struct hashnode;
+ template<typename T> struct hashtable {
+ typedef hashnode<T> node;
+ node *find_node() {
+ // This is ill-formed in C++11, per core issue 903, but we accept
+ // it anyway in a system header.
+ return false;
+ }
+ };
+ }
+}
+
+#else
+
+#define BE_THE_HEADER
+#include "libstdcxx_pointer_return_false_hack.cpp"
+
+auto *test1 = std::tr1::hashtable<int>().find_node();
+
+void *test2() { return false; } // expected-error {{cannot initialize}}
+
+#endif
diff --git a/test/SemaCXX/linkage-spec.cpp b/test/SemaCXX/linkage-spec.cpp
index 504df0d..1598d0e 100644
--- a/test/SemaCXX/linkage-spec.cpp
+++ b/test/SemaCXX/linkage-spec.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wretained-language-linkage -DW_RETAINED_LANGUAGE_LINKAGE %s
extern "C" {
extern "C" void f(int);
}
@@ -41,7 +42,7 @@ namespace pr5430 {
using namespace pr5430;
extern "C" void pr5430::func(void) { }
-// PR5404
+// PR5405
int f2(char *)
{
return 0;
@@ -55,6 +56,18 @@ extern "C"
}
}
+namespace PR5405 {
+ int f2b(char *) {
+ return 0;
+ }
+
+ extern "C" {
+ int f2b(int) {
+ return f2b((char *)0); // ok
+ }
+ }
+}
+
// PR6991
extern "C" typedef int (*PutcFunc_t)(int);
@@ -114,3 +127,49 @@ namespace pr14958 {
}
int js::ObjectClass;
}
+
+extern "C" void PR16167; // expected-error {{variable has incomplete type 'void'}}
+extern void PR16167_0; // expected-error {{variable has incomplete type 'void'}}
+
+// PR7927
+enum T_7927 {
+ E_7927
+};
+
+extern "C" void f_pr7927(int);
+
+namespace {
+ extern "C" void f_pr7927(int);
+
+ void foo_pr7927() {
+ f_pr7927(E_7927);
+ f_pr7927(0);
+ ::f_pr7927(E_7927);
+ ::f_pr7927(0);
+ }
+}
+
+void bar_pr7927() {
+ f_pr7927(E_7927);
+ f_pr7927(0);
+ ::f_pr7927(E_7927);
+ ::f_pr7927(0);
+}
+
+namespace PR17337 {
+ extern "C++" {
+ class Foo;
+ extern "C" int bar3(Foo *y);
+ class Foo {
+ int x;
+ friend int bar3(Foo *y);
+#ifdef W_RETAINED_LANGUAGE_LINKAGE
+// expected-note@-5 {{previous declaration is here}}
+// expected-warning@-3 {{retaining previous language linkage}}
+#endif
+ };
+ extern "C" int bar3(Foo *y) {
+ return y->x;
+ }
+ }
+}
diff --git a/test/SemaCXX/linkage2.cpp b/test/SemaCXX/linkage2.cpp
index 3cfa981..075f5e7 100644
--- a/test/SemaCXX/linkage2.cpp
+++ b/test/SemaCXX/linkage2.cpp
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -fsyntax-only -verify -fmodules %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=gnu++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++11-extensions -Wno-local-type-template-args %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++11-extensions -Wno-local-type-template-args -fmodules %s
namespace test1 {
int x; // expected-note {{previous definition is here}}
@@ -65,7 +66,7 @@ namespace test6 {
get_future();
template <class _Rp>
struct shared_future<_Rp&> {
- shared_future(future<_Rp&>&& __f); // expected-warning {{rvalue references are a C++11 extension}}
+ shared_future(future<_Rp&>&& __f);
};
void f() {
typedef int T;
@@ -164,3 +165,51 @@ namespace test16 {
}
}
}
+
+namespace test17 {
+ namespace {
+ struct I {
+ };
+ }
+ template <typename T1, typename T2> void foo() {}
+ template <typename T, T x> void bar() {} // expected-note {{candidate function}}
+ inline void *g() {
+ struct L {
+ };
+ // foo<L, I>'s linkage should be the merge of UniqueExternalLinkage (or
+ // InternalLinkage in c++11) and VisibleNoLinkage. The correct answer is
+ // NoLinkage in both cases. This means that using foo<L, I> as a template
+ // argument should fail.
+ return reinterpret_cast<void*>(bar<typeof(foo<L, I>), foo<L, I> >); // expected-error {{reinterpret_cast cannot resolve overloaded function 'bar' to type 'void *}}
+ }
+ void h() {
+ g();
+ }
+}
+
+namespace test18 {
+ template <typename T> struct foo {
+ template <T *P> static void f() {}
+ static void *g() { return (void *)f<&x>; }
+ static T x;
+ };
+ template <typename T> T foo<T>::x;
+ inline void *f() {
+ struct S {
+ };
+ return foo<S>::g();
+ }
+ void *h() { return f(); }
+}
+
+extern "C" void pr16247_foo(int);
+static void pr16247_foo(double);
+void pr16247_foo(int) {}
+void pr16247_foo(double) {}
+
+namespace PR16247 {
+ extern "C" void pr16247_bar(int);
+ static void pr16247_bar(double);
+ void pr16247_bar(int) {}
+ void pr16247_bar(double) {}
+}
diff --git a/test/SemaCXX/member-expr.cpp b/test/SemaCXX/member-expr.cpp
index 515bcd4..239aecf 100644
--- a/test/SemaCXX/member-expr.cpp
+++ b/test/SemaCXX/member-expr.cpp
@@ -87,7 +87,7 @@ namespace test5 {
}
void test2(A &x) {
- x->A::foo<int>(); // expected-error {{'test5::A' is not a pointer}}
+ x->A::foo<int>(); // expected-error {{'test5::A' is not a pointer; maybe you meant to use '.'?}}
}
}
@@ -172,3 +172,55 @@ void f(int i) {
j = 0;
}
}
+
+namespace PR15045 {
+ class Cl0 {
+ public:
+ int a;
+ };
+
+ int f() {
+ Cl0 c;
+ return c->a; // expected-error {{member reference type 'PR15045::Cl0' is not a pointer; maybe you meant to use '.'?}}
+ }
+
+ struct bar {
+ void func(); // expected-note {{'func' declared here}}
+ };
+
+ struct foo {
+ bar operator->(); // expected-note 2 {{'->' applied to return value of the operator->() declared here}}
+ };
+
+ template <class T> void call_func(T t) {
+ t->func(); // expected-error-re 2 {{member reference type 'PR15045::bar' is not a pointer$}} \
+ // expected-note {{did you mean to use '.' instead?}}
+ }
+
+ void test_arrow_on_non_pointer_records() {
+ bar e;
+ foo f;
+
+ // Show that recovery has happened by also triggering typo correction
+ e->Func(); // expected-error {{member reference type 'PR15045::bar' is not a pointer; maybe you meant to use '.'?}} \
+ // expected-error {{no member named 'Func' in 'PR15045::bar'; did you mean 'func'?}}
+
+ // 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$}}
+
+ call_func(e); // expected-note {{in instantiation of function template specialization 'PR15045::call_func<PR15045::bar>' requested here}}
+
+ call_func(f); // expected-note {{in instantiation of function template specialization 'PR15045::call_func<PR15045::foo>' requested here}}
+ }
+}
+
+namespace pr16676 {
+ struct S { int i; };
+ struct T { S* get_s(); };
+ int f(S* s) {
+ T t;
+ return t.get_s // expected-error {{reference to non-static member function must be called; did you mean to call it with no arguments?}}
+ .i; // expected-error {{member reference type 'pr16676::S *' is a pointer; maybe you meant to use '->'}}
+ }
+}
diff --git a/test/SemaCXX/member-init.cpp b/test/SemaCXX/member-init.cpp
index 19e8e75..6e4fd5d 100644
--- a/test/SemaCXX/member-init.cpp
+++ b/test/SemaCXX/member-init.cpp
@@ -89,3 +89,14 @@ namespace PR14838 {
const function &r; // expected-note {{reference member declared here}}
} af;
}
+
+namespace rdar14084171 {
+ struct Point { // expected-note 3 {{candidate constructor}}
+ double x;
+ double y;
+ };
+ struct Sprite {
+ Point location = Point(0,0); // expected-error {{no matching constructor for initialization of 'rdar14084171::Point'}}
+ };
+ void f(Sprite& x) { x = x; }
+}
diff --git a/test/SemaCXX/member-pointer-ms.cpp b/test/SemaCXX/member-pointer-ms.cpp
index 7dca121..aee8e2e 100644
--- a/test/SemaCXX/member-pointer-ms.cpp
+++ b/test/SemaCXX/member-pointer-ms.cpp
@@ -5,8 +5,6 @@
// 2012, which supports C++11 and static_assert. It should pass for both 64-bit
// and 32-bit x86.
//
-// expected-no-diagnostics
-
// Test the size of various member pointer combinations:
// - complete and incomplete
// - single, multiple, and virtual inheritance (and unspecified for incomplete)
@@ -165,3 +163,6 @@ struct MemPtrInTemplate {
int T::*data_ptr;
void (T::*func_ptr)();
};
+
+int Virtual::*CastTest = reinterpret_cast<int Virtual::*>(&AA::x);
+ // expected-error@-1 {{cannot reinterpret_cast from member pointer type}}
diff --git a/test/SemaCXX/microsoft-dtor-lookup.cpp b/test/SemaCXX/microsoft-dtor-lookup.cpp
new file mode 100644
index 0000000..d264bab
--- /dev/null
+++ b/test/SemaCXX/microsoft-dtor-lookup.cpp
@@ -0,0 +1,87 @@
+// 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
+
+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.
+
+struct A {
+ void operator delete(void *); // expected-note {{member found by ambiguous name lookup}}
+};
+
+struct B {
+ void operator delete(void *); // expected-note {{member found by ambiguous name lookup}}
+};
+
+struct C : A, B {
+ ~C();
+};
+
+struct VC : A, B {
+ virtual ~VC(); // expected-error {{member 'operator delete' found in multiple base classes of different types}}
+};
+
+}
+
+namespace Test2 {
+
+// In the MSVC ABI, functions must destroy their aggregate arguments. foo
+// 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}}
+ int a;
+};
+
+struct B : public A { // expected-error {{base class 'Test2::A' has private destructor}}
+ int b;
+};
+
+struct C {
+ ~C();
+ int c;
+};
+
+struct D {
+ // D has a non-trivial implicit dtor that destroys C.
+ 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 baz(D d) { } // no error
+
+}
+
+#ifdef MSVC_ABI
+namespace Test3 {
+
+class A {
+ A();
+ ~A(); // expected-note 2{{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}}
+
+// 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.
+void foo(A *a) {
+ bar(*a); // expected-error {{temporary of type 'Test3::A' has private destructor}}
+}
+}
+#endif
+
+namespace Test4 {
+// Don't try to access the dtor of an incomplete on a function declaration.
+class A;
+void foo(A a);
+}
diff --git a/test/SemaCXX/microsoft-new-delete.cpp b/test/SemaCXX/microsoft-new-delete.cpp
new file mode 100644
index 0000000..e0d25dc
--- /dev/null
+++ b/test/SemaCXX/microsoft-new-delete.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+#include <stddef.h>
+
+struct arbitrary_t {} arbitrary;
+void *operator new(size_t size, arbitrary_t);
+
+void f() {
+ // Expect no error in MSVC compatibility mode
+ int *p = new(arbitrary) int[4];
+}
diff --git a/test/SemaCXX/missing-members.cpp b/test/SemaCXX/missing-members.cpp
index 529ba10..619bc61 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 { };
+ class C { }; // expected-note 2 {{'A::B::C' declared here}}
struct S { };
union U { };
}
@@ -19,8 +19,12 @@ namespace B {
void g() {
A::B::D::E; // expected-error {{no member named 'D' in namespace 'A::B'}}
- B::B::C::D; // expected-error {{no member named 'C' in 'B::B'}}
- ::C::D; // expected-error {{no member named 'C' in the global namespace}}
+ // 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'}}
}
int A::B::i = 10; // expected-error {{no member named 'i' in namespace 'A::B'}}
diff --git a/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp b/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp
index 40bcf45..6195e03 100644
--- a/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp
+++ b/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp
@@ -19,7 +19,7 @@ namespace fizbin {
// expected-note{{'fizbin::nested::lessFoobar' declared here}}
class dummy { // expected-note 2 {{'fizbin::dummy' declared here}}
public:
- static bool moreFoobar() { return false; } // expected-note{{'moreFoobar' declared here}}
+ static bool morebar() { return false; } // expected-note{{'morebar' declared here}}
};
}
void Check() { // expected-note{{'Check' declared here}}
@@ -29,9 +29,9 @@ void Check() { // expected-note{{'Check' declared here}}
if (lessFoobar()) Double(7); // expected-error{{use of undeclared identifier 'lessFoobar'; did you mean 'fizbin::nested::lessFoobar'?}}
if (baztool::toFoobar()) Double(7); // expected-error{{use of undeclared identifier 'baztool'; did you mean 'fizbin::baztool'?}}
if (nested::moreFoobar()) Double(7); // expected-error{{use of undeclared identifier 'nested'; did you mean 'fizbin::nested'?}}
- if (dummy::moreFoobar()) Double(7); // expected-error{{use of undeclared identifier 'dummy'; did you mean 'fizbin::dummy'?}}
- if (dummy::mreFoobar()) Double(7); // expected-error{{use of undeclared identifier 'dummy'; did you mean 'fizbin::dummy'?}} \
- // expected-error{{no member named 'mreFoobar' in 'fizbin::dummy'; did you mean 'moreFoobar'?}}
+ if (dummy::morebar()) Double(7); // expected-error{{use of undeclared identifier 'dummy'; did you mean 'fizbin::dummy'?}}
+ if (dummy::mrebar()) Double(7); // expected-error{{use of undeclared identifier 'dummy'; did you mean 'fizbin::dummy'?}} \
+ // expected-error{{no member named 'mrebar' in 'fizbin::dummy'; did you mean 'morebar'?}}
if (moFoobin()) Double(7); // expected-error{{use of undeclared identifier 'moFoobin'}}
}
diff --git a/test/SemaCXX/ms-overload-entry-point.cpp b/test/SemaCXX/ms-overload-entry-point.cpp
new file mode 100644
index 0000000..67fed01
--- /dev/null
+++ b/test/SemaCXX/ms-overload-entry-point.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions -triple i386-pc-win32 %s
+
+template <typename T>
+int wmain() { // expected-error{{'wmain' cannot be a template}}
+ return 0;
+}
+
+namespace {
+int WinMain(void) { return 0; }
+int WinMain(int) { return 0; }
+}
+
+void wWinMain(void) {} // expected-note{{previous definition is here}}
+void wWinMain(int) {} // expected-error{{conflicting types for 'wWinMain'}}
+
+int foo() {
+ wmain<void>(); // expected-error{{no matching function for call to 'wmain'}}
+ wmain<int>(); // expected-error{{no matching function for call to 'wmain'}}
+ WinMain();
+ return 0;
+}
diff --git a/test/SemaCXX/ms-wchar.cpp b/test/SemaCXX/ms-wchar.cpp
new file mode 100644
index 0000000..878d8ca
--- /dev/null
+++ b/test/SemaCXX/ms-wchar.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions -triple i386-pc-win32 %s
+
+wchar_t f();
+__wchar_t f(); // No error, wchar_t and __wchar_t are the same type.
+
+__wchar_t g = L'a';
+__wchar_t s[] = L"Hello world!";
+
+unsigned short t[] = L"Hello world!"; // expected-error{{array initializer must be an initializer list}}
+
+wchar_t u[] = 1; // expected-error{{array initializer must be an initializer list or wide string literal}}
+__wchar_t v[] = 1; // expected-error{{array initializer must be an initializer list or wide string literal}}
diff --git a/test/SemaCXX/ms_struct.cpp b/test/SemaCXX/ms_struct.cpp
new file mode 100644
index 0000000..37fa9a7
--- /dev/null
+++ b/test/SemaCXX/ms_struct.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-apple-darwin9 -std=c++11 %s
+// expected-no-diagnostics
+
+#pragma ms_struct on
+
+struct A {
+ unsigned long a:4;
+ unsigned char b;
+};
+
+struct B : public A {
+ 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
diff --git a/test/SemaCXX/ms_wide_bitfield.cpp b/test/SemaCXX/ms_wide_bitfield.cpp
new file mode 100644
index 0000000..d917390
--- /dev/null
+++ b/test/SemaCXX/ms_wide_bitfield.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -mms-bitfields -verify %s 2>&1
+
+struct A {
+ char a : 9; // expected-error{{size of bit-field 'a' (9 bits) exceeds size of its type (8 bits)}}
+ int b : 33; // expected-error{{size of bit-field 'b' (33 bits) exceeds size of its type (32 bits)}}
+ bool c : 9; // expected-error{{size of bit-field 'c' (9 bits) exceeds size of its type (8 bits)}}
+};
+
+int a[sizeof(A) == 1 ? 1 : -1];
diff --git a/test/SemaCXX/neon-vector-types.cpp b/test/SemaCXX/neon-vector-types.cpp
index 336fcd4..c2953d7 100644
--- a/test/SemaCXX/neon-vector-types.cpp
+++ b/test/SemaCXX/neon-vector-types.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify "-triple" "thumbv7-apple-ios3.0.0" %s
+// RUN: %clang_cc1 -fsyntax-only -verify "-triple" "thumbv7-apple-ios3.0.0" -target-feature +neon %s
// rdar://9208404
typedef int MP4Err;
diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp
index 7239646..df4f1b2 100644
--- a/test/SemaCXX/nested-name-spec.cpp
+++ b/test/SemaCXX/nested-name-spec.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify -fblocks %s
namespace A {
struct C {
static int cx;
@@ -50,6 +50,7 @@ namespace B {
void f1() {
void A::Af(); // expected-error {{definition or redeclaration of 'Af' not allowed inside a function}}
+ void (^x)() = ^{ void A::Af(); }; // expected-error {{definition or redeclaration of 'Af' not allowed inside a block}}
}
void f2() {
@@ -166,9 +167,7 @@ void N::f() { } // okay
struct Y; // expected-note{{forward declaration of 'Y'}}
Y::foo y; // expected-error{{incomplete type 'Y' named in nested name specifier}}
-X::X() : a(5) { } // expected-error{{use of undeclared identifier 'X'}} \
- // expected-error{{C++ requires a type specifier for all declarations}} \
- // expected-error{{only constructors take base initializers}}
+X::X() : a(5) { } // expected-error{{use of undeclared identifier 'X'}}
struct foo_S {
static bool value;
@@ -260,7 +259,7 @@ namespace PR8159 {
namespace rdar7980179 {
class A { void f0(); }; // expected-note {{previous}}
- int A::f0() {} // expected-error {{out-of-line definition of 'rdar7980179::A::f0' differs from the declaration in the return type}}
+ int A::f0() {} // expected-error {{return type of out-of-line definition of 'rdar7980179::A::f0' differs}}
}
namespace alias = A;
@@ -297,3 +296,16 @@ namespace NS {
int foobar = a + longer_b; // expected-error {{use of undeclared identifier 'a'; did you mean 'NS::a'?}} \
// expected-error {{use of undeclared identifier 'longer_b'; did you mean 'NS::longer_b'?}}
}
+
+// <rdar://problem/13853540>
+namespace N {
+ struct X { };
+ namespace N {
+ struct Foo {
+ struct N::X *foo(); // expected-error{{no struct named 'X' in namespace 'N::N'}}
+ };
+ }
+}
+
+namespace TypedefNamespace { typedef int F; };
+TypedefNamespace::F::NonexistentName BadNNSWithCXXScopeSpec; // expected-error {{expected a class or namespace}}
diff --git a/test/SemaCXX/new-delete-0x.cpp b/test/SemaCXX/new-delete-0x.cpp
index 9e3b492..a11392d 100644
--- a/test/SemaCXX/new-delete-0x.cpp
+++ b/test/SemaCXX/new-delete-0x.cpp
@@ -21,7 +21,9 @@ void bad_news(int *ip)
auto s = new int*[[]{return 1;}()][2]; // expected-error {{expected ']'}}
// ... but not here:
auto t = new (int(*)[[]]); // expected-error {{an attribute list cannot appear here}}
- auto u = new (int(*)[[]{return 1;}()][2]); // expected-error {{C++11 only allows consecutive left square brackets when introducing an attribute}} expected-error {{variably modified type}}
+ auto u = new (int(*)[[]{return 1;}()][2]); // expected-error {{C++11 only allows consecutive left square brackets when introducing an attribute}} \
+ expected-error {{variably modified type}} \
+ expected-error {{a lambda expression may not appear inside of a constant expression}}
}
void good_deletes()
diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp
index 8b35295..7facd10 100644
--- a/test/SemaCXX/new-delete.cpp
+++ b/test/SemaCXX/new-delete.cpp
@@ -18,6 +18,13 @@ struct V : U
{
};
+inline void operator delete(void *); // expected-warning {{replacement function 'operator delete' cannot be declared 'inline'}}
+
+__attribute__((used))
+inline void *operator new(size_t) { // no warning, due to __attribute__((used))
+ return 0;
+}
+
// PR5823
void* operator new(const size_t); // expected-note 2 {{candidate}}
void* operator new(size_t, int*); // expected-note 3 {{candidate}}
@@ -116,8 +123,8 @@ struct X1 {
};
struct X2 {
- operator int*(); // expected-note {{candidate function}}
- operator float*(); // expected-note {{candidate function}}
+ operator int*(); // expected-note {{conversion}}
+ operator float*(); // expected-note {{conversion}}
};
void test_delete_conv(X0 x0, X1 x1, X2 x2) {
@@ -209,7 +216,7 @@ struct X11 : X10 { // expected-error {{no suitable member 'operator delete' in '
};
void f() {
- X11 x11; // expected-note {{implicit default destructor for 'X11' first required here}}
+ X11 x11; // expected-note {{implicit destructor for 'X11' first required here}}
}
struct X12 {
@@ -394,7 +401,7 @@ namespace ArrayNewNeedsDtor {
struct A { A(); private: ~A(); }; // expected-note {{declared private here}}
struct B { B(); A a; }; // expected-error {{field of type 'ArrayNewNeedsDtor::A' has private destructor}}
B *test9() {
- return new B[5]; // expected-note {{implicit default destructor for 'ArrayNewNeedsDtor::B' first required here}}
+ return new B[5]; // expected-note {{implicit destructor for 'ArrayNewNeedsDtor::B' first required here}}
}
}
diff --git a/test/SemaCXX/no-rtti.cpp b/test/SemaCXX/no-rtti.cpp
index 7516705..a171b3c 100644
--- a/test/SemaCXX/no-rtti.cpp
+++ b/test/SemaCXX/no-rtti.cpp
@@ -8,3 +8,22 @@ void f()
{
(void)typeid(int); // expected-error {{cannot use typeid with -fno-rtti}}
}
+
+namespace {
+struct A {
+ virtual ~A(){};
+};
+
+struct B : public A {
+ B() : A() {}
+};
+}
+
+bool isa_B(A *a) {
+ return dynamic_cast<B *>(a) != 0; // expected-error {{cannot use dynamic_cast with -fno-rtti}}
+}
+
+void* getMostDerived(A* a) {
+ // This cast does not use RTTI.
+ return dynamic_cast<void *>(a);
+}
diff --git a/test/SemaCXX/no-warn-unused-const-variables.cpp b/test/SemaCXX/no-warn-unused-const-variables.cpp
new file mode 100644
index 0000000..c146ca0
--- /dev/null
+++ b/test/SemaCXX/no-warn-unused-const-variables.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wno-unused-const-variable -verify %s
+
+namespace {
+ int i = 0; // expected-warning {{unused variable 'i'}}
+ const int j = 0;;
+}
diff --git a/test/SemaCXX/nullptr.cpp b/test/SemaCXX/nullptr.cpp
index b49f63b..28798a4 100644
--- a/test/SemaCXX/nullptr.cpp
+++ b/test/SemaCXX/nullptr.cpp
@@ -64,6 +64,9 @@ nullptr_t f(nullptr_t null)
(void)reinterpret_cast<uintptr_t>(nullptr);
(void)reinterpret_cast<uintptr_t>(*pn);
+ // You can't reinterpret_cast nullptr to any integer
+ (void)reinterpret_cast<char>(nullptr); // expected-error {{cast from pointer to smaller type 'char' loses information}}
+
int *ip = *pn;
if (*pn) { }
diff --git a/test/SemaCXX/offsetof.cpp b/test/SemaCXX/offsetof.cpp
index a5f5d34..e6069ac 100644
--- a/test/SemaCXX/offsetof.cpp
+++ b/test/SemaCXX/offsetof.cpp
@@ -73,3 +73,13 @@ struct LtoRCheck {
};
int ltor = __builtin_offsetof(struct LtoRCheck, a[LtoRCheck().f]); // \
expected-error {{reference to non-static member function must be called}}
+
+namespace PR17578 {
+struct Base {
+ int Field;
+};
+struct Derived : virtual Base {
+ void Fun() { (void)__builtin_offsetof(Derived, Field); } // expected-warning {{offset of on non-POD type}} \
+ expected-error {{invalid application of 'offsetof' to a field of a virtual base}}
+};
+}
diff --git a/test/SemaCXX/operator-arrow-depth.cpp b/test/SemaCXX/operator-arrow-depth.cpp
new file mode 100644
index 0000000..3e2ba8e
--- /dev/null
+++ b/test/SemaCXX/operator-arrow-depth.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DMAX=128 -foperator-arrow-depth 128
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DMAX=2 -foperator-arrow-depth 2
+// RUN: %clang -fsyntax-only -Xclang -verify %s -DMAX=10 -foperator-arrow-depth=10
+
+template<int N> struct B;
+template<int N> struct A {
+ B<N> operator->(); // expected-note +{{'operator->' declared here produces an object of type 'B<}}
+};
+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)}}
+#endif
+};
+
+struct X { int n; };
+template<> struct B<1> {
+ X *operator->();
+};
+
+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}}
+ // expected-note@-1 {{use -foperator-arrow-depth=N to increase 'operator->' limit}}
diff --git a/test/SemaCXX/overload-decl.cpp b/test/SemaCXX/overload-decl.cpp
index 9bba47a..fdb14cb 100644
--- a/test/SemaCXX/overload-decl.cpp
+++ b/test/SemaCXX/overload-decl.cpp
@@ -26,8 +26,14 @@ class X {
void g(int, float); // expected-note {{previous declaration is here}}
int g(int, Float); // expected-error {{functions that differ only in their return type cannot be overloaded}}
- static void g(float);
+ static void g(float); // expected-note {{previous declaration is here}}
static void g(int); // expected-error {{static and non-static member functions with the same parameter types cannot be overloaded}}
+ static void g(float); // expected-error {{class member cannot be redeclared}}
+
+ void h(); // expected-note {{previous declaration is here}} \
+ expected-note {{previous declaration is here}}
+ void h() __restrict; // expected-error {{class member cannot be redeclared}} \
+ expected-error {{conflicting types for 'h'}}
};
int main() {} // expected-note {{previous definition is here}}
diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp
index e5b3fab..99105cb 100644
--- a/test/SemaCXX/overloaded-operator.cpp
+++ b/test/SemaCXX/overloaded-operator.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
class X { };
X operator+(X, X);
@@ -387,8 +387,8 @@ void test_lookup_through_using() {
namespace rdar9136502 {
struct X {
- int i();
- int i(int);
+ int i(); // expected-note{{possible target for call}}
+ int i(int); // expected-note{{possible target for call}}
};
struct Y {
@@ -396,7 +396,8 @@ namespace rdar9136502 {
};
void f(X x, Y y) {
- y << x.i; // expected-error{{reference to non-static member function must be called}}
+ y << x
+ .i; // expected-error{{reference to non-static member function must be called; did you mean to call it with no arguments?}}
}
}
@@ -440,3 +441,14 @@ namespace test10 {
a[bar<float>];
}
}
+
+struct InvalidOperatorEquals {
+ InvalidOperatorEquals operator=() = delete; // expected-error {{overloaded 'operator=' must be a binary operator}}
+};
+
+namespace PR7681 {
+ template <typename PT1, typename PT2> class PointerUnion;
+ void foo(PointerUnion<int*, float*> &Result) {
+ Result = 1; // expected-error {{no viable overloaded '='}} // expected-note {{type 'PointerUnion<int *, float *>' is incomplete}}
+ }
+}
diff --git a/test/SemaCXX/parentheses.cpp b/test/SemaCXX/parentheses.cpp
new file mode 100644
index 0000000..b430b25
--- /dev/null
+++ b/test/SemaCXX/parentheses.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -verify %s
+
+// PR16930, PR16727:
+template<class Foo>
+bool test(Foo f, int *array)
+{
+ return false && false || array[f.get()]; // expected-warning {{'&&' within '||'}} expected-note {{parentheses}}
+}
diff --git a/test/SemaCXX/pr13394-crash-on-invalid.cpp b/test/SemaCXX/pr13394-crash-on-invalid.cpp
index 413c52a..841e3c2 100644
--- a/test/SemaCXX/pr13394-crash-on-invalid.cpp
+++ b/test/SemaCXX/pr13394-crash-on-invalid.cpp
@@ -9,8 +9,21 @@ namespace stretch_v1 {
namespace gatekeeper_v1 {
namespace gatekeeper_factory_v1 {
struct closure_t { // expected-note {{'closure_t' declared here}}
- gatekeeper_v1::closure_t* create(); // expected-error {{no type named 'closure_t' in namespace 'gatekeeper_v1'; did you mean 'closure_t'?}}
+ gatekeeper_v1::closure_t* create(); // expected-error {{no type named 'closure_t' in namespace 'gatekeeper_v1'; did you mean simply 'closure_t'?}}
};
}
- gatekeeper_v1::closure_t *x; // expected-error {{no type named 'closure_t' in namespace 'gatekeeper_v1}}
+ // 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'$}}
}
+
+namespace Foo {
+struct Base {
+ void Bar() {} // expected-note{{'Bar' declared here}}
+};
+}
+
+struct Derived : public Foo::Base {
+ void test() {
+ Foo::Bar(); // expected-error{{no member named 'Bar' in namespace 'Foo'; did you mean simply 'Bar'?}}
+ }
+};
diff --git a/test/SemaCXX/predefined-expr.cpp b/test/SemaCXX/predefined-expr.cpp
new file mode 100644
index 0000000..257d44c
--- /dev/null
+++ b/test/SemaCXX/predefined-expr.cpp
@@ -0,0 +1,103 @@
+// RUN: %clang_cc1 -std=c++1y -fblocks -fsyntax-only -verify %s
+// PR16946
+// expected-no-diagnostics
+
+auto foo() {
+ static_assert(sizeof(__func__) == 4, "foo");
+ static_assert(sizeof(__FUNCTION__) == 4, "foo");
+ static_assert(sizeof(__PRETTY_FUNCTION__) == 11, "auto foo()");
+ return 0;
+}
+
+auto bar() -> decltype(42) {
+ static_assert(sizeof(__func__) == 4, "bar");
+ static_assert(sizeof(__FUNCTION__) == 4, "bar");
+ static_assert(sizeof(__PRETTY_FUNCTION__) == 10, "int bar()");
+ return 0;
+}
+
+// Within templates.
+template <typename T>
+int baz() {
+ static_assert(sizeof(__func__) == 4, "baz");
+ static_assert(sizeof(__FUNCTION__) == 4, "baz");
+ static_assert(sizeof(__PRETTY_FUNCTION__) == 20, "int baz() [T = int]");
+
+ []() {
+ static_assert(sizeof(__func__) == 11, "operator()");
+ static_assert(sizeof(__FUNCTION__) == 11, "operator()");
+ static_assert(sizeof(__PRETTY_FUNCTION__) == 50,
+ "auto baz()::<anonymous class>::operator()() const");
+ return 0;
+ }
+ ();
+
+ ^{
+ // FIXME: This is obviously wrong.
+ static_assert(sizeof(__func__) == 1, "__baz_block_invoke");
+ static_assert(sizeof(__FUNCTION__) == 1, "__baz_block_invoke");
+ static_assert(sizeof(__PRETTY_FUNCTION__) == 1, "__baz_block_invoke");
+ }
+ ();
+
+ #pragma clang __debug captured
+ {
+ static_assert(sizeof(__func__) == 4, "baz");
+ static_assert(sizeof(__FUNCTION__) == 4, "baz");
+ static_assert(sizeof(__PRETTY_FUNCTION__) == 20, "int baz() [T = int]");
+ }
+
+ return 0;
+}
+
+int main() {
+ static_assert(sizeof(__func__) == 5, "main");
+ static_assert(sizeof(__FUNCTION__) == 5, "main");
+ static_assert(sizeof(__PRETTY_FUNCTION__) == 11, "int main()");
+
+ []() {
+ static_assert(sizeof(__func__) == 11, "operator()");
+ static_assert(sizeof(__FUNCTION__) == 11, "operator()");
+ static_assert(sizeof(__PRETTY_FUNCTION__) == 51,
+ "auto main()::<anonymous class>::operator()() const");
+ return 0;
+ }
+ ();
+
+ ^{
+ // FIXME: This is obviously wrong.
+ static_assert(sizeof(__func__) == 1, "__main_block_invoke");
+ static_assert(sizeof(__FUNCTION__) == 1, "__main_block_invoke");
+ static_assert(sizeof(__PRETTY_FUNCTION__) == 1, "__main_block_invoke");
+ }
+ ();
+
+ #pragma clang __debug captured
+ {
+ static_assert(sizeof(__func__) == 5, "main");
+ static_assert(sizeof(__FUNCTION__) == 5, "main");
+ static_assert(sizeof(__PRETTY_FUNCTION__) == 11, "int main()");
+
+ #pragma clang __debug captured
+ {
+ static_assert(sizeof(__func__) == 5, "main");
+ static_assert(sizeof(__FUNCTION__) == 5, "main");
+ static_assert(sizeof(__PRETTY_FUNCTION__) == 11, "int main()");
+ }
+ }
+
+ []() {
+ #pragma clang __debug captured
+ {
+ static_assert(sizeof(__func__) == 11, "operator()");
+ static_assert(sizeof(__FUNCTION__) == 11, "operator()");
+ static_assert(sizeof(__PRETTY_FUNCTION__) == 51,
+ "auto main()::<anonymous class>::operator()() const");
+ }
+ }
+ ();
+
+ baz<int>();
+
+ return 0;
+}
diff --git a/test/SemaCXX/qualified-id-lookup.cpp b/test/SemaCXX/qualified-id-lookup.cpp
index a14193c..23164fa 100644
--- a/test/SemaCXX/qualified-id-lookup.cpp
+++ b/test/SemaCXX/qualified-id-lookup.cpp
@@ -86,13 +86,13 @@ namespace a {
namespace a {
namespace a { // A1
namespace a { // A2
- int i; // expected-note{{'::a::a::a::i' declared here}}
+ int i; // expected-note{{'a::a::a::i' declared here}}
}
}
}
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::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'$}}
}
@@ -149,6 +149,6 @@ namespace PR6830 {
}
namespace pr12339 {
- extern "C" void i;
+ extern "C" void i; // expected-error{{variable has incomplete type 'void'}}
pr12339::FOO // expected-error{{no type named 'FOO' in namespace 'pr12339'}}
} // expected-error{{expected unqualified-id}}
diff --git a/test/SemaCXX/references.cpp b/test/SemaCXX/references.cpp
index 4f3dab0..37fc2a8 100644
--- a/test/SemaCXX/references.cpp
+++ b/test/SemaCXX/references.cpp
@@ -137,3 +137,10 @@ namespace PR8608 {
// The following crashed trying to recursively evaluate the LValue.
const int &do_not_crash = do_not_crash; // expected-warning{{reference 'do_not_crash' is not yet bound to a value when used within its own initialization}}
+
+namespace ExplicitRefInit {
+ // This is invalid: we can't copy-initialize an 'A' temporary using an
+ // explicit constructor.
+ struct A { explicit A(int); };
+ const A &a(0); // expected-error {{reference to type 'const ExplicitRefInit::A' could not bind to an rvalue of type 'int'}}
+}
diff --git a/test/SemaCXX/scope-check.cpp b/test/SemaCXX/scope-check.cpp
index de276ae..90c9317 100644
--- a/test/SemaCXX/scope-check.cpp
+++ b/test/SemaCXX/scope-check.cpp
@@ -276,6 +276,27 @@ namespace test15 {
}
namespace test16 {
+ struct S { int n; };
+ int f() {
+ goto x; // expected-error {{goto into protected scope}}
+ const S &s = S(); // expected-note {{jump bypasses variable initialization}}
+x: return s.n;
+ }
+}
+
+#if __cplusplus >= 201103L
+namespace test17 {
+ struct S { int get(); private: int n; };
+ int f() {
+ goto x; // expected-error {{goto into protected scope}}
+ S s = {}; // expected-note {{jump bypasses variable initialization}}
+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()
diff --git a/test/SemaCXX/self-comparison.cpp b/test/SemaCXX/self-comparison.cpp
new file mode 100644
index 0000000..fb15ec8
--- /dev/null
+++ b/test/SemaCXX/self-comparison.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int foo(int x) {
+ return x == x; // expected-warning {{self-comparison always evaluates to true}}
+}
+
+struct X {
+ bool operator==(const X &x);
+};
+
+struct A {
+ int x;
+ X x2;
+ int a[3];
+ int b[3];
+ bool f() { return x == x; } // expected-warning {{self-comparison always evaluates to true}}
+ bool g() { return x2 == x2; } // no-warning
+ bool h() { return a == b; } // expected-warning {{array comparison always evaluates to false}}
+ bool i() {
+ int c[3];
+ return a == c; // expected-warning {{array comparison always evaluates to false}}
+ }
+};
diff --git a/test/SemaCXX/static-data-member.cpp b/test/SemaCXX/static-data-member.cpp
new file mode 100644
index 0000000..9fe87b1
--- /dev/null
+++ b/test/SemaCXX/static-data-member.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -w %s
+
+struct ABC {
+ static double a;
+ static double b;
+ static double c;
+ static double d;
+ static double e;
+ static double f;
+};
+
+double ABC::a = 1.0;
+extern double ABC::b = 1.0; // expected-error {{static data member definition cannot specify a storage class}}
+static double ABC::c = 1.0; // expected-error {{'static' can only be specified inside the class definition}}
+__private_extern__ double ABC::d = 1.0; // expected-error {{static data member definition cannot specify a storage class}}
+auto double ABC::e = 1.0; // expected-error {{static data member definition cannot specify a storage class}}
+register double ABC::f = 1.0; // expected-error {{static data member definition cannot specify a storage class}}
diff --git a/test/SemaCXX/storage-class.cpp b/test/SemaCXX/storage-class.cpp
index 7412184..decf1e7 100644
--- a/test/SemaCXX/storage-class.cpp
+++ b/test/SemaCXX/storage-class.cpp
@@ -4,4 +4,4 @@ extern int PR6495b = 42; // expected-warning{{'extern' variable has an initializ
extern const int PR6495c[] = {42,43,44};
extern struct Test1 {}; // expected-warning {{'extern' is not permitted on a declaration of a type}}
-extern "C" struct Test0 {}; // no warning
+extern "C" struct Test0 { int x; }; // no warning
diff --git a/test/SemaCXX/string-init.cpp b/test/SemaCXX/string-init.cpp
new file mode 100644
index 0000000..7e62d18
--- /dev/null
+++ b/test/SemaCXX/string-init.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+void f() {
+ char a1[] = "a"; // No error.
+ char a2[] = u8"a"; // No error.
+ char a3[] = u"a"; // expected-error{{initializing char array with wide string literal}}
+ char a4[] = U"a"; // expected-error{{initializing char array with wide string literal}}
+ char a5[] = L"a"; // expected-error{{initializing char array with wide string literal}}
+
+ wchar_t b1[] = "a"; // expected-error{{initializing wide char array with non-wide string literal}}
+ wchar_t b2[] = u8"a"; // expected-error{{initializing wide char array with non-wide string literal}}
+ wchar_t b3[] = u"a"; // expected-error{{initializing wide char array with incompatible wide string literal}}
+ wchar_t b4[] = U"a"; // expected-error{{initializing wide char array with incompatible wide string literal}}
+ wchar_t b5[] = L"a"; // No error.
+
+ char16_t c1[] = "a"; // expected-error{{initializing wide char array with non-wide string literal}}
+ char16_t c2[] = u8"a"; // expected-error{{initializing wide char array with non-wide string literal}}
+ char16_t c3[] = u"a"; // No error.
+ char16_t c4[] = U"a"; // expected-error{{initializing wide char array with incompatible wide string literal}}
+ char16_t c5[] = L"a"; // expected-error{{initializing wide char array with incompatible wide string literal}}
+
+ char32_t d1[] = "a"; // expected-error{{initializing wide char array with non-wide string literal}}
+ char32_t d2[] = u8"a"; // expected-error{{initializing wide char array with non-wide string literal}}
+ char32_t d3[] = u"a"; // expected-error{{initializing wide char array with incompatible wide string literal}}
+ char32_t d4[] = U"a"; // No error.
+ char32_t d5[] = L"a"; // expected-error{{initializing wide char array with incompatible wide string literal}}
+
+ int e1[] = "a"; // expected-error{{array initializer must be an initializer list}}
+ int e2[] = u8"a"; // expected-error{{array initializer must be an initializer list}}
+ int e3[] = u"a"; // expected-error{{array initializer must be an initializer list}}
+ int e4[] = U"a"; // expected-error{{array initializer must be an initializer list}}
+ int e5[] = L"a"; // expected-error{{array initializer must be an initializer list}}
+}
+
+void g() {
+ char a[] = 1; // expected-error{{array initializer must be an initializer list or string literal}}
+ wchar_t b[] = 1; // expected-error{{array initializer must be an initializer list or wide string literal}}
+ char16_t c[] = 1; // expected-error{{array initializer must be an initializer list or wide string literal}}
+ char32_t d[] = 1; // expected-error{{array initializer must be an initializer list or wide string literal}}
+}
diff --git a/test/SemaCXX/string-plus-char.cpp b/test/SemaCXX/string-plus-char.cpp
new file mode 100644
index 0000000..00a2c45
--- /dev/null
+++ b/test/SemaCXX/string-plus-char.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+
+class A {
+public:
+ A(): str() { }
+ A(const char *p) { }
+ A(char *p) : str(p + 'a') { } // expected-warning {{adding 'char' to a string pointer does not append to the string}} expected-note {{use array indexing to silence this warning}}
+ A& operator+(const char *p) { return *this; }
+ A& operator+(char ch) { return *this; }
+ char * str;
+};
+
+void f(const char *s) {
+ A a = s + 'a'; // // expected-warning {{adding 'char' to a string pointer does not append to the string}} expected-note {{use array indexing to silence this warning}}
+ a = a + s + 'b'; // no-warning
+
+ char *str = 0;
+ char *str2 = str + 'c'; // expected-warning {{adding 'char' to a string pointer does not append to the string}} expected-note {{use array indexing to silence this warning}}
+
+ const char *constStr = s + 'c'; // expected-warning {{adding 'char' to a string pointer does not append to the string}} expected-note {{use array indexing to silence this warning}}
+
+ str = 'c' + str;// expected-warning {{adding 'char' to a string pointer does not append to the string}} expected-note {{use array indexing to silence this warning}}
+
+ wchar_t *wstr;
+ wstr = wstr + L'c'; // expected-warning {{adding 'wchar_t' to a string pointer does not append to the string}} expected-note {{use array indexing to silence this warning}}
+ str2 = str + u'a'; // expected-warning {{adding 'char16_t' to a string pointer does not append to the string}} expected-note {{use array indexing to silence this warning}}
+
+ // no-warning
+ char c = 'c';
+ str = str + c;
+ str = c + str;
+}
diff --git a/test/SemaCXX/struct-class-redecl.cpp b/test/SemaCXX/struct-class-redecl.cpp
index 5c59578..e1b95ba 100644
--- a/test/SemaCXX/struct-class-redecl.cpp
+++ b/test/SemaCXX/struct-class-redecl.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -Wmismatched-tags -verify %s
-// RUN: %clang_cc1 -fsyntax-only -Wmismatched-tags %s 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -fsyntax-only -Wmismatched-tags %s 2>&1 | FileCheck %s
class X; // expected-note 2{{here}}
typedef struct X * X_t; // expected-warning{{previously declared}}
union X { int x; float y; }; // expected-error{{use of 'X' with tag type that does not match previous declaration}}
diff --git a/test/SemaCXX/switch.cpp b/test/SemaCXX/switch.cpp
index 517faa9..392dcd8 100644
--- a/test/SemaCXX/switch.cpp
+++ b/test/SemaCXX/switch.cpp
@@ -85,3 +85,18 @@ void local_class(int n) {
}();
}
}
+
+namespace Conversion {
+ struct S {
+ explicit operator int(); // expected-note {{conversion}}
+ };
+ template<typename T> void f(T t) {
+ switch (t) { // expected-error {{explicit conversion}}
+ case 0:
+ return;
+ default:
+ break;
+ }
+ }
+ template void f(S); // expected-note {{instantiation of}}
+}
diff --git a/test/SemaCXX/trailing-return-0x.cpp b/test/SemaCXX/trailing-return-0x.cpp
index bd601db..f7e3433 100644
--- a/test/SemaCXX/trailing-return-0x.cpp
+++ b/test/SemaCXX/trailing-return-0x.cpp
@@ -94,3 +94,11 @@ namespace DR1608 {
auto f() -> decltype((*this)[0]); // expected-error {{cannot be overloaded}}
};
}
+
+namespace PR16273 {
+ struct A {
+ template <int N> void f();
+ auto g()->decltype(this->f<0>());
+ };
+}
+
diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp
index aa18ff4..3e47921 100644
--- a/test/SemaCXX/type-traits.cpp
+++ b/test/SemaCXX/type-traits.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 -fms-extensions -Wno-microsoft %s
#define T(b) (b) ? 1 : -1
#define F(b) (b) ? -1 : 1
@@ -308,6 +308,37 @@ void is_final()
{ int arr[F(__is_final(PotentiallyFinal<float>))]; }
}
+struct SealedClass sealed {
+};
+
+template<typename T>
+struct PotentiallySealed { };
+
+template<typename T>
+struct PotentiallySealed<T*> sealed { };
+
+template<>
+struct PotentiallySealed<int> sealed { };
+
+void is_sealed()
+{
+ { int arr[T(__is_sealed(SealedClass))]; }
+ { int arr[T(__is_sealed(PotentiallySealed<float*>))]; }
+ { int arr[T(__is_sealed(PotentiallySealed<int>))]; }
+
+ { int arr[F(__is_sealed(int))]; }
+ { int arr[F(__is_sealed(Union))]; }
+ { int arr[F(__is_sealed(Int))]; }
+ { int arr[F(__is_sealed(IntAr))]; }
+ { int arr[F(__is_sealed(UnionAr))]; }
+ { int arr[F(__is_sealed(Derives))]; }
+ { int arr[F(__is_sealed(ClassType))]; }
+ { int arr[F(__is_sealed(cvoid))]; }
+ { int arr[F(__is_sealed(IntArNB))]; }
+ { int arr[F(__is_sealed(HasAnonymousUnion))]; }
+ { int arr[F(__is_sealed(PotentiallyFinal<float>))]; }
+}
+
typedef HasVirt Polymorph;
struct InheritPolymorph : Polymorph {};
@@ -1072,6 +1103,9 @@ void is_trivially_copyable2()
int t31[F(__is_trivially_copyable(SuperNonTrivialStruct))];
int t32[F(__is_trivially_copyable(NonTCStruct))];
int t33[F(__is_trivially_copyable(ExtDefaulted))];
+
+ int t34[T(__is_trivially_copyable(const int))];
+ int t35[F(__is_trivially_copyable(volatile int))];
}
struct CStruct {
@@ -1244,14 +1278,14 @@ void has_trivial_default_constructor() {
void has_trivial_move_constructor() {
// n3376 12.8 [class.copy]/12
- // A copy/move constructor for class X is trivial if it is not
- // user-provided, its declared parameter type is the same as
+ // A copy/move constructor for class X is trivial if it is not
+ // user-provided, its declared parameter type is the same as
// if it had been implicitly declared, and if
- // — class X has no virtual functions (10.3) and no virtual
+ // - class X has no virtual functions (10.3) and no virtual
// base classes (10.1), and
- // — the constructor selected to copy/move each direct base
+ // - the constructor selected to copy/move each direct base
// class subobject is trivial, and
- // — for each non-static data member of X that is of class
+ // - for each non-static data member of X that is of class
// type (or array thereof), the constructor selected
// to copy/move that member is trivial;
// otherwise the copy/move constructor is non-trivial.
@@ -1445,14 +1479,14 @@ void has_nothrow_move_assign() {
void has_trivial_move_assign() {
// n3376 12.8 [class.copy]/25
- // A copy/move assignment operator for class X is trivial if it
- // is not user-provided, its declared parameter type is the same
+ // A copy/move assignment operator for class X is trivial if it
+ // is not user-provided, its declared parameter type is the same
// as if it had been implicitly declared, and if:
- // — class X has no virtual functions (10.3) and no virtual base
+ // - class X has no virtual functions (10.3) and no virtual base
// classes (10.1), and
- // — the assignment operator selected to copy/move each direct
+ // - the assignment operator selected to copy/move each direct
// base class subobject is trivial, and
- // — for each non-static data member of X that is of class type
+ // - for each non-static data member of X that is of class type
// (or array thereof), the assignment operator
// selected to copy/move that member is trivial;
{ int arr[T(__has_trivial_move_assign(Int))]; }
@@ -1571,7 +1605,7 @@ template<typename T> struct DerivedB : BaseA<T> { };
template<typename T> struct CrazyDerived : T { };
-class class_forward; // expected-note {{forward declaration of 'class_forward'}}
+class class_forward; // expected-note 2 {{forward declaration of 'class_forward'}}
template <typename Base, typename Derived>
void isBaseOfT() {
@@ -1770,6 +1804,8 @@ void is_trivial()
{ int arr[F(__is_trivial(cvoid))]; }
}
+template<typename T> struct TriviallyConstructibleTemplate {};
+
void trivial_checks()
{
{ int arr[T(__is_trivially_copyable(int))]; }
@@ -1848,6 +1884,11 @@ void trivial_checks()
{ int arr[F((__is_trivially_constructible(ExtDefaulted,
ExtDefaulted &&)))]; }
+ { int arr[T((__is_trivially_constructible(TriviallyConstructibleTemplate<int>)))]; }
+ { int arr[F((__is_trivially_constructible(class_forward)))]; } // expected-error {{incomplete type 'class_forward' used in type trait expression}}
+ { int arr[F((__is_trivially_constructible(class_forward[])))]; }
+ { int arr[F((__is_trivially_constructible(void)))]; }
+
{ int arr[T((__is_trivially_assignable(int&, int)))]; }
{ int arr[T((__is_trivially_assignable(int&, int&)))]; }
{ int arr[T((__is_trivially_assignable(int&, int&&)))]; }
diff --git a/test/SemaCXX/typo-correction-pt2.cpp b/test/SemaCXX/typo-correction-pt2.cpp
new file mode 100644
index 0000000..525d11b
--- /dev/null
+++ b/test/SemaCXX/typo-correction-pt2.cpp
@@ -0,0 +1,201 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++11-extensions %s
+//
+// FIXME: This file is overflow from test/SemaCXX/typo-correction.cpp due to a
+// hard-coded limit of 20 different typo corrections Sema::CorrectTypo will
+// attempt within a single file (which is to avoid having very broken files take
+// minutes to finally be rejected by the parser).
+
+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'$}}
+ }
+}
+
+namespace PR13387 {
+struct A {
+ void CreateFoo(float, float);
+ void CreateBar(float, float);
+};
+struct B : A {
+ using A::CreateFoo;
+ void CreateFoo(int, int);
+};
+void f(B &x) {
+ x.Createfoo(0,0); // expected-error {{no member named 'Createfoo' in 'PR13387::B'; did you mean 'CreateFoo'?}}
+}
+}
+
+struct DataStruct {void foo();};
+struct T {
+ DataStruct data_struct;
+ void f();
+};
+// should be void T::f();
+void f() {
+ data_struct->foo(); // expected-error-re{{use of undeclared identifier 'data_struct'$}}
+}
+
+namespace PR12287 {
+class zif {
+ void nab(int);
+};
+void nab(); // expected-note{{'::PR12287::nab' declared here}}
+void zif::nab(int) {
+ nab(); // expected-error{{too few arguments to function call, expected 1, have 0; did you mean '::PR12287::nab'?}}
+}
+}
+
+namespace TemplateFunction {
+template <class T>
+void A(T) { } // expected-note {{'::TemplateFunction::A' declared here}}
+
+template <class T>
+void B(T) { } // expected-note {{'::TemplateFunction::B' declared here}}
+
+class Foo {
+ public:
+ void A(int, int) {}
+ void B() {}
+};
+
+void test(Foo F, int num) {
+ F.A(num); // expected-error {{too few arguments to function call, expected 2, have 1; did you mean '::TemplateFunction::A'?}}
+ F.B(num); // expected-error {{too many arguments to function call, expected 0, have 1; did you mean '::TemplateFunction::B'?}}
+}
+}
+namespace using_suggestion_val_dropped_specifier {
+void FFF() {} // expected-note {{'::using_suggestion_val_dropped_specifier::FFF' declared here}}
+namespace N { }
+using N::FFF; // expected-error {{no member named 'FFF' in namespace 'using_suggestion_val_dropped_specifier::N'; did you mean '::using_suggestion_val_dropped_specifier::FFF'?}}
+}
+
+namespace class_member_typo_corrections {
+class Outer {
+public:
+ class Inner {}; // expected-note {{'Outer::Inner' declared here}}
+ Inner MyMethod(Inner arg);
+};
+
+Inner Outer::MyMethod(Inner arg) { // expected-error {{unknown type name 'Inner'; did you mean 'Outer::Inner'?}}
+ return Inner();
+}
+
+class Result {
+public:
+ enum ResultType {
+ ENTITY, // expected-note {{'Result::ENTITY' declared here}}
+ PREDICATE, // expected-note {{'Result::PREDICATE' declared here}}
+ LITERAL // expected-note {{'Result::LITERAL' declared here}}
+ };
+
+ ResultType type();
+};
+
+void test() {
+ Result result_cell;
+ switch (result_cell.type()) {
+ case ENTITY: // expected-error {{use of undeclared identifier 'ENTITY'; did you mean 'Result::ENTITY'?}}
+ case LITERAL: // expected-error {{use of undeclared identifier 'LITERAL'; did you mean 'Result::LITERAL'?}}
+ case PREDICAT: // expected-error {{use of undeclared identifier 'PREDICAT'; did you mean 'Result::PREDICATE'?}}
+ break;
+ }
+}
+
+class Figure {
+ enum ResultType {
+ SQUARE,
+ TRIANGLE,
+ CIRCLE
+ };
+
+public:
+ ResultType type();
+};
+
+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'$}}
+ break;
+ }
+}
+}
+
+long readline(const char *, char *, unsigned long);
+void assign_to_unknown_var() {
+ 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'$}}
+}
+}
+
+namespace PR17394 {
+ class A {
+ protected:
+ long zzzzzzzzzz;
+ };
+ class B : private A {};
+ B zzzzzzzzzy<>; // expected-error {{expected ';' after top level declarator}}{}
+}
+
+namespace correct_fields_in_member_funcs {
+struct S {
+ int my_member; // expected-note {{'my_member' declared here}}
+ void f() { my_menber = 1; } // expected-error {{use of undeclared identifier 'my_menber'; did you mean 'my_member'?}}
+};
+}
+
+namespace PR17019 {
+ template<class F>
+ struct evil {
+ evil(F de) { // expected-note {{'de' declared here}}
+ de_; // expected-error {{use of undeclared identifier 'de_'; did you mean 'de'?}} \
+ // expected-warning {{expression result unused}}
+ }
+ ~evil() {
+ de_->bar() // expected-error {{use of undeclared identifier 'de_'}}
+ }
+ };
+
+ void meow() {
+ evil<int> Q(0); // expected-note {{in instantiation of member function}}
+ }
+}
+
+namespace fix_class_name_qualifier {
+class MessageHeaders {};
+class MessageUtils {
+ public:
+ static void ParseMessageHeaders(int, int); // expected-note {{'MessageUtils::ParseMessageHeaders' declared here}}
+};
+
+void test() {
+ // No, we didn't mean to call MessageHeaders::MessageHeaders.
+ MessageHeaders::ParseMessageHeaders(5, 4); // expected-error {{no member named 'ParseMessageHeaders' in 'fix_class_name_qualifier::MessageHeaders'; did you mean 'MessageUtils::ParseMessageHeaders'?}}
+}
+}
+
+namespace PR18213 { // expected-note {{'PR18213' declared here}}
+struct WrapperInfo {
+ int i;
+};
+
+template <typename T> struct Wrappable {
+ static WrapperInfo kWrapperInfo;
+};
+
+// Note the space before "::PR18213" is intended and needed, as it highlights
+// the actual typo, which is the leading "::".
+// TODO: Suggest removing the "::" from "::PR18213" (the right correction)
+// instead of incorrectly suggesting dropping "PR18213::WrapperInfo::".
+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}}
+}
diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp
index caa6355..4047e6a 100644
--- a/test/SemaCXX/typo-correction.cpp
+++ b/test/SemaCXX/typo-correction.cpp
@@ -1,4 +1,8 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++11-extensions %s
+//
+// WARNING: Do not add more typo correction test cases to this file lest you run
+// afoul the hard-coded limit (escape hatch) of 20 different typos whose
+// correction was attempted by Sema::CorrectTypo
struct errc {
int v_;
@@ -213,10 +217,14 @@ namespace PR13051 {
operator bool() const;
};
- void f() {
- f(&S<int>::tempalte f<int>); // expected-error{{did you mean 'template'?}}
- f(&S<int>::opeartor bool); // expected-error{{did you mean 'operator'?}}
- f(&S<int>::foo); // expected-error-re{{no member named 'foo' in 'PR13051::S<int>'$}}
+ void foo(); // expected-note{{'foo' declared here}}
+ void g(void(*)());
+ void g(bool(S<int>::*)() const);
+
+ void test() {
+ g(&S<int>::tempalte f<int>); // expected-error{{did you mean 'template'?}}
+ g(&S<int>::opeartor bool); // expected-error{{did you mean 'operator'?}}
+ g(&S<int>::foo); // expected-error{{no member named 'foo' in 'PR13051::S<int>'; did you mean simply 'foo'?}}
}
}
@@ -230,33 +238,67 @@ class foo { }; // expected-note{{'foo' declared here}}
class bar : boo { }; // expected-error{{unknown class name 'boo'; did you mean 'foo'?}}
}
-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'$}}
- }
+namespace outer {
+ void somefunc(); // expected-note{{'::outer::somefunc' declared here}}
+ void somefunc(int, int); // expected-note{{'::outer::somefunc' declared here}}
+
+ namespace inner {
+ void somefunc(int) {
+ someFunc(); // expected-error{{use of undeclared identifier 'someFunc'; did you mean '::outer::somefunc'?}}
+ someFunc(1, 2); // expected-error{{use of undeclared identifier 'someFunc'; did you mean '::outer::somefunc'?}}
+ }
+ }
}
-namespace PR13387 {
-struct A {
- void CreateFoo(float, float); // expected-note {{'CreateFoo' declared here}}
- void CreateBar(float, float);
-};
-struct B : A {
- using A::CreateFoo;
- void CreateFoo(int, int);
-};
-void f(B &x) {
- x.Createfoo(0,0); // expected-error {{no member named 'Createfoo' in 'PR13387::B'; did you mean 'CreateFoo'?}}
+namespace b6956809_test1 {
+ struct A {};
+ struct B {};
+
+ struct S1 {
+ void method(A*); // no note here
+ void method(B*);
+ };
+
+ void test1() {
+ B b;
+ S1 s;
+ s.methodd(&b); // expected-error{{no member named 'methodd' in 'b6956809_test1::S1'; did you mean 'method'}}
+ }
+
+ struct S2 {
+ S2();
+ void method(A*) const; // expected-note{{candidate function not viable}}
+ private:
+ void method(B*); // expected-note{{candidate function not viable}}
+ };
+
+ void test2() {
+ B b;
+ const S2 s;
+ s.methodd(&b); // expected-error{{no member named 'methodd' in 'b6956809_test1::S2'; did you mean 'method'}} expected-error{{no matching member function for call to 'method'}}
+ }
}
+
+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> 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'?}}
+ }
}
-struct DataStruct {void foo();};
-struct T {
- DataStruct data_struct;
- void f();
+// This test should have one correction, followed by an error without a
+// suggestion due to exceeding the maximum number of typos for which correction
+// is attempted.
+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'$}}
};
-// should be void T::f();
-void f() {
- data_struct->foo(); // expected-error-re{{use of undeclared identifier 'data_struct'$}}
}
diff --git a/test/SemaCXX/uninitialized.cpp b/test/SemaCXX/uninitialized.cpp
index 665cfe7..4991ebe 100644
--- a/test/SemaCXX/uninitialized.cpp
+++ b/test/SemaCXX/uninitialized.cpp
@@ -340,7 +340,10 @@ namespace {
};
struct E {
- int a, b, c;
+ int b = 1;
+ int c = 1;
+ int a; // This field needs to be last to prevent the cross field
+ // uninitialized warning.
E(char (*)[1]) : a(a ? b : c) {} // expected-warning {{field 'a' is uninitialized when used here}}
E(char (*)[2]) : a(b ? a : a) {} // expected-warning 2{{field 'a' is uninitialized when used here}}
E(char (*)[3]) : a(b ? (a) : c) {} // expected-warning {{field 'a' is uninitialized when used here}}
@@ -459,7 +462,7 @@ namespace in_class_initializers {
};
struct U {
- U() : a(b + 1), b(a + 1) {} // FIXME: Warn here.
+ U() : a(b + 1), b(a + 1) {} // expected-warning{{field 'b' is uninitialized when used here}}
int a = 42; // Note: because a and b are in the member initializer list, these initializers are ignored.
int b = 1;
};
@@ -484,7 +487,8 @@ namespace references {
}
struct T {
- T() : a(b), b(a) {} // FIXME: Warn here.
+ T() // expected-note{{during field initialization in this constructor}}
+ : a(b), b(a) {} // expected-warning{{reference 'b' is not yet bound to a value when used here}}
int &a, &b;
int &c = c; // expected-warning{{reference 'c' is not yet bound to a value when used here}}
};
@@ -523,3 +527,204 @@ namespace lambdas {
A a2([&] { return a2.x; }); // ok
}
}
+
+namespace record_fields {
+ struct A {
+ A() {}
+ A get();
+ static A num();
+ static A copy(A);
+ static A something(A&);
+ };
+
+ A ref(A&);
+ A const_ref(const A&);
+ A pointer(A*);
+ A normal(A);
+
+ struct B {
+ A a;
+ B(char (*)[1]) : a(a) {} // expected-warning {{uninitialized}}
+ B(char (*)[2]) : a(a.get()) {} // expected-warning {{uninitialized}}
+ B(char (*)[3]) : a(a.num()) {}
+ B(char (*)[4]) : a(a.copy(a)) {} // expected-warning {{uninitialized}}
+ B(char (*)[5]) : a(a.something(a)) {}
+ B(char (*)[6]) : a(ref(a)) {}
+ B(char (*)[7]) : a(const_ref(a)) {}
+ B(char (*)[8]) : a(pointer(&a)) {}
+ B(char (*)[9]) : a(normal(a)) {} // expected-warning {{uninitialized}}
+ };
+ struct C {
+ C() {} // expected-note4{{in this constructor}}
+ A a1 = a1; // expected-warning {{uninitialized}}
+ A a2 = a2.get(); // expected-warning {{uninitialized}}
+ A a3 = a3.num();
+ A a4 = a4.copy(a4); // expected-warning {{uninitialized}}
+ A a5 = a5.something(a5);
+ A a6 = ref(a6);
+ A a7 = const_ref(a7);
+ A a8 = pointer(&a8);
+ A a9 = normal(a9); // expected-warning {{uninitialized}}
+ };
+ struct D { // expected-note4{{in the implicit default constructor}}
+ A a1 = a1; // expected-warning {{uninitialized}}
+ A a2 = a2.get(); // expected-warning {{uninitialized}}
+ A a3 = a3.num();
+ A a4 = a4.copy(a4); // expected-warning {{uninitialized}}
+ A a5 = a5.something(a5);
+ A a6 = ref(a6);
+ A a7 = const_ref(a7);
+ A a8 = pointer(&a8);
+ A a9 = normal(a9); // expected-warning {{uninitialized}}
+ };
+ D d;
+ struct E {
+ A a1 = a1;
+ A a2 = a2.get();
+ A a3 = a3.num();
+ A a4 = a4.copy(a4);
+ A a5 = a5.something(a5);
+ A a6 = ref(a6);
+ A a7 = const_ref(a7);
+ A a8 = pointer(&a8);
+ A a9 = normal(a9);
+ };
+}
+
+namespace cross_field_warnings {
+ struct A {
+ int a, b;
+ A() {}
+ A(char (*)[1]) : b(a) {} // expected-warning{{field 'a' is uninitialized when used here}}
+ A(char (*)[2]) : a(b) {} // expected-warning{{field 'b' is uninitialized when used here}}
+ };
+
+ struct B {
+ int a = b; // expected-warning{{field 'b' is uninitialized when used here}}
+ int b;
+ B() {} // expected-note{{during field initialization in this constructor}}
+ };
+
+ struct C {
+ int a;
+ int b = a; // expected-warning{{field 'a' is uninitialized when used here}}
+ C(char (*)[1]) : a(5) {}
+ C(char (*)[2]) {} // expected-note{{during field initialization in this constructor}}
+ };
+
+ struct D {
+ int a;
+ int &b;
+ int &c = a;
+ int d = b;
+ D() : b(a) {}
+ };
+
+ struct E {
+ int a;
+ int get();
+ static int num();
+ E() {}
+ E(int) {}
+ };
+
+ struct F {
+ int a;
+ E e;
+ int b;
+ F(char (*)[1]) : a(e.get()) {} // expected-warning{{field 'e' is uninitialized when used here}}
+ F(char (*)[2]) : a(e.num()) {}
+ F(char (*)[3]) : e(a) {} // expected-warning{{field 'a' is uninitialized when used here}}
+ F(char (*)[4]) : a(4), e(a) {}
+ F(char (*)[5]) : e(b) {} // expected-warning{{field 'b' is uninitialized when used here}}
+ F(char (*)[6]) : e(b), b(4) {} // expected-warning{{field 'b' is uninitialized when used here}}
+ };
+
+ struct G {
+ G(const A&) {};
+ };
+
+ struct H {
+ A a1;
+ G g;
+ A a2;
+ H() : g(a1) {}
+ H(int) : g(a2) {}
+ };
+
+ struct I {
+ I(int*) {}
+ };
+
+ struct J : public I {
+ int *a;
+ int *b;
+ int c;
+ J() : I((a = new int(5))), b(a), c(*a) {}
+ };
+
+ struct K {
+ int a = (b = 5);
+ int b = b + 5;
+ };
+
+ struct L {
+ int a = (b = 5);
+ int b = b + 5; // expected-warning{{field 'b' is uninitialized when used here}}
+ L() : a(5) {} // expected-note{{during field initialization in this constructor}}
+ };
+
+ struct M { };
+
+ struct N : public M {
+ int a;
+ int b;
+ N() : b(a) { } // expected-warning{{field 'a' is uninitialized when used here}}
+ };
+
+ struct O {
+ int x = 42;
+ int get() { return x; }
+ };
+
+ struct P {
+ O o;
+ int x = o.get();
+ P() : x(o.get()) { }
+ };
+
+ struct Q {
+ int a;
+ int b;
+ int &c;
+ Q() :
+ a(c = 5), // expected-warning{{reference 'c' is not yet bound to a value when used here}}
+ b(c), // expected-warning{{reference 'c' is not yet bound to a value when used here}}
+ c(a) {}
+ };
+
+ struct R {
+ int a;
+ int b;
+ int c;
+ int d = a + b + c;
+ R() : a(c = 5), b(c), c(a) {}
+ };
+}
+
+namespace base_class {
+ struct A {
+ A (int) {}
+ };
+
+ struct B : public A {
+ int x;
+ B() : A(x) {} // expected-warning{{field 'x' is uninitialized when used here}}
+ };
+
+ struct C : public A {
+ int x;
+ int y;
+ C() : A(y = 4), x(y) {}
+ };
+}
diff --git a/test/SemaCXX/unknown-type-name.cpp b/test/SemaCXX/unknown-type-name.cpp
index ce5972b..f2c84df 100644
--- a/test/SemaCXX/unknown-type-name.cpp
+++ b/test/SemaCXX/unknown-type-name.cpp
@@ -93,14 +93,14 @@ template<typename T> int A<T>::h(T::type x, char) {} // expected-error{{missing
template<typename T> int h(T::type, int); // expected-error{{missing 'typename'}}
template<typename T> int h(T::type x, char); // expected-error{{missing 'typename'}}
-template<typename T> int junk1(T::junk); // expected-error{{declared as a template}}
+template<typename T> int junk1(T::junk); // expected-warning{{variable templates are a C++1y extension}}
template<typename T> int junk2(T::junk) throw(); // expected-error{{missing 'typename'}}
template<typename T> int junk3(T::junk) = delete; // expected-error{{missing 'typename'}} expected-warning{{C++11}}
template<typename T> int junk4(T::junk j); // expected-error{{missing 'typename'}}
// FIXME: We can tell this was intended to be a function because it does not
// have a dependent nested name specifier.
-template<typename T> int i(T::type, int()); // expected-error{{variable 'i' declared as a template}}
+template<typename T> int i(T::type, int()); // expected-warning{{variable templates are a C++1y extension}}
// FIXME: We know which type specifier should have been specified here. Provide
// a fix-it to add 'typename A<T>::type'
diff --git a/test/SemaCXX/using-decl-1.cpp b/test/SemaCXX/using-decl-1.cpp
index ebe97f6..24d92f1 100644
--- a/test/SemaCXX/using-decl-1.cpp
+++ b/test/SemaCXX/using-decl-1.cpp
@@ -118,3 +118,45 @@ namespace foo
using ::foo::Class1::Function; // expected-error{{incomplete type 'foo::Class1' named in nested name specifier}}
};
}
+
+// Don't suggest non-typenames for positions requiring typenames.
+namespace using_suggestion_tyname_val {
+namespace N { void FFF() {} }
+using typename N::FFG; // expected-error {{no member named 'FFG' in namespace 'using_suggestion_tyname_val::N'}}
+}
+
+namespace using_suggestion_member_tyname_val {
+class CCC { public: void AAA() { } };
+class DDD : public CCC { public: using typename CCC::AAB; }; // expected-error {{no member named 'AAB' in 'using_suggestion_member_tyname_val::CCC'}}
+}
+
+namespace using_suggestion_tyname_val_dropped_specifier {
+void FFF() {}
+namespace N { }
+using typename N::FFG; // expected-error {{no member named 'FFG' in namespace 'using_suggestion_tyname_val_dropped_specifier::N'}}
+}
+
+// Currently hints aren't provided to drop out the incorrect M::.
+namespace using_suggestion_ty_dropped_nested_specifier {
+namespace N {
+class AAA {}; // expected-note {{'N::AAA' declared here}}
+namespace M { }
+}
+using N::M::AAA; // expected-error {{no member named 'AAA' in namespace 'using_suggestion_ty_dropped_nested_specifier::N::M'; did you mean 'N::AAA'?}}
+}
+
+namespace using_suggestion_tyname_ty_dropped_nested_specifier {
+namespace N {
+class AAA {}; // expected-note {{'N::AAA' declared here}}
+namespace M { }
+}
+using typename N::M::AAA; // expected-error {{no member named 'AAA' in namespace 'using_suggestion_tyname_ty_dropped_nested_specifier::N::M'; did you mean 'N::AAA'?}}
+}
+
+namespace using_suggestion_val_dropped_nested_specifier {
+namespace N {
+void FFF() {} // expected-note {{'N::FFF' declared here}}
+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'?}}
+}
diff --git a/test/SemaCXX/using-decl-templates.cpp b/test/SemaCXX/using-decl-templates.cpp
index 2f8abca..8314688 100644
--- a/test/SemaCXX/using-decl-templates.cpp
+++ b/test/SemaCXX/using-decl-templates.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
template<typename T> struct A {
void f() { }
@@ -80,3 +80,15 @@ namespace PR10883 {
void foo(const Container& current); // expected-error {{unknown type name 'Container'}}
};
}
+
+template<typename T> class UsingTypenameNNS {
+ using typename T::X;
+ typename X::X x;
+};
+
+namespace aliastemplateinst {
+ template<typename T> struct A { };
+ template<typename T> using APtr = A<T*>; // expected-note{{previous use is here}}
+
+ template struct APtr<int>; // expected-error{{elaborated type refers to a non-tag type}}
+}
diff --git a/test/SemaCXX/vararg-non-pod.cpp b/test/SemaCXX/vararg-non-pod.cpp
index da06d95..56dafc4 100644
--- a/test/SemaCXX/vararg-non-pod.cpp
+++ b/test/SemaCXX/vararg-non-pod.cpp
@@ -17,6 +17,10 @@ void t1()
g(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
g(10, version);
+
+ void (*ptr)(int, ...) = g;
+ ptr(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
+ ptr(10, version);
}
void t2()
@@ -25,9 +29,17 @@ void t2()
c.g(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
c.g(10, version);
-
+
+ void (C::*ptr)(int, ...) = &C::g;
+ (c.*ptr)(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
+ (c.*ptr)(10, version);
+
C::h(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
C::h(10, version);
+
+ void (*static_ptr)(int, ...) = &C::h;
+ static_ptr(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
+ static_ptr(10, version);
}
int (^block)(int, ...);
@@ -141,3 +153,39 @@ namespace t10 {
s(f);
}
}
+
+namespace t11 {
+ typedef void(*function_ptr)(int, ...);
+ typedef void(C::*member_ptr)(int, ...);
+ typedef void(^block_ptr)(int, ...);
+
+ function_ptr get_f_ptr();
+ member_ptr get_m_ptr();
+ block_ptr get_b_ptr();
+
+ function_ptr arr_f_ptr[5];
+ member_ptr arr_m_ptr[5];
+ block_ptr arr_b_ptr[5];
+
+ void test() {
+ C c(10);
+
+ (get_f_ptr())(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
+ (get_f_ptr())(10, version);
+
+ (c.*get_m_ptr())(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
+ (c.*get_m_ptr())(10, version);
+
+ (get_b_ptr())(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}}
+ (get_b_ptr())(10, version);
+
+ (arr_f_ptr[3])(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
+ (arr_f_ptr[3])(10, version);
+
+ (c.*arr_m_ptr[3])(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
+ (c.*arr_m_ptr[3])(10, version);
+
+ (arr_b_ptr[3])(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}}
+ (arr_b_ptr[3])(10, version);
+ }
+}
diff --git a/test/SemaCXX/vector.cpp b/test/SemaCXX/vector.cpp
index 4d2d064..7957c23 100644
--- a/test/SemaCXX/vector.cpp
+++ b/test/SemaCXX/vector.cpp
@@ -37,7 +37,7 @@ void f2_test(char16 c16, longlong16 ll16, char16_e c16e, longlong16_e ll16e) {
}
// Test the conditional operator with vector types.
-void conditional(bool Cond, char16 c16, longlong16 ll16, char16_e c16e,
+void conditional(bool Cond, char16 c16, longlong16 ll16, char16_e c16e,
longlong16_e ll16e) {
// Conditional operators with the same type.
__typeof__(Cond? c16 : c16) *c16p1 = &c16;
@@ -105,11 +105,11 @@ struct convertible_to { // expected-note 3 {{candidate function (the implicit co
operator T() const;
};
-void test_implicit_conversions(bool Cond, char16 c16, longlong16 ll16,
+void test_implicit_conversions(bool Cond, char16 c16, longlong16 ll16,
char16_e c16e, longlong16_e ll16e,
- convertible_to<char16> to_c16,
- convertible_to<longlong16> to_ll16,
- convertible_to<char16_e> to_c16e,
+ convertible_to<char16> to_c16,
+ convertible_to<longlong16> to_ll16,
+ convertible_to<char16_e> to_c16e,
convertible_to<longlong16_e> to_ll16e,
convertible_to<char16&> rto_c16,
convertible_to<char16_e&> rto_c16e) {
@@ -183,7 +183,7 @@ void test_implicit_conversions(bool Cond, char16 c16, longlong16 ll16,
(void)(Cond? to_c16 : to_c16e);
(void)(Cond? to_ll16e : to_ll16);
-
+
// These 2 are convertable with -flax-vector-conversions (default)
(void)(Cond? to_c16 : to_ll16);
(void)(Cond? to_c16e : to_ll16e);
@@ -278,3 +278,10 @@ void test_pseudo_dtor(fltx4 *f) {
(*f).~fltx4();
test_pseudo_dtor_tmpl(f);
}
+
+// PR16204
+typedef __attribute__((ext_vector_type(4))) int vi4;
+const int &reference_to_vec_element = vi4(1).x;
+
+// PR12649
+typedef bool bad __attribute__((__vector_size__(16))); // expected-error {{invalid vector element type 'bool'}}
diff --git a/test/SemaCXX/virtual-base-used.cpp b/test/SemaCXX/virtual-base-used.cpp
index d147b13..04518ce 100644
--- a/test/SemaCXX/virtual-base-used.cpp
+++ b/test/SemaCXX/virtual-base-used.cpp
@@ -13,19 +13,19 @@ struct D : public virtual B {
virtual void foo();
~D();
};
-void D::foo() { // expected-note {{implicit default destructor for 'B' first required here}}
+void D::foo() { // expected-note {{implicit destructor for 'B' first required here}}
}
struct E : public virtual A {
NoDestroy x; // expected-error {{field of type 'NoDestroy' has private destructor}}
};
-struct F : public E { // expected-note {{implicit default destructor for 'E' first required here}}
+struct F : public E { // expected-note {{implicit destructor for 'E' first required here}}
};
struct G : public virtual F {
virtual void foo();
~G();
};
-void G::foo() { // expected-note {{implicit default destructor for 'F' first required here}}
+void G::foo() { // expected-note {{implicit destructor for 'F' first required here}}
}
struct H : public virtual A {
@@ -38,5 +38,5 @@ struct J : public I {
virtual void foo();
~J();
};
-void J::foo() { // expected-note {{implicit default destructor for 'H' first required here}}
+void J::foo() { // expected-note {{implicit destructor for 'H' first required here}}
}
diff --git a/test/SemaCXX/virtual-member-functions-key-function.cpp b/test/SemaCXX/virtual-member-functions-key-function.cpp
index 09a30b9..80ce029 100644
--- a/test/SemaCXX/virtual-member-functions-key-function.cpp
+++ b/test/SemaCXX/virtual-member-functions-key-function.cpp
@@ -4,7 +4,7 @@ struct A {
};
struct B : A { // expected-error {{no suitable member 'operator delete' in 'B'}}
- B() { } // expected-note {{implicit default destructor for 'B' first required here}}
+ B() { } // expected-note {{implicit destructor for 'B' first required here}}
void operator delete(void *, int); // expected-note {{'operator delete' declared here}}
};
@@ -14,7 +14,7 @@ struct C : A { // expected-error {{no suitable member 'operator delete' in 'C'}
void f() {
(void)new B;
- (void)new C; // expected-note {{implicit default destructor for 'C' first required here}}
+ (void)new C; // expected-note {{implicit destructor for 'C' first required here}}
}
// Make sure that the key-function computation is consistent when the
diff --git a/test/SemaCXX/virtual-override-x86.cpp b/test/SemaCXX/virtual-override-x86.cpp
index ad70d3f..75d8af3 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
+// RUN: %clang_cc1 -triple=i686-pc-unknown -fsyntax-only -verify %s -std=c++11 -cxx-abi microsoft
namespace PR14339 {
class A {
@@ -28,6 +28,6 @@ namespace PR14339 {
class F : public E {
public:
- void g(); // expected-error{{virtual function 'g' has different calling convention attributes ('void ()') than the function it overrides (which has calling convention 'void () __attribute__((stdcall))'}}
+ void g(); // expected-error{{virtual function 'g' has different calling convention attributes ('void () __attribute__((thiscall))') than the function it overrides (which has calling convention 'void () __attribute__((stdcall))'}}
};
}
diff --git a/test/SemaCXX/virtuals.cpp b/test/SemaCXX/virtuals.cpp
index a340e9d..6b8231d 100644
--- a/test/SemaCXX/virtuals.cpp
+++ b/test/SemaCXX/virtuals.cpp
@@ -45,3 +45,9 @@ namespace rdar9670557 {
func *h = 0;
};
}
+
+namespace pr8264 {
+ struct Test {
+ virtual virtual void func(); // expected-warning {{duplicate 'virtual' declaration specifier}}
+ };
+}
diff --git a/test/SemaCXX/warn-consumed-analysis.cpp b/test/SemaCXX/warn-consumed-analysis.cpp
new file mode 100644
index 0000000..64fdc00
--- /dev/null
+++ b/test/SemaCXX/warn-consumed-analysis.cpp
@@ -0,0 +1,795 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wconsumed -fcxx-exceptions -std=c++11 %s
+
+// TODO: Switch to using macros for the expected warnings.
+
+#define CALLABLE_WHEN(...) __attribute__ ((callable_when(__VA_ARGS__)))
+#define CONSUMABLE(state) __attribute__ ((consumable(state)))
+#define PARAM_TYPESTATE(state) __attribute__ ((param_typestate(state)))
+#define RETURN_TYPESTATE(state) __attribute__ ((return_typestate(state)))
+#define SET_TYPESTATE(state) __attribute__ ((set_typestate(state)))
+#define TEST_TYPESTATE(state) __attribute__ ((test_typestate(state)))
+
+typedef decltype(nullptr) nullptr_t;
+
+template <typename T>
+class CONSUMABLE(unconsumed) ConsumableClass {
+ T var;
+
+public:
+ ConsumableClass();
+ ConsumableClass(nullptr_t p) RETURN_TYPESTATE(consumed);
+ ConsumableClass(T val) RETURN_TYPESTATE(unconsumed);
+ ConsumableClass(ConsumableClass<T> &other);
+ ConsumableClass(ConsumableClass<T> &&other);
+
+ ConsumableClass<T>& operator=(ConsumableClass<T> &other);
+ ConsumableClass<T>& operator=(ConsumableClass<T> &&other);
+ ConsumableClass<T>& operator=(nullptr_t) SET_TYPESTATE(consumed);
+
+ template <typename U>
+ ConsumableClass<T>& operator=(ConsumableClass<U> &other);
+
+ template <typename U>
+ ConsumableClass<T>& operator=(ConsumableClass<U> &&other);
+
+ void operator()(int a) SET_TYPESTATE(consumed);
+ void operator*() const CALLABLE_WHEN("unconsumed");
+ void unconsumedCall() const CALLABLE_WHEN("unconsumed");
+ void callableWhenUnknown() const CALLABLE_WHEN("unconsumed", "unknown");
+
+ bool isValid() const TEST_TYPESTATE(unconsumed);
+ operator bool() const TEST_TYPESTATE(unconsumed);
+ bool operator!=(nullptr_t) const TEST_TYPESTATE(unconsumed);
+ bool operator==(nullptr_t) const TEST_TYPESTATE(consumed);
+
+ void constCall() const;
+ void nonconstCall();
+
+ void consume() SET_TYPESTATE(consumed);
+ void unconsume() SET_TYPESTATE(unconsumed);
+};
+
+class CONSUMABLE(unconsumed) DestructorTester {
+public:
+ DestructorTester() RETURN_TYPESTATE(unconsumed);
+ DestructorTester(int);
+
+ void operator*() CALLABLE_WHEN("unconsumed");
+
+ ~DestructorTester() CALLABLE_WHEN("consumed");
+};
+
+void baf0(const ConsumableClass<int> var);
+void baf1(const ConsumableClass<int> &var);
+void baf2(const ConsumableClass<int> *var);
+
+void baf3(ConsumableClass<int> var);
+void baf4(ConsumableClass<int> &var);
+void baf5(ConsumableClass<int> *var);
+void baf6(ConsumableClass<int> &&var);
+
+ConsumableClass<int> returnsUnconsumed() {
+ return ConsumableClass<int>(); // expected-warning {{return value not in expected state; expected 'unconsumed', observed 'consumed'}}
+}
+
+ConsumableClass<int> returnsConsumed() RETURN_TYPESTATE(consumed);
+ConsumableClass<int> returnsConsumed() {
+ return ConsumableClass<int>();
+}
+
+ConsumableClass<int> returnsUnknown() RETURN_TYPESTATE(unknown);
+
+void testInitialization() {
+ ConsumableClass<int> var0;
+ ConsumableClass<int> var1 = ConsumableClass<int>();
+
+ var0 = ConsumableClass<int>();
+
+ *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}}
+
+ if (var0.isValid()) {
+ *var0;
+ *var1;
+
+ } else {
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
+ }
+}
+
+void testDestruction() {
+ DestructorTester D0(42), D1(42);
+
+ *D0;
+ *D1;
+
+ DestructorTester D2;
+ *D2;
+
+ 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}}
+}
+
+void testTempValue() {
+ *ConsumableClass<int>(); // expected-warning {{invalid invocation of method 'operator*' on a temporary object while it is in the 'consumed' state}}
+}
+
+void testSimpleRValueRefs() {
+ ConsumableClass<int> var0;
+ ConsumableClass<int> var1(42);
+
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
+ *var1;
+
+ var0 = static_cast<ConsumableClass<int>&&>(var1);
+
+ *var0;
+ *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
+}
+
+void testIfStmt() {
+ ConsumableClass<int> var;
+
+ if (var.isValid()) {
+ *var;
+ } else {
+ *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
+ }
+
+ if (!var.isValid()) {
+ *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
+ } else {
+ *var;
+ }
+
+ if (var) {
+ // Empty
+ } else {
+ *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
+ }
+
+ if (var != nullptr) {
+ // Empty
+ } else {
+ *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
+ }
+
+ if (var == nullptr) {
+ *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
+ } else {
+ // Empty
+ }
+}
+
+void testComplexConditionals0() {
+ ConsumableClass<int> var0, var1, var2;
+
+ if (var0 && var1) {
+ *var0;
+ *var1;
+
+ } else {
+ *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}}
+ }
+
+ if (var0 || var1) {
+ *var0;
+ *var1;
+
+ } else {
+ *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}}
+ }
+
+ if (var0 && !var1) {
+ *var0;
+ *var1;
+
+ } else {
+ *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}}
+ }
+
+ if (var0 || !var1) {
+ *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}}
+
+ } else {
+ *var0;
+ *var1;
+ }
+
+ if (!var0 && !var1) {
+ *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}}
+
+ } else {
+ *var0;
+ *var1;
+ }
+
+ if (!var0 || !var1) {
+ *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}}
+
+ } else {
+ *var0;
+ *var1;
+ }
+
+ if (!(var0 && var1)) {
+ *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}}
+
+ } else {
+ *var0;
+ *var1;
+ }
+
+ if (!(var0 || var1)) {
+ *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}}
+
+ } else {
+ *var0;
+ *var1;
+ }
+
+ if (var0 && var1 && var2) {
+ *var0;
+ *var1;
+ *var2;
+
+ } else {
+ *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; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}}
+ }
+
+#if 0
+ // FIXME: Get this test to pass.
+ if (var0 || var1 || var2) {
+ *var0;
+ *var1;
+ *var2;
+
+ } else {
+ *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; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}}
+ }
+#endif
+}
+
+void testComplexConditionals1() {
+ ConsumableClass<int> var0, var1, var2;
+
+ // Coerce all variables into the unknown state.
+ baf4(var0);
+ baf4(var1);
+ baf4(var2);
+
+ if (var0 && var1) {
+ *var0;
+ *var1;
+
+ } else {
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
+ *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
+ }
+
+ if (var0 || var1) {
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
+ *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
+
+ } else {
+ *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}}
+ }
+
+ if (var0 && !var1) {
+ *var0;
+ *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
+
+ } else {
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
+ *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
+ }
+
+ if (var0 || !var1) {
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
+ *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
+
+ } else {
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
+ *var1;
+ }
+
+ if (!var0 && !var1) {
+ *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}}
+
+ } else {
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
+ *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
+ }
+
+ if (!(var0 || var1)) {
+ *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}}
+
+ } else {
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
+ *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
+ }
+
+ if (!var0 || !var1) {
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
+ *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
+
+ } else {
+ *var0;
+ *var1;
+ }
+
+ if (!(var0 && var1)) {
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
+ *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
+
+ } else {
+ *var0;
+ *var1;
+ }
+
+ if (var0 && var1 && var2) {
+ *var0;
+ *var1;
+ *var2;
+
+ } else {
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
+ *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
+ *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'unknown' state}}
+ }
+
+#if 0
+ // FIXME: Get this test to pass.
+ if (var0 || var1 || var2) {
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
+ *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
+ *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'unknown' state}}
+
+ } else {
+ *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; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}}
+ }
+#endif
+}
+
+void testStateChangeInBranch() {
+ ConsumableClass<int> var;
+
+ // Make var enter the 'unknown' state.
+ baf4(var);
+
+ if (!var) {
+ var = ConsumableClass<int>(42);
+ }
+
+ *var;
+}
+
+void testFunctionParam(ConsumableClass<int> param) {
+
+ if (param.isValid()) {
+ *param;
+ } else {
+ *param;
+ }
+
+ param = nullptr;
+ *param; // expected-warning {{invocation of method 'operator*' on object 'param' while it is in the 'consumed' state}}
+}
+
+void testParamReturnTypestateCallee(bool cond, ConsumableClass<int> &Param RETURN_TYPESTATE(unconsumed)) { // expected-warning {{parameter 'Param' not in expected state when the function returns: expected 'unconsumed', observed 'consumed'}}
+
+ if (cond) {
+ Param.consume();
+ return; // expected-warning {{parameter 'Param' not in expected state when the function returns: expected 'unconsumed', observed 'consumed'}}
+ }
+
+ Param.consume();
+}
+
+void testParamReturnTypestateCaller() {
+ ConsumableClass<int> var;
+
+ testParamReturnTypestateCallee(true, var);
+
+ *var;
+}
+
+void testParamTypestateCallee(ConsumableClass<int> Param0 PARAM_TYPESTATE(consumed),
+ ConsumableClass<int> &Param1 PARAM_TYPESTATE(consumed)) {
+
+ *Param0; // expected-warning {{invalid invocation of method 'operator*' on object 'Param0' while it is in the 'consumed' state}}
+ *Param1; // expected-warning {{invalid invocation of method 'operator*' on object 'Param1' while it is in the 'consumed' state}}
+}
+
+void testParamTypestateCaller() {
+ ConsumableClass<int> Var0, Var1(42);
+
+ testParamTypestateCallee(Var0, Var1); // expected-warning {{argument not in expected state; expected 'consumed', observed 'unconsumed'}}
+}
+
+void baf3(ConsumableClass<int> var) {
+ *var;
+}
+
+void baf4(ConsumableClass<int> &var) {
+ *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
+}
+
+void baf6(ConsumableClass<int> &&var) {
+ *var;
+}
+
+void testCallingConventions() {
+ ConsumableClass<int> var(42);
+
+ baf0(var);
+ *var;
+
+ baf1(var);
+ *var;
+
+ baf2(&var);
+ *var;
+
+ baf4(var);
+ *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
+
+ var = ConsumableClass<int>(42);
+ baf5(&var);
+ *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
+
+ var = ConsumableClass<int>(42);
+ baf6(static_cast<ConsumableClass<int>&&>(var));
+ *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
+}
+
+void testConstAndNonConstMemberFunctions() {
+ ConsumableClass<int> var(42);
+
+ var.constCall();
+ *var;
+
+ var.nonconstCall();
+ *var;
+}
+
+void testFunctionParam0(ConsumableClass<int> param) {
+ *param;
+}
+
+void testFunctionParam1(ConsumableClass<int> &param) {
+ *param; // expected-warning {{invalid invocation of method 'operator*' on object 'param' while it is in the 'unknown' state}}
+}
+
+void testReturnStates() {
+ ConsumableClass<int> var;
+
+ var = returnsUnconsumed();
+ *var;
+
+ var = returnsConsumed();
+ *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
+}
+
+void testCallableWhen() {
+ ConsumableClass<int> var(42);
+
+ *var;
+
+ baf4(var);
+
+ var.callableWhenUnknown();
+}
+
+void testMoveAsignmentish() {
+ ConsumableClass<int> var0;
+ ConsumableClass<long> var1(42);
+
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
+ *var1;
+
+ var0 = static_cast<ConsumableClass<long>&&>(var1);
+
+ *var0;
+ *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
+
+ var1 = ConsumableClass<long>(42);
+ var1 = nullptr;
+ *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
+}
+
+void testConditionalMerge() {
+ ConsumableClass<int> var;
+
+ if (var.isValid()) {
+ // Empty
+ }
+
+ *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
+
+ if (var.isValid()) {
+ // Empty
+ } else {
+ // Empty
+ }
+
+ *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
+}
+
+void testSetTypestate() {
+ ConsumableClass<int> var(42);
+
+ *var;
+
+ var.consume();
+
+ *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
+
+ var.unconsume();
+
+ *var;
+}
+
+void testConsumes0() {
+ ConsumableClass<int> var(nullptr);
+
+ *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
+}
+
+void testConsumes1() {
+ ConsumableClass<int> var(42);
+
+ var.unconsumedCall();
+ var(6);
+
+ var.unconsumedCall(); // expected-warning {{invalid invocation of method 'unconsumedCall' on object 'var' while it is in the 'consumed' state}}
+}
+
+void testUnreachableBlock() {
+ ConsumableClass<int> var(42);
+
+ if (var) {
+ *var;
+ } else {
+ *var;
+ }
+
+ *var;
+}
+
+
+void testForLoop1() {
+ ConsumableClass<int> var0, var1(42);
+
+ for (int i = 0; i < 10; ++i) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}}
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
+
+ *var1;
+ var1.consume();
+ *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
+ }
+
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
+}
+
+void testWhileLoop1() {
+ int i = 10;
+
+ ConsumableClass<int> var0, var1(42);
+
+ while (i-- > 0) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}}
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
+
+ *var1;
+ var1.consume();
+ *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
+ }
+
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
+}
+
+typedef const int*& IntegerPointerReference;
+void testIsRValueRefishAndCanonicalType(IntegerPointerReference a) {}
+
+namespace ContinueICETest {
+
+bool cond1();
+bool cond2();
+
+static void foo1() {
+ while (cond1()) {
+ if (cond2())
+ continue;
+ }
+}
+
+static void foo2() {
+ while (true) {
+ if (false)
+ continue;
+ }
+}
+
+class runtime_error
+{
+public:
+ virtual ~runtime_error();
+};
+
+void read(bool sf) {
+ while (sf) {
+ if(sf) throw runtime_error();
+ }
+}
+
+} // end namespace ContinueICETest
+
+
+namespace InitializerAssertionFailTest {
+
+class CONSUMABLE(unconsumed) Status {
+ int code;
+
+public:
+ Status() RETURN_TYPESTATE(consumed);
+ Status(int c) RETURN_TYPESTATE(unconsumed);
+
+ Status(const Status &other);
+ Status(Status &&other);
+
+ Status& operator=(const Status &other) CALLABLE_WHEN("unknown", "consumed");
+ Status& operator=(Status &&other) CALLABLE_WHEN("unknown", "consumed");
+
+ bool check() const SET_TYPESTATE(consumed);
+ void ignore() const SET_TYPESTATE(consumed);
+ // Status& markAsChecked() { return *this; }
+
+ void clear() CALLABLE_WHEN("unknown", "consumed") SET_TYPESTATE(consumed);
+
+ ~Status() CALLABLE_WHEN("unknown", "consumed");
+};
+
+
+bool cond();
+Status doSomething();
+void handleStatus(const Status& s RETURN_TYPESTATE(consumed));
+void handleStatusPtr(const Status* s);
+
+void testSimpleTemporaries0() {
+ doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}}
+}
+
+void testSimpleTemporaries1() {
+ doSomething().ignore();
+}
+
+void testSimpleTemporaries2() {
+ handleStatus(doSomething());
+}
+
+void testSimpleTemporaries3() {
+ Status s = doSomething();
+} // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
+
+void testSimpleTemporaries4() {
+ Status s = doSomething();
+ s.check();
+}
+
+void testSimpleTemporaries5() {
+ Status s = doSomething();
+ s.clear(); // expected-warning {{invalid invocation of method 'clear' on object 's' while it is in the 'unconsumed' state}}
+}
+
+void testSimpleTemporaries6() {
+ Status s = doSomething();
+ handleStatus(s);
+}
+
+void testSimpleTemporaries7() {
+ Status s;
+ s = doSomething();
+} // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
+
+void testTemporariesWithConditionals0() {
+ int a;
+
+ Status s = doSomething();
+ if (cond()) a = 0;
+ else a = 1;
+} // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
+
+void testTemporariesWithConditionals1() {
+ int a;
+
+ Status s = doSomething();
+ if (cond()) a = 0;
+ else a = 1;
+ s.ignore();
+}
+
+void testTemporariesWithConditionals2() {
+ int a;
+
+ Status s = doSomething();
+ s.ignore();
+ if (cond()) a = 0;
+ else a = 1;
+}
+
+void testTemporariesWithConditionals3() {
+ Status s = doSomething();
+ if (cond()) {
+ s.check();
+ }
+}
+
+void testTemporariesAndConstructors0() {
+ Status s(doSomething());
+ s.check();
+}
+
+void testTemporariesAndConstructors1() {
+ // Test the copy constructor.
+
+ Status s1 = doSomething();
+ Status s2(s1);
+ s2.check();
+} // expected-warning {{invalid invocation of method '~Status' on object 's1' while it is in the 'unconsumed' state}}
+
+void testTemporariesAndConstructors2() {
+ // Test the move constructor.
+
+ Status s1 = doSomething();
+ Status s2(static_cast<Status&&>(s1));
+ s2.check();
+}
+
+void testTemporariesAndOperators0() {
+ // 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() {
+ // Test the move assignment operator.
+
+ Status s1 = doSomething();
+ Status s2;
+ s2 = static_cast<Status&&>(s1);
+ s2.check();
+}
+
+void testTemporariesAndOperators2() {
+ Status s1 = doSomething();
+ Status s2 = doSomething();
+ s1 = s2; // expected-warning {{invalid invocation of method 'operator=' on object 's1' while it is in the 'unconsumed' state}}
+ s1.check();
+ s2.check();
+}
+
+} // end namespace InitializerAssertionFailTest
+
diff --git a/test/SemaCXX/warn-consumed-parsing.cpp b/test/SemaCXX/warn-consumed-parsing.cpp
new file mode 100644
index 0000000..0a91636
--- /dev/null
+++ b/test/SemaCXX/warn-consumed-parsing.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wconsumed -std=c++11 %s
+
+#define CALLABLE_WHEN(...) __attribute__ ((callable_when(__VA_ARGS__)))
+#define CONSUMABLE(state) __attribute__ ((consumable(state)))
+#define SET_TYPESTATE(state) __attribute__ ((set_typestate(state)))
+#define RETURN_TYPESTATE(state) __attribute__ ((return_typestate(state)))
+#define TEST_TYPESTATE(state) __attribute__ ((test_typestate(state)))
+
+// FIXME: This test is here because the warning is issued by the Consumed
+// analysis, not SemaDeclAttr. The analysis won't run after an error
+// has been issued. Once the attribute propagation for template
+// instantiation has been fixed, this can be moved somewhere else and the
+// definition can be removed.
+int returnTypestateForUnconsumable() RETURN_TYPESTATE(consumed); // expected-warning {{return state set for an unconsumable type 'int'}}
+int returnTypestateForUnconsumable() {
+ return 0;
+}
+
+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}}
+};
+
+int var0 SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to methods}}
+int var1 TEST_TYPESTATE(consumed); // expected-warning {{'test_typestate' attribute only applies to methods}}
+int var2 CALLABLE_WHEN("consumed"); // expected-warning {{'callable_when' attribute only applies to methods}}
+int var3 CONSUMABLE(consumed); // expected-warning {{'consumable' attribute only applies to classes}}
+int var4 RETURN_TYPESTATE(consumed); // expected-warning {{'return_typestate' attribute only applies to functions}}
+
+void function0() SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to methods}}
+void function1() TEST_TYPESTATE(consumed); // expected-warning {{'test_typestate' attribute only applies to methods}}
+void function2() CALLABLE_WHEN("consumed"); // expected-warning {{'callable_when' attribute only applies to methods}}
+void function3() CONSUMABLE(consumed); // expected-warning {{'consumable' attribute only applies to classes}}
+
+class CONSUMABLE(unknown) AttrTester1 {
+ void callableWhen0() CALLABLE_WHEN("unconsumed");
+ void callableWhen1() CALLABLE_WHEN(42); // expected-error {{'callable_when' attribute requires a string}}
+ void callableWhen2() CALLABLE_WHEN("foo"); // expected-warning {{'callable_when' attribute argument not supported: foo}}
+ void consumes() SET_TYPESTATE(consumed);
+ bool testUnconsumed() TEST_TYPESTATE(consumed);
+};
+
+AttrTester1 returnTypestateTester0() RETURN_TYPESTATE(not_a_state); // expected-warning {{'return_typestate' attribute argument not supported: 'not_a_state'}}
+AttrTester1 returnTypestateTester1() RETURN_TYPESTATE(42); // expected-error {{'return_typestate' attribute requires an identifier}}
+
+void returnTypestateTester2(AttrTester1 &Param RETURN_TYPESTATE(unconsumed));
+
+class AttrTester2 {
+ void callableWhen() CALLABLE_WHEN("unconsumed"); // expected-warning {{consumed analysis attribute is attached to member of class 'AttrTester2' which isn't marked as consumable}}
+ void consumes() SET_TYPESTATE(consumed); // expected-warning {{consumed analysis attribute is attached to member of class 'AttrTester2' which isn't marked as consumable}}
+ bool testUnconsumed() TEST_TYPESTATE(consumed); // expected-warning {{consumed analysis attribute is attached to member of class 'AttrTester2' which isn't marked as consumable}}
+};
+
+class CONSUMABLE(42) AttrTester3; // expected-error {{'consumable' attribute requires an identifier}}
diff --git a/test/SemaCXX/warn-dangling-field.cpp b/test/SemaCXX/warn-dangling-field.cpp
index 95f8c61..eb65bd0 100644
--- a/test/SemaCXX/warn-dangling-field.cpp
+++ b/test/SemaCXX/warn-dangling-field.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wdangling-field -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wdangling-field -verify -std=c++11 %s
struct X {
X(int);
@@ -35,3 +35,17 @@ template <typename T> struct S4 {
template struct S4<int>; // no warning from this instantiation
template struct S4<int&>; // expected-note {{in instantiation}}
+
+struct S5 {
+ const X &x; // expected-note {{here}}
+};
+S5 s5 = { 0 }; // ok, lifetime-extended
+
+struct S6 {
+ S5 s5; // expected-note {{here}}
+ S6() : s5 { 0 } {} // expected-warning {{binding reference subobject of member 's5' to a temporary}}
+};
+
+struct S7 : S5 {
+ S7() : S5 { 0 } {} // expected-warning {{binding reference member 'x' to a temporary}}
+};
diff --git a/test/SemaCXX/warn-div-or-rem-by-zero.cpp b/test/SemaCXX/warn-div-or-rem-by-zero.cpp
new file mode 100644
index 0000000..44b877e
--- /dev/null
+++ b/test/SemaCXX/warn-div-or-rem-by-zero.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -verify %s
+// RUN: %clang_cc1 -std=c++11 -verify %s
+// RUN: %clang_cc1 -std=c++1y -verify %s
+
+void div() {
+ (void)(42 / 0); // expected-warning{{division by zero is undefined}}
+ (void)(42 / false); // expected-warning{{division by zero is undefined}}
+ (void)(42 / !1); // expected-warning{{division by zero is undefined}}
+ (void)(42 / (1 - 1)); // expected-warning{{division by zero is undefined}}
+ (void)(42 / !(1 + 1)); // expected-warning{{division by zero is undefined}}
+ (void)(42 / (int)(0.0)); // expected-warning{{division by zero is undefined}}
+}
+
+void rem() {
+ (void)(42 % 0); // expected-warning{{remainder by zero is undefined}}
+ (void)(42 % false); // expected-warning{{remainder by zero is undefined}}
+ (void)(42 % !1); // expected-warning{{remainder by zero is undefined}}
+ (void)(42 % (1 - 1)); // expected-warning{{remainder by zero is undefined}}
+ (void)(42 % !(1 + 1)); // expected-warning{{remainder by zero is undefined}}
+ (void)(42 % (int)(0.0)); // expected-warning{{remainder by zero is undefined}}
+}
diff --git a/test/SemaCXX/warn-empty-body.cpp b/test/SemaCXX/warn-empty-body.cpp
index d643ced..d3aaac1 100644
--- a/test/SemaCXX/warn-empty-body.cpp
+++ b/test/SemaCXX/warn-empty-body.cpp
@@ -269,3 +269,8 @@ void test_template_inst(int x) {
test_template<double>(x);
}
+#define IDENTITY(a) a
+void test7(int x, int y) {
+ if (x) IDENTITY(); // no-warning
+}
+
diff --git a/test/SemaCXX/warn-func-not-needed.cpp b/test/SemaCXX/warn-func-not-needed.cpp
index d51c173..65721f4 100644
--- a/test/SemaCXX/warn-func-not-needed.cpp
+++ b/test/SemaCXX/warn-func-not-needed.cpp
@@ -42,3 +42,12 @@ namespace test4 {
g<int>();
}
}
+
+namespace test4 {
+ static void func();
+ void bar() {
+ void func();
+ func();
+ }
+ static void func() {}
+}
diff --git a/test/SemaCXX/warn-global-constructors.cpp b/test/SemaCXX/warn-global-constructors.cpp
index 6330958..f57f0de 100644
--- a/test/SemaCXX/warn-global-constructors.cpp
+++ b/test/SemaCXX/warn-global-constructors.cpp
@@ -95,3 +95,9 @@ namespace pr8095 {
static Bar b;
}
}
+
+namespace referencemember {
+ struct A { int &a; };
+ int a;
+ A b = { a };
+}
diff --git a/test/SemaCXX/warn-logical-not-compare.cpp b/test/SemaCXX/warn-logical-not-compare.cpp
new file mode 100644
index 0000000..3ecce47
--- /dev/null
+++ b/test/SemaCXX/warn-logical-not-compare.cpp
@@ -0,0 +1,194 @@
+// RUN: %clang_cc1 -fsyntax-only -Wlogical-not-parentheses -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wlogical-not-parentheses -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+
+bool getBool();
+int getInt();
+
+bool test1(int i1, int i2, bool b1, bool b2) {
+ bool ret;
+
+ ret = !i1 == i2;
+ // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
+ // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
+ // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
+ // CHECK: to evaluate the comparison first
+ // CHECK: fix-it:"{{.*}}":{10:10-10:10}:"("
+ // CHECK: fix-it:"{{.*}}":{10:18-10:18}:")"
+ // CHECK: to silence this warning
+ // CHECK: fix-it:"{{.*}}":{10:9-10:9}:"("
+ // CHECK: fix-it:"{{.*}}":{10:12-10:12}:")"
+
+ ret = !i1 != i2;
+ //expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
+ // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
+ // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
+ // CHECK: to evaluate the comparison first
+ // CHECK: fix-it:"{{.*}}":{21:10-21:10}:"("
+ // CHECK: fix-it:"{{.*}}":{21:18-21:18}:")"
+ // CHECK: to silence this warning
+ // CHECK: fix-it:"{{.*}}":{21:9-21:9}:"("
+ // CHECK: fix-it:"{{.*}}":{21:12-21:12}:")"
+
+ ret = !i1 < i2;
+ //expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
+ // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
+ // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
+ // CHECK: to evaluate the comparison first
+ // CHECK: fix-it:"{{.*}}":{32:10-32:10}:"("
+ // CHECK: fix-it:"{{.*}}":{32:17-32:17}:")"
+ // CHECK: to silence this warning
+ // CHECK: fix-it:"{{.*}}":{32:9-32:9}:"("
+ // CHECK: fix-it:"{{.*}}":{32:12-32:12}:")"
+
+ ret = !i1 > i2;
+ //expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
+ // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
+ // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
+ // CHECK: to evaluate the comparison first
+ // CHECK: fix-it:"{{.*}}":{43:10-43:10}:"("
+ // CHECK: fix-it:"{{.*}}":{43:17-43:17}:")"
+ // CHECK: to silence this warning
+ // CHECK: fix-it:"{{.*}}":{43:9-43:9}:"("
+ // CHECK: fix-it:"{{.*}}":{43:12-43:12}:")"
+
+ ret = !i1 <= i2;
+ //expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
+ // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
+ // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
+ // CHECK: to evaluate the comparison first
+ // CHECK: fix-it:"{{.*}}":{54:10-54:10}:"("
+ // CHECK: fix-it:"{{.*}}":{54:18-54:18}:")"
+ // CHECK: to silence this warning
+ // CHECK: fix-it:"{{.*}}":{54:9-54:9}:"("
+ // CHECK: fix-it:"{{.*}}":{54:12-54:12}:")"
+
+ ret = !i1 >= i2;
+ //expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
+ // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
+ // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
+ // CHECK: to evaluate the comparison first
+ // CHECK: fix-it:"{{.*}}":{65:10-65:10}:"("
+ // CHECK: fix-it:"{{.*}}":{65:18-65:18}:")"
+ // CHECK: to silence this warning
+ // CHECK: fix-it:"{{.*}}":{65:9-65:9}:"("
+ // CHECK: fix-it:"{{.*}}":{65:12-65:12}:")"
+
+ ret = i1 == i2;
+ ret = i1 != i2;
+ ret = i1 < i2;
+ ret = i1 > i2;
+ ret = i1 <= i2;
+ ret = i1 >= i2;
+
+ // Warning silenced by parens.
+ ret = (!i1) == i2;
+ ret = (!i1) != i2;
+ ret = (!i1) < i2;
+ ret = (!i1) > i2;
+ ret = (!i1) <= i2;
+ ret = (!i1) >= i2;
+
+ ret = !b1 == b2;
+ ret = !b1 != b2;
+ ret = !b1 < b2;
+ ret = !b1 > b2;
+ ret = !b1 <= b2;
+ ret = !b1 >= b2;
+
+ ret = !getInt() == i1;
+ // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
+ // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
+ // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
+ // CHECK: to evaluate the comparison first
+ // CHECK: fix-it:"{{.*}}":{98:10-98:10}:"("
+ // CHECK: fix-it:"{{.*}}":{98:24-98:24}:")"
+ // CHECK: to silence this warning
+ // CHECK: fix-it:"{{.*}}":{98:9-98:9}:"("
+ // CHECK: fix-it:"{{.*}}":{98:18-98:18}:")"
+
+ ret = (!getInt()) == i1;
+ ret = !getBool() == b1;
+ return ret;
+}
+
+enum E {e1, e2};
+E getE();
+
+bool test2 (E e) {
+ bool ret;
+ ret = e == e1;
+ ret = e == getE();
+ ret = getE() == e1;
+ ret = getE() == getE();
+
+ ret = !e == e1;
+ // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
+ // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
+ // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
+ // CHECK: to evaluate the comparison first
+ // CHECK: fix-it:"{{.*}}":{124:10-124:10}:"("
+ // CHECK: fix-it:"{{.*}}":{124:17-124:17}:")"
+ // CHECK: to silence this warning
+ // CHECK: fix-it:"{{.*}}":{124:9-124:9}:"("
+ // CHECK: fix-it:"{{.*}}":{124:11-124:11}:")"
+
+ ret = !e == getE();
+ // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
+ // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
+ // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
+ // CHECK: to evaluate the comparison first
+ // CHECK: fix-it:"{{.*}}":{135:10-135:10}:"("
+ // CHECK: fix-it:"{{.*}}":{135:21-135:21}:")"
+ // CHECK: to silence this warning
+ // CHECK: fix-it:"{{.*}}":{135:9-135:9}:"("
+ // CHECK: fix-it:"{{.*}}":{135:11-135:11}:")"
+
+ ret = !getE() == e1;
+ // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
+ // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
+ // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
+ // CHECK: to evaluate the comparison first
+ // CHECK: fix-it:"{{.*}}":{146:10-146:10}:"("
+ // CHECK: fix-it:"{{.*}}":{146:22-146:22}:")"
+ // CHECK: to silence this warning
+ // CHECK: fix-it:"{{.*}}":{146:9-146:9}:"("
+ // CHECK: fix-it:"{{.*}}":{146:16-146:16}:")"
+
+ ret = !getE() == getE();
+ // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
+ // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
+ // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
+ // CHECK: to evaluate the comparison first
+ // CHECK: fix-it:"{{.*}}":{157:10-157:10}:"("
+ // CHECK: fix-it:"{{.*}}":{157:26-157:26}:")"
+ // CHECK: to silence this warning
+ // CHECK: fix-it:"{{.*}}":{157:9-157:9}:"("
+ // CHECK: fix-it:"{{.*}}":{157:16-157:16}:")"
+
+ ret = !(e == e1);
+ ret = !(e == getE());
+ ret = !(getE() == e1);
+ ret = !(getE() == getE());
+
+ ret = (!e) == e1;
+ ret = (!e) == getE();
+ ret = (!getE()) == e1;
+ ret = (!getE()) == getE();
+
+ return ret;
+}
+
+bool PR16673(int x) {
+ bool ret;
+ // Make sure we don't emit a fixit for the left paren, but not the right paren.
+#define X(x) x
+ ret = X(!x == 1 && 1);
+ // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
+ // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
+ // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
+ // CHECK: to evaluate the comparison first
+ // CHECK-NOT: fix-it
+ // CHECK: to silence this warning
+ // CHECK-NOT: fix-it
+ return ret;
+}
diff --git a/test/SemaCXX/warn-loop-analysis.cpp b/test/SemaCXX/warn-loop-analysis.cpp
index 627bc51..c666c48 100644
--- a/test/SemaCXX/warn-loop-analysis.cpp
+++ b/test/SemaCXX/warn-loop-analysis.cpp
@@ -152,3 +152,111 @@ void test6() {
for (;x6;);
for (;y;);
}
+
+void test7() {
+ int i;
+ for (;;i++) { // expected-note{{incremented here}}
+ if (true) test7();
+ i++; // expected-warning{{incremented both}}
+ }
+ for (;;i++) { // expected-note{{incremented here}}
+ if (true) break;
+ ++i; // expected-warning{{incremented both}}
+ }
+ for (;;++i) { // expected-note{{incremented here}}
+ while (true) return;
+ i++; // expected-warning{{incremented both}}
+ }
+ for (;;++i) { // expected-note{{incremented here}}
+ ++i; // expected-warning{{incremented both}}
+ }
+
+ for (;;i--) { // expected-note{{decremented here}}
+ if (true) test7();
+ i--; // expected-warning{{decremented both}}
+ }
+ for (;;i--) { // expected-note{{decremented here}}
+ if (true) break;
+ --i; // expected-warning{{decremented both}}
+ }
+ for (;;--i) { // expected-note{{decremented here}}
+ while (true) return;
+ i--; // expected-warning{{decremented both}}
+ }
+ for (;;--i) { // expected-note{{decremented here}}
+ --i; // expected-warning{{decremented both}}
+ }
+
+ // Don't warn when loop is only one statement.
+ for (;;++i)
+ i++;
+ for (;;--i)
+ --i;
+
+ // Don't warn when loop has continue statement.
+ for (;;i++) {
+ if (true) continue;
+ i++;
+ }
+ for (;;i--) {
+ if (true) continue;
+ i--;
+ }
+}
+
+struct iterator {
+ iterator operator++() { return *this; }
+ iterator operator++(int) { return *this; }
+ iterator operator--() { return *this; }
+ iterator operator--(int) { return *this; }
+};
+void test8() {
+ iterator i;
+ for (;;i++) { // expected-note{{incremented here}}
+ if (true) test7();
+ i++; // expected-warning{{incremented both}}
+ }
+ for (;;i++) { // expected-note{{incremented here}}
+ if (true) break;
+ ++i; // expected-warning{{incremented both}}
+ }
+ for (;;++i) { // expected-note{{incremented here}}
+ while (true) return;
+ i++; // expected-warning{{incremented both}}
+ }
+ for (;;++i) { // expected-note{{incremented here}}
+ ++i; // expected-warning{{incremented both}}
+ }
+
+ for (;;i--) { // expected-note{{decremented here}}
+ if (true) test7();
+ i--; // expected-warning{{decremented both}}
+ }
+ for (;;i--) { // expected-note{{decremented here}}
+ if (true) break;
+ --i; // expected-warning{{decremented both}}
+ }
+ for (;;--i) { // expected-note{{decremented here}}
+ while (true) return;
+ i--; // expected-warning{{decremented both}}
+ }
+ for (;;--i) { // expected-note{{decremented here}}
+ --i; // expected-warning{{decremented both}}
+ }
+
+ // Don't warn when loop is only one statement.
+ for (;;++i)
+ i++;
+ for (;;--i)
+ --i;
+
+ // Don't warn when loop has continue statement.
+ for (;;i++) {
+ if (true) continue;
+ i++;
+ }
+ for (;;i--) {
+ if (true) continue;
+ i--;
+ }
+}
diff --git a/test/SemaCXX/warn-member-not-needed.cpp b/test/SemaCXX/warn-member-not-needed.cpp
new file mode 100644
index 0000000..61bb348
--- /dev/null
+++ b/test/SemaCXX/warn-member-not-needed.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wunneeded-member-function %s
+
+namespace {
+ class A {
+ void g() {} // expected-warning {{is not needed and will not be emitted}}
+ template <typename T>
+ void foo() {
+ g();
+ }
+ };
+}
diff --git a/test/SemaCXX/warn-missing-variable-declarations.cpp b/test/SemaCXX/warn-missing-variable-declarations.cpp
index 12af973..ad23e04 100644
--- a/test/SemaCXX/warn-missing-variable-declarations.cpp
+++ b/test/SemaCXX/warn-missing-variable-declarations.cpp
@@ -41,3 +41,9 @@ int CGood1::MGood1;
namespace {
int mgood4;
}
+
+class C {
+ void test() {
+ static int x = 0; // no-warn
+ }
+};
diff --git a/test/SemaCXX/warn-reinterpret-base-class.cpp b/test/SemaCXX/warn-reinterpret-base-class.cpp
index 67902f7..36b8fda 100644
--- a/test/SemaCXX/warn-reinterpret-base-class.cpp
+++ b/test/SemaCXX/warn-reinterpret-base-class.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fdiagnostics-parseable-fixits -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s 2>&1 | FileCheck %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
// PR 13824
class A {
diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp
index bc4b40e..ce6250d 100644
--- a/test/SemaCXX/warn-thread-safety-analysis.cpp
+++ b/test/SemaCXX/warn-thread-safety-analysis.cpp
@@ -11,8 +11,10 @@
#define PT_GUARDED_VAR __attribute__ ((pt_guarded_var))
#define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__)))
#define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__)))
-#define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock_function(__VA_ARGS__)))
-#define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock_function(__VA_ARGS__)))
+#define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock_function(__VA_ARGS__)))
+#define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock_function(__VA_ARGS__)))
+#define ASSERT_EXCLUSIVE_LOCK(...) __attribute__ ((assert_exclusive_lock(__VA_ARGS__)))
+#define ASSERT_SHARED_LOCK(...) __attribute__ ((assert_shared_lock(__VA_ARGS__)))
#define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__)))
#define SHARED_TRYLOCK_FUNCTION(...) __attribute__ ((shared_trylock_function(__VA_ARGS__)))
#define UNLOCK_FUNCTION(...) __attribute__ ((unlock_function(__VA_ARGS__)))
@@ -33,6 +35,9 @@ class __attribute__((lockable)) Mutex {
bool TryLock() __attribute__((exclusive_trylock_function(true)));
bool ReaderTryLock() __attribute__((shared_trylock_function(true)));
void LockWhen(const int &cond) __attribute__((exclusive_lock_function));
+
+ void AssertHeld() ASSERT_EXCLUSIVE_LOCK();
+ void AssertReaderHeld() ASSERT_SHARED_LOCK();
};
class __attribute__((scoped_lockable)) MutexLock {
@@ -75,6 +80,7 @@ public:
T* get() const { return ptr_; }
T* operator->() const { return ptr_; }
T& operator*() const { return *ptr_; }
+ T& operator[](int i) const { return ptr_[i]; }
private:
T* ptr_;
@@ -102,14 +108,14 @@ class MutexWrapper {
public:
Mutex mu;
int x __attribute__((guarded_by(mu)));
- void MyLock() __attribute__((exclusive_lock_function(mu)));
+ void MyLock() __attribute__((exclusive_lock_function(mu)));
};
MutexWrapper sls_mw;
void sls_fun_0() {
sls_mw.mu.Lock();
- sls_mw.x = 5;
+ sls_mw.x = 5;
sls_mw.mu.Unlock();
}
@@ -3069,44 +3075,6 @@ void Foo::test1() {
#endif
}
-
-void Foo::test2() {
-/* FIXME: these tests depend on changes to the CFG.
- *
- if (mu_.TryLock() && c) {
- a = 0;
- unlock();
- }
- else return;
-
- if (c && mu_.TryLock()) {
- a = 0;
- unlock();
- }
- else return;
-
- if (!(mu_.TryLock() && c))
- return;
- a = 0;
- unlock();
-
- if (!(c && mu_.TryLock()))
- return;
- a = 0;
- unlock();
-
- if (!(mu_.TryLock() == 0) && c) {
- a = 0;
- unlock();
- }
-
- if (!mu_.TryLock() || c)
- return;
- a = 0;
- unlock();
-*/
-}
-
} // end namespace TryLockEqTest
@@ -3985,3 +3953,364 @@ private:
} // end namespace LockUnlockFunctionTest
+
+namespace AssertHeldTest {
+
+class Foo {
+public:
+ int c;
+ int a GUARDED_BY(mu_);
+ Mutex mu_;
+
+ void test1() {
+ mu_.AssertHeld();
+ int b = a;
+ a = 0;
+ }
+
+ void test2() {
+ mu_.AssertReaderHeld();
+ int b = a;
+ a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ }
+
+ void test3() {
+ if (c) {
+ mu_.AssertHeld();
+ }
+ else {
+ mu_.AssertHeld();
+ }
+ int b = a;
+ a = 0;
+ }
+
+ void test4() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
+ mu_.AssertHeld();
+ int b = a;
+ a = 0;
+ }
+
+ void test5() UNLOCK_FUNCTION(mu_) {
+ mu_.AssertHeld();
+ mu_.Unlock();
+ }
+
+ void test6() {
+ mu_.AssertHeld();
+ mu_.Unlock();
+ } // should this be a warning?
+
+ void test7() {
+ if (c) {
+ mu_.AssertHeld();
+ }
+ else {
+ mu_.Lock();
+ }
+ int b = a;
+ a = 0;
+ mu_.Unlock();
+ }
+
+ void test8() {
+ if (c) {
+ mu_.Lock();
+ }
+ else {
+ mu_.AssertHeld();
+ }
+ int b = a;
+ a = 0;
+ mu_.Unlock();
+ }
+
+ void test9() {
+ if (c) {
+ mu_.AssertHeld();
+ }
+ else {
+ mu_.Lock(); // expected-note {{mutex acquired here}}
+ }
+ } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+
+ void test10() {
+ if (c) {
+ mu_.Lock(); // expected-note {{mutex acquired here}}
+ }
+ else {
+ mu_.AssertHeld();
+ }
+ } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+
+ void assertMu() ASSERT_EXCLUSIVE_LOCK(mu_);
+
+ void test11() {
+ assertMu();
+ int b = a;
+ a = 0;
+ }
+};
+
+} // end namespace AssertHeldTest
+
+
+namespace LogicalConditionalTryLock {
+
+class Foo {
+public:
+ Mutex mu;
+ int a GUARDED_BY(mu);
+ bool c;
+
+ bool newc();
+
+ void test1() {
+ if (c && mu.TryLock()) {
+ a = 0;
+ mu.Unlock();
+ }
+ }
+
+ void test2() {
+ bool b = mu.TryLock();
+ if (c && b) {
+ a = 0;
+ mu.Unlock();
+ }
+ }
+
+ void test3() {
+ if (c || !mu.TryLock())
+ return;
+ a = 0;
+ mu.Unlock();
+ }
+
+ void test4() {
+ while (c && mu.TryLock()) {
+ a = 0;
+ c = newc();
+ mu.Unlock();
+ }
+ }
+
+ void test5() {
+ while (c) {
+ if (newc() || !mu.TryLock())
+ break;
+ a = 0;
+ mu.Unlock();
+ }
+ }
+
+ void test6() {
+ mu.Lock();
+ do {
+ a = 0;
+ mu.Unlock();
+ } while (newc() && mu.TryLock());
+ }
+
+ void test7() {
+ for (bool b = mu.TryLock(); c && b;) {
+ a = 0;
+ mu.Unlock();
+ }
+ }
+
+ void test8() {
+ if (c && newc() && mu.TryLock()) {
+ a = 0;
+ mu.Unlock();
+ }
+ }
+
+ void test9() {
+ if (!(c && newc() && mu.TryLock()))
+ return;
+ a = 0;
+ mu.Unlock();
+ }
+
+ void test10() {
+ if (!(c || !mu.TryLock())) {
+ a = 0;
+ mu.Unlock();
+ }
+ }
+};
+
+} // end namespace LogicalConditionalTryLock
+
+
+
+namespace PtGuardedByTest {
+
+void doSomething();
+
+class Cell {
+ public:
+ int a;
+};
+
+
+// This mainly duplicates earlier tests, but just to make sure...
+class PtGuardedBySanityTest {
+ Mutex mu1;
+ Mutex mu2;
+ int* a GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
+ Cell* c GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
+ int sa[10] GUARDED_BY(mu1);
+ Cell sc[10] GUARDED_BY(mu1);
+
+ void test1() {
+ mu1.Lock();
+ if (a == 0) doSomething(); // OK, we don't dereference.
+ a = 0;
+ c = 0;
+ if (sa[0] == 42) doSomething();
+ sa[0] = 57;
+ if (sc[0].a == 42) doSomething();
+ sc[0].a = 57;
+ mu1.Unlock();
+ }
+
+ 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 (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 locking 'mu2'}}
+ (*c).a = 0; // 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 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}}
+ 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 (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 locking 'mu1'}}
+ (*c).a = 0; // expected-warning {{reading variable 'c' requires locking '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'}}
+ 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 == 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}}
+ }
+
+ void test5() {
+ mu1.ReaderLock(); // OK -- correct use.
+ mu2.Lock();
+ if (*a == 0) doSomething();
+ *a = 0;
+
+ if (c->a == 0) doSomething();
+ c->a = 0;
+
+ if ((*c).a == 0) doSomething();
+ (*c).a = 0;
+ mu2.Unlock();
+ mu1.Unlock();
+ }
+};
+
+
+class SmartPtr_PtGuardedBy_Test {
+ Mutex mu1;
+ Mutex mu2;
+ SmartPtr<int> sp GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
+ SmartPtr<Cell> sq GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
+
+ void test1() {
+ mu1.ReaderLock();
+ mu2.Lock();
+
+ sp.get();
+ if (*sp == 0) doSomething();
+ *sp = 0;
+ sq->a = 0;
+
+ if (sp[0] == 0) doSomething();
+ sp[0] = 0;
+
+ mu2.Unlock();
+ mu1.Unlock();
+ }
+
+ 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'}}
+
+ 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'}}
+
+ mu2.Unlock();
+ }
+
+ void test3() {
+ 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] == 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'}}
+
+ mu1.Unlock();
+ }
+};
+
+} // end namespace PtGuardedByTest
+
+
+namespace NonMemberCalleeICETest {
+
+class A {
+ void Run() {
+ (RunHelper)(); // expected-warning {{calling function 'RunHelper' requires exclusive lock on 'M'}}
+ }
+
+ void RunHelper() __attribute__((exclusive_locks_required(M)));
+ Mutex M;
+};
+
+} // end namespace NonMemberCalleeICETest
+
diff --git a/test/SemaCXX/warn-thread-safety-parsing.cpp b/test/SemaCXX/warn-thread-safety-parsing.cpp
index df9415c..1bd4e43 100644
--- a/test/SemaCXX/warn-thread-safety-parsing.cpp
+++ b/test/SemaCXX/warn-thread-safety-parsing.cpp
@@ -8,8 +8,10 @@
#define PT_GUARDED_VAR __attribute__ ((pt_guarded_var))
#define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__)))
#define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__)))
-#define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock_function(__VA_ARGS__)))
-#define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock_function(__VA_ARGS__)))
+#define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock_function(__VA_ARGS__)))
+#define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock_function(__VA_ARGS__)))
+#define ASSERT_EXCLUSIVE_LOCK(...) __attribute__ ((assert_exclusive_lock(__VA_ARGS__)))
+#define ASSERT_SHARED_LOCK(...) __attribute__ ((assert_shared_lock(__VA_ARGS__)))
#define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__)))
#define SHARED_TRYLOCK_FUNCTION(...) __attribute__ ((shared_trylock_function(__VA_ARGS__)))
#define UNLOCK_FUNCTION(...) __attribute__ ((unlock_function(__VA_ARGS__)))
@@ -24,7 +26,15 @@
class LOCKABLE Mutex {
public:
- void Lock();
+ void Lock() EXCLUSIVE_LOCK_FUNCTION();
+ void ReaderLock() SHARED_LOCK_FUNCTION();
+ void Unlock() UNLOCK_FUNCTION();
+
+ bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true);
+ bool ReaderTryLock() SHARED_TRYLOCK_FUNCTION(true);
+
+ void AssertHeld() ASSERT_EXCLUSIVE_LOCK();
+ void AssertReaderHeld() ASSERT_SHARED_LOCK();
};
class UnlockableMu{
@@ -93,7 +103,7 @@ class Bar {
void noanal_fun() NO_THREAD_SAFETY_ANALYSIS;
void noanal_fun_args() __attribute__((no_thread_safety_analysis(1))); // \
- // expected-error {{attribute takes no arguments}}
+ // expected-error {{'no_thread_safety_analysis' attribute takes no arguments}}
int noanal_testfn(int y) NO_THREAD_SAFETY_ANALYSIS;
@@ -132,13 +142,13 @@ void noanal_fun_params(int lvar NO_THREAD_SAFETY_ANALYSIS); // \
int gv_var_noargs GUARDED_VAR;
int gv_var_args __attribute__((guarded_var(1))); // \
- // expected-error {{attribute takes no arguments}}
+ // expected-error {{'guarded_var' attribute takes no arguments}}
class GVFoo {
private:
int gv_field_noargs GUARDED_VAR;
int gv_field_args __attribute__((guarded_var(1))); // \
- // expected-error {{attribute takes no arguments}}
+ // expected-error {{'guarded_var' attribute takes no arguments}}
};
class GUARDED_VAR GV { // \
@@ -178,7 +188,7 @@ class PGVFoo {
int field_noargs PT_GUARDED_VAR; // \
// expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
int *gv_field_args __attribute__((pt_guarded_var(1))); // \
- // expected-error {{attribute takes no arguments}}
+ // expected-error {{'pt_guarded_var' attribute takes no arguments}}
};
class PT_GUARDED_VAR PGV { // \
@@ -186,7 +196,7 @@ class PT_GUARDED_VAR PGV { // \
};
int *pgv_var_args __attribute__((pt_guarded_var(1))); // \
- // expected-error {{attribute takes no arguments}}
+ // expected-error {{'pt_guarded_var' attribute takes no arguments}}
void pgv_function() PT_GUARDED_VAR; // \
@@ -215,7 +225,7 @@ class LOCKABLE LTestClass {
};
class __attribute__((lockable (1))) LTestClass_args { // \
- // expected-error {{attribute takes no arguments}}
+ // expected-error {{'lockable' attribute takes no arguments}}
};
void l_test_function() LOCKABLE; // \
@@ -255,7 +265,7 @@ class SCOPED_LOCKABLE SLTestClass {
};
class __attribute__((scoped_lockable (1))) SLTestClass_args { // \
- // expected-error {{attribute takes no arguments}}
+ // expected-error {{'scoped_lockable' attribute takes no arguments}}
};
void sl_test_function() SCOPED_LOCKABLE; // \
@@ -297,16 +307,18 @@ void sl_function_params(int lvar SCOPED_LOCKABLE); // \
int gb_var_arg GUARDED_BY(mu1);
+int gb_non_ascii GUARDED_BY(L"wide"); // expected-warning {{ignoring 'guarded_by' attribute because its argument is invalid}}
+
int gb_var_args __attribute__((guarded_by(mu1, mu2))); // \
- // expected-error {{attribute takes one argument}}
+ // expected-error {{'guarded_by' attribute takes one argument}}
int gb_var_noargs __attribute__((guarded_by)); // \
- // expected-error {{attribute takes one argument}}
+ // expected-error {{'guarded_by' attribute takes one argument}}
class GBFoo {
private:
int gb_field_noargs __attribute__((guarded_by)); // \
- // expected-error {{attribute takes one argument}}
+ // expected-error {{'guarded_by' attribute takes one argument}}
int gb_field_args GUARDED_BY(mu1);
};
@@ -364,12 +376,12 @@ int gb_var_arg_bad_4 GUARDED_BY(umu); // \
//1. Check applied to the right types & argument number
int *pgb_var_noargs __attribute__((pt_guarded_by)); // \
- // expected-error {{attribute takes one argument}}
+ // expected-error {{'pt_guarded_by' attribute takes one argument}}
int *pgb_ptr_var_arg PT_GUARDED_BY(mu1);
int *pgb_ptr_var_args __attribute__((pt_guarded_by(mu1, mu2))); // \
- // expected-error {{attribute takes one argument}}
+ // expected-error {{'pt_guarded_by' attribute takes one argument}}
int pgb_var_args PT_GUARDED_BY(mu1); // \
// expected-warning {{'pt_guarded_by' only applies to pointer types; type here is 'int'}}
@@ -377,7 +389,7 @@ int pgb_var_args PT_GUARDED_BY(mu1); // \
class PGBFoo {
private:
int *pgb_field_noargs __attribute__((pt_guarded_by)); // \
- // expected-error {{attribute takes one argument}}
+ // expected-error {{'pt_guarded_by' attribute takes one argument}}
int *pgb_field_args PT_GUARDED_BY(mu1);
};
@@ -750,11 +762,11 @@ int etf_function_9() EXCLUSIVE_TRYLOCK_FUNCTION(true);
// illegal attribute arguments
int etf_function_bad_1() EXCLUSIVE_TRYLOCK_FUNCTION(mu1); // \
- // expected-error {{'exclusive_trylock_function' attribute first argument must be of int or bool type}}
+ // expected-error {{'exclusive_trylock_function' attribute requires parameter 1 to be int or bool}}
int etf_function_bad_2() EXCLUSIVE_TRYLOCK_FUNCTION("mu"); // \
- // expected-error {{'exclusive_trylock_function' attribute first argument must be of int or bool type}}
+ // expected-error {{'exclusive_trylock_function' attribute requires parameter 1 to be int or bool}}
int etf_function_bad_3() EXCLUSIVE_TRYLOCK_FUNCTION(muDoublePointer); // \
- // expected-error {{'exclusive_trylock_function' attribute first argument must be of int or bool type}}
+ // expected-error {{'exclusive_trylock_function' attribute requires parameter 1 to be int or bool}}
int etf_function_bad_4() EXCLUSIVE_TRYLOCK_FUNCTION(1, "mu"); // \
// expected-warning {{ignoring 'exclusive_trylock_function' attribute because its argument is invalid}}
@@ -824,11 +836,11 @@ int stf_function_9() SHARED_TRYLOCK_FUNCTION(true);
// illegal attribute arguments
int stf_function_bad_1() SHARED_TRYLOCK_FUNCTION(mu1); // \
- // expected-error {{'shared_trylock_function' attribute first argument must be of int or bool type}}
+ // expected-error {{'shared_trylock_function' attribute requires parameter 1 to be int or bool}}
int stf_function_bad_2() SHARED_TRYLOCK_FUNCTION("mu"); // \
- // expected-error {{'shared_trylock_function' attribute first argument must be of int or bool type}}
+ // expected-error {{'shared_trylock_function' attribute requires parameter 1 to be int or bool}}
int stf_function_bad_3() SHARED_TRYLOCK_FUNCTION(muDoublePointer); // \
- // expected-error {{'shared_trylock_function' attribute first argument must be of int or bool type}}
+ // expected-error {{'shared_trylock_function' attribute requires parameter 1 to be int or bool}}
int stf_function_bad_4() SHARED_TRYLOCK_FUNCTION(1, "mu"); // \
// expected-warning {{ignoring 'shared_trylock_function' attribute because its argument is invalid}}
@@ -921,12 +933,12 @@ int uf_function_bad_7() UNLOCK_FUNCTION(0); // \
// Takes exactly one argument, a var/field
void lr_function() __attribute__((lock_returned)); // \
- // expected-error {{attribute takes one argument}}
+ // expected-error {{'lock_returned' attribute takes one argument}}
void lr_function_arg() LOCK_RETURNED(mu1);
void lr_function_args() __attribute__((lock_returned(mu1, mu2))); // \
- // expected-error {{attribute takes one argument}}
+ // expected-error {{'lock_returned' attribute takes one argument}}
int lr_testfn(int y) LOCK_RETURNED(mu1);
diff --git a/test/SemaCXX/warn-unreachable.cpp b/test/SemaCXX/warn-unreachable.cpp
index f36300a..dd07125 100644
--- a/test/SemaCXX/warn-unreachable.cpp
+++ b/test/SemaCXX/warn-unreachable.cpp
@@ -62,8 +62,8 @@ void test5() {
struct S {
int mem;
} s;
- S &foor() __attribute__((noreturn));
- foor()
+ S &foonr() __attribute__((noreturn));
+ foonr()
.mem; // expected-warning {{will never be executed}}
}
diff --git a/test/SemaCXX/warn-unsequenced.cpp b/test/SemaCXX/warn-unsequenced.cpp
index c7acfca..54e16a5 100644
--- a/test/SemaCXX/warn-unsequenced.cpp
+++ b/test/SemaCXX/warn-unsequenced.cpp
@@ -1,12 +1,13 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wno-unused %s
-int f(int, int);
+int f(int, int = 0);
struct A {
int x, y;
};
struct S {
S(int, int);
+ int n;
};
void test() {
@@ -32,6 +33,9 @@ void test() {
f(a = 0, a); // expected-warning {{unsequenced modification and access}}
f(a, a += 0); // expected-warning {{unsequenced modification and access}}
f(a = 0, a = 0); // expected-warning {{multiple unsequenced modifications}}
+ a = f(++a); // ok
+ a = f(a++); // ok
+ a = f(++a, a++); // expected-warning {{multiple unsequenced modifications}}
// Compound assignment "A OP= B" is equivalent to "A = A OP B" except that A
// is evaluated only once.
@@ -47,6 +51,12 @@ void test() {
S str2 = { a++, a++ }; // ok
S str3 = { a++ + a, a++ }; // expected-warning {{unsequenced modification and access}}
+ struct Z { A a; S s; } z = { { ++a, ++a }, { ++a, ++a } }; // ok
+ a = S { ++a, a++ }.n; // ok
+ A { ++a, a++ }.x; // ok
+ a = A { ++a, a++ }.x; // expected-warning {{unsequenced modifications}}
+ A { ++a, a++ }.x + A { ++a, a++ }.y; // expected-warning {{unsequenced modifications}}
+
(xs[2] && (a = 0)) + a; // ok
(0 && (a = 0)) + a; // ok
(1 && (a = 0)) + a; // expected-warning {{unsequenced modification and access}}
@@ -58,6 +68,8 @@ void test() {
(xs[4] ? a : ++a) + a; // ok
(0 ? a : ++a) + a; // expected-warning {{unsequenced modification and access}}
(1 ? a : ++a) + a; // ok
+ (0 ? a : a++) + a; // expected-warning {{unsequenced modification and access}}
+ (1 ? a : a++) + a; // ok
(xs[5] ? ++a : ++a) + a; // FIXME: warn here
(++a, xs[6] ? ++a : 0) + a; // expected-warning {{unsequenced modification and access}}
diff --git a/test/SemaCXX/warn-unused-attribute.cpp b/test/SemaCXX/warn-unused-attribute.cpp
new file mode 100644
index 0000000..72f96ee
--- /dev/null
+++ b/test/SemaCXX/warn-unused-attribute.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -verify %s
+struct __attribute__((warn_unused)) Test
+{
+ Test();
+ ~Test();
+ void use();
+};
+
+struct TestNormal
+{
+ TestNormal();
+};
+
+int main()
+{
+ Test unused; // expected-warning {{unused variable 'unused'}}
+ Test used;
+ TestNormal normal;
+ used.use();
+}
diff --git a/test/SemaCXX/warn-unused-filescoped.cpp b/test/SemaCXX/warn-unused-filescoped.cpp
index 9fb6011..b0af5b3 100644
--- a/test/SemaCXX/warn-unused-filescoped.cpp
+++ b/test/SemaCXX/warn-unused-filescoped.cpp
@@ -1,6 +1,41 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wunused -Wunused-member-function -Wno-c++11-extensions -std=c++98 %s
// RUN: %clang_cc1 -fsyntax-only -verify -Wunused -Wunused-member-function -std=c++11 %s
+#ifdef HEADER
+
+static void headerstatic() {} // expected-warning{{unused}}
+static inline void headerstaticinline() {}
+
+namespace {
+ void headeranon() {} // expected-warning{{unused}}
+ inline void headerinlineanon() {}
+}
+
+namespace test7
+{
+ template<typename T>
+ static inline void foo(T) { }
+
+ // This should not emit an unused-function warning since it inherits
+ // the static storage type from the base template.
+ template<>
+ inline void foo(int) { }
+
+ // Partial specialization
+ template<typename T, typename U>
+ static inline void bar(T, U) { }
+
+ template<typename U>
+ inline void bar(int, U) { }
+
+ template<>
+ inline void bar(int, int) { }
+};
+
+#else
+#define HEADER
+#include "warn-unused-filescoped.cpp"
+
static void f1(); // expected-warning{{unused}}
namespace {
@@ -37,8 +72,10 @@ namespace {
void S::m3() { } // expected-warning{{unused}}
-static inline void f4() { }
-const unsigned int cx = 0;
+static inline void f4() { } // expected-warning{{unused}}
+const unsigned int cx = 0; // expected-warning{{unused}}
+const unsigned int cy = 0;
+int f5() { return cy; }
static int x1; // expected-warning{{unused}}
@@ -98,7 +135,7 @@ namespace test5 {
// FIXME: We should produce warnings for both of these.
static const int m = n;
int x = sizeof(m);
- static const double d = 0.0;
+ static const double d = 0.0; // expected-warning{{not needed and will not be emitted}}
int y = sizeof(d);
}
@@ -133,27 +170,6 @@ namespace test6 {
};
}
-namespace test7
-{
- template<typename T>
- static inline void foo(T) { }
-
- // This should not emit an unused-function warning since it inherits
- // the static storage type from the base template.
- template<>
- inline void foo(int) { }
-
- // Partial specialization
- template<typename T, typename U>
- static inline void bar(T, U) { }
-
- template<typename U>
- inline void bar(int, U) { }
-
- template<>
- inline void bar(int, int) { }
-};
-
namespace pr14776 {
namespace {
struct X {};
@@ -161,3 +177,20 @@ namespace pr14776 {
X a = X(); // expected-warning {{unused variable 'a'}}
auto b = X(); // expected-warning {{unused variable 'b'}}
}
+
+namespace UndefinedInternalStaticMember {
+ namespace {
+ struct X {
+ static const unsigned x = 3;
+ int y[x];
+ };
+ }
+}
+
+namespace test8 {
+static void func();
+void bar() { void func() __attribute__((used)); }
+static void func() {}
+}
+
+#endif
diff --git a/test/SemaCXX/warn-unused-private-field.cpp b/test/SemaCXX/warn-unused-private-field.cpp
index 661442d..932a7dc 100644
--- a/test/SemaCXX/warn-unused-private-field.cpp
+++ b/test/SemaCXX/warn-unused-private-field.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wunused-private-field -Wused-but-marked-unused -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -Wunused-private-field -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++11 %s
class NotFullyDefined {
public:
diff --git a/test/SemaCXX/warn-unused-result.cpp b/test/SemaCXX/warn-unused-result.cpp
index b0bf61f..581af09 100644
--- a/test/SemaCXX/warn-unused-result.cpp
+++ b/test/SemaCXX/warn-unused-result.cpp
@@ -78,3 +78,19 @@ void lazy() {
DoYetAnotherThing();
}
}
+
+namespace PR17587 {
+struct [[clang::warn_unused_result]] Status;
+
+struct Foo {
+ Status Bar();
+};
+
+struct Status {};
+
+void Bar() {
+ Foo f;
+ f.Bar(); // expected-warning {{ignoring return value}}
+};
+
+}
diff --git a/test/SemaCXX/warn-unused-value.cpp b/test/SemaCXX/warn-unused-value.cpp
index 072ee60..5e43d3e 100644
--- a/test/SemaCXX/warn-unused-value.cpp
+++ b/test/SemaCXX/warn-unused-value.cpp
@@ -49,3 +49,23 @@ namespace test2 {
}
}
+namespace test3 {
+struct Used {
+ Used();
+ Used(int);
+ Used(int, int);
+};
+struct __attribute__((warn_unused)) Unused {
+ Unused();
+ Unused(int);
+ Unused(int, int);
+};
+void f() {
+ Used();
+ Used(1);
+ Used(1, 1);
+ Unused(); // expected-warning {{expression result unused}}
+ Unused(1); // expected-warning {{expression result unused}}
+ Unused(1, 1); // expected-warning {{expression result unused}}
+}
+}
diff --git a/test/SemaCXX/warn-unused-variables.cpp b/test/SemaCXX/warn-unused-variables.cpp
index 00597f9..93d2f6f 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 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -verify %s
template<typename T> void f() {
T t;
t = 17;
@@ -128,3 +128,26 @@ 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-using-namespace-in-header.cpp b/test/SemaCXX/warn-using-namespace-in-header.cpp
index f68b998..6b84e6e 100644
--- a/test/SemaCXX/warn-using-namespace-in-header.cpp
+++ b/test/SemaCXX/warn-using-namespace-in-header.cpp
@@ -57,4 +57,13 @@ using namespace dont_warn;
// cc file.
USING_MACRO
+// Check behavior of line markers.
+namespace warn_header_with_line_marker {}
+# 1 "XXX.h" 1
+using namespace warn_header_with_line_marker; // expected-warning {{using namespace directive in global context in header}}
+# 70 "warn-using-namespace-in-header.cpp" 2
+
+namespace nowarn_after_line_marker {}
+using namespace nowarn_after_line_marker;
+
#endif
diff --git a/test/SemaCXX/writable-strings-deprecated.cpp b/test/SemaCXX/writable-strings-deprecated.cpp
index 8295401..b8f605b 100644
--- a/test/SemaCXX/writable-strings-deprecated.cpp
+++ b/test/SemaCXX/writable-strings-deprecated.cpp
@@ -1,11 +1,15 @@
// RUN: %clang_cc1 -fsyntax-only -Wno-deprecated-writable-strings -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
// rdar://8827606
char *fun(void)
{
return "foo";
+#ifdef ERROR
+ // expected-error@-2 {{deprecated}}
+#endif
}
void test(bool b)
OpenPOWER on IntegriCloud