summaryrefslogtreecommitdiffstats
path: root/test/SemaCXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaCXX')
-rw-r--r--test/SemaCXX/MicrosoftExtensions.cpp74
-rw-r--r--test/SemaCXX/PR9572.cpp8
-rw-r--r--test/SemaCXX/PR9884.cpp17
-rw-r--r--test/SemaCXX/PR9902.cpp28
-rw-r--r--test/SemaCXX/PR9908.cpp32
-rw-r--r--test/SemaCXX/aggregate-initialization.cpp4
-rw-r--r--test/SemaCXX/alias-template.cpp147
-rw-r--r--test/SemaCXX/anonymous-union.cpp30
-rw-r--r--test/SemaCXX/attr-cxx0x.cpp5
-rw-r--r--test/SemaCXX/attr-noreturn.cpp17
-rw-r--r--test/SemaCXX/attr-regparm.cpp3
-rw-r--r--test/SemaCXX/class.cpp2
-rw-r--r--test/SemaCXX/conversion.cpp11
-rw-r--r--test/SemaCXX/copy-constructor-error.cpp4
-rw-r--r--test/SemaCXX/cxx0x-cursory-default-delete.cpp69
-rw-r--r--test/SemaCXX/cxx0x-defaulted-functions.cpp45
-rw-r--r--test/SemaCXX/cxx0x-delegating-ctors.cpp24
-rw-r--r--test/SemaCXX/cxx0x-deleted-default-ctor.cpp120
-rw-r--r--test/SemaCXX/cxx0x-nontrivial-union.cpp22
-rw-r--r--test/SemaCXX/default-arg-special-member.cpp12
-rw-r--r--test/SemaCXX/default-constructor-initializers.cpp7
-rw-r--r--test/SemaCXX/defaulted-ctor-loop.cpp14
-rw-r--r--test/SemaCXX/deleted-function-extension.cpp8
-rw-r--r--test/SemaCXX/deleted-function.cpp5
-rw-r--r--test/SemaCXX/dependent-noexcept-unevaluated.cpp41
-rw-r--r--test/SemaCXX/dependent-types.cpp5
-rw-r--r--test/SemaCXX/destructor.cpp175
-rw-r--r--test/SemaCXX/enum-scoped.cpp10
-rw-r--r--test/SemaCXX/expressions.cpp31
-rw-r--r--test/SemaCXX/generalized-initializers.cpp174
-rw-r--r--test/SemaCXX/implicit-exception-spec.cpp63
-rw-r--r--test/SemaCXX/implicit-member-functions.cpp2
-rw-r--r--test/SemaCXX/member-expr.cpp12
-rw-r--r--test/SemaCXX/member-init.cpp50
-rw-r--r--test/SemaCXX/member-pointer.cpp25
-rw-r--r--test/SemaCXX/nullptr.cpp57
-rw-r--r--test/SemaCXX/overload-call.cpp22
-rw-r--r--test/SemaCXX/overloaded-operator.cpp17
-rw-r--r--test/SemaCXX/redeclared-alias-template.cpp23
-rw-r--r--test/SemaCXX/reinterpret-cast.cpp162
-rw-r--r--test/SemaCXX/return.cpp16
-rw-r--r--test/SemaCXX/struct-class-redecl.cpp160
-rw-r--r--test/SemaCXX/switch.cpp2
-rw-r--r--test/SemaCXX/tag-ambig.cpp28
-rw-r--r--test/SemaCXX/type-traits.cpp102
-rw-r--r--test/SemaCXX/underlying_type.cpp37
-rw-r--r--test/SemaCXX/value-initialization.cpp9
-rw-r--r--test/SemaCXX/vararg-non-pod.cpp9
-rw-r--r--test/SemaCXX/vtable-instantiation.cc50
-rw-r--r--test/SemaCXX/warn-bad-memaccess.cpp70
-rw-r--r--test/SemaCXX/warn-non-pod-memset.cpp63
-rw-r--r--test/SemaCXX/warn-pure-virtual-call-from-ctor-dtor.cpp7
52 files changed, 1996 insertions, 134 deletions
diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp
index 2d620b6..9b03feb 100644
--- a/test/SemaCXX/MicrosoftExtensions.cpp
+++ b/test/SemaCXX/MicrosoftExtensions.cpp
@@ -6,6 +6,8 @@ void f(const type_info &a);
// Microsoft doesn't validate exception specification.
+namespace microsoft_exception_spec {
+
void foo(); // expected-note {{previous declaration}}
void foo() throw(); // expected-warning {{exception specification in declaration does not match previous declaration}}
@@ -22,6 +24,15 @@ struct Derived : Base {
virtual void f3();
};
+class A {
+ virtual ~A() throw(); // expected-note {{overridden virtual function is here}}
+};
+
+class B : public A {
+ virtual ~B(); // expected-warning {{exception specification of overriding function is more lax than base version}}
+};
+
+}
// MSVC allows type definition in anonymous union and struct
struct A
@@ -179,4 +190,65 @@ void static_func(); // expected-note {{previous declaration is here}}
static void static_func() // expected-warning {{static declaration of 'static_func' follows non-static declaration}}
{
-} \ No newline at end of file
+}
+
+long function_prototype(int a);
+long (*function_ptr)(int a);
+
+void function_to_voidptr_conv() {
+ void *a1 = function_prototype;
+ void *a2 = &function_prototype;
+ void *a3 = function_ptr;
+}
+
+
+void pointer_to_integral_type_conv(char* ptr) {
+ char ch = (char)ptr;
+ short sh = (short)ptr;
+ ch = (char)ptr;
+ sh = (short)ptr;
+}
+
+namespace ms_using_declaration_bug {
+
+class A {
+public:
+ int f();
+};
+
+class B : public A {
+private:
+ using A::f;
+};
+
+class C : public B {
+private:
+ using B::f; // expected-warning {{using declaration refers to inaccessible member 'ms_using_declaration_bug::B::f', which refers to accessible member 'ms_using_declaration_bug::A::f', accepted for Microsoft compatibility}}
+};
+
+}
+
+
+
+namespace friend_as_a_forward_decl {
+
+class A {
+ class Nested {
+ friend class B;
+ B* b;
+ };
+ B* b;
+};
+B* global_b;
+
+
+void f()
+{
+ class Local {
+ friend class Z;
+ Z* b;
+ };
+ Z* b;
+}
+
+ } \ No newline at end of file
diff --git a/test/SemaCXX/PR9572.cpp b/test/SemaCXX/PR9572.cpp
index d1b7077..25c0c01 100644
--- a/test/SemaCXX/PR9572.cpp
+++ b/test/SemaCXX/PR9572.cpp
@@ -1,13 +1,13 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
class Base {
- virtual ~Base();
+ virtual ~Base(); // expected-note {{implicitly declared private here}}
};
-struct Foo : public Base {
- const int kBlah = 3; // expected-error{{fields can only be initialized in constructors}}
+struct Foo : public Base { // expected-error {{base class 'Base' has private destructor}}
+ const int kBlah = 3; // expected-warning {{accepted as a C++0x extension}}
Foo();
};
struct Bar : public Foo {
- Bar() { }
+ Bar() { } // expected-note {{implicit default destructor for 'Foo' first required here}}
};
struct Baz {
Foo f;
diff --git a/test/SemaCXX/PR9884.cpp b/test/SemaCXX/PR9884.cpp
new file mode 100644
index 0000000..ab883c4
--- /dev/null
+++ b/test/SemaCXX/PR9884.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+class Base {
+protected:
+ Base(int val);
+};
+
+
+class Derived : public Base {
+public:
+ Derived(int val);
+};
+
+
+Derived::Derived(int val)
+ : Base( val )
+{
+}
diff --git a/test/SemaCXX/PR9902.cpp b/test/SemaCXX/PR9902.cpp
new file mode 100644
index 0000000..ec76789
--- /dev/null
+++ b/test/SemaCXX/PR9902.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+template <class _Tp, class _Up, bool = false>
+struct __allocator_traits_rebind
+{
+};
+
+template <template <class, class...> class _Alloc, class _Tp, class ..._Args,
+class _Up>
+struct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, false>
+{
+ typedef _Alloc<_Up, _Args...> type;
+};
+
+template <class Alloc>
+struct allocator_traits
+{
+ template <class T> using rebind_alloc = typename __allocator_traits_rebind<Alloc, T>::type;
+ template <class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;
+};
+
+template <class T>
+struct allocator {};
+
+int main()
+{
+ allocator_traits<allocator<char>>::rebind_alloc<int> a;
+}
diff --git a/test/SemaCXX/PR9908.cpp b/test/SemaCXX/PR9908.cpp
new file mode 100644
index 0000000..3b98b72
--- /dev/null
+++ b/test/SemaCXX/PR9908.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+template <class _Tp, class _Up>
+struct __allocator_traits_rebind
+{
+ typedef typename _Tp::template rebind<_Up>::other type;
+};
+
+template <class Alloc>
+struct allocator_traits
+{
+ typedef Alloc allocator_type;
+ template <class T> using rebind_alloc = typename
+__allocator_traits_rebind<allocator_type, T>::type;
+ template <class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;
+};
+
+template <class T>
+struct ReboundA {};
+
+template <class T>
+struct A
+{
+ typedef T value_type;
+
+ template <class U> struct rebind {typedef ReboundA<U> other;};
+};
+
+int main()
+{
+ allocator_traits<A<char> >::rebind_traits<double> a;
+}
diff --git a/test/SemaCXX/aggregate-initialization.cpp b/test/SemaCXX/aggregate-initialization.cpp
index 4c34447..b9e69b0 100644
--- a/test/SemaCXX/aggregate-initialization.cpp
+++ b/test/SemaCXX/aggregate-initialization.cpp
@@ -2,6 +2,8 @@
// Verify that we can't initialize non-aggregates with an initializer
// list.
+// FIXME: Note that due to a (likely) standard bug, this is technically an
+// aggregate.
struct NonAggr1 {
NonAggr1(int) { }
@@ -22,7 +24,7 @@ struct NonAggr4 {
virtual void f();
};
-NonAggr1 na1 = { 17 }; // expected-error{{non-aggregate type 'NonAggr1' cannot be initialized with an initializer list}}
+NonAggr1 na1 = { 17 };
NonAggr2 na2 = { 17 }; // expected-error{{non-aggregate type 'NonAggr2' cannot be initialized with an initializer list}}
NonAggr3 na3 = { 17 }; // expected-error{{non-aggregate type 'NonAggr3' cannot be initialized with an initializer list}}
NonAggr4 na4 = { 17 }; // expected-error{{non-aggregate type 'NonAggr4' cannot be initialized with an initializer list}}
diff --git a/test/SemaCXX/alias-template.cpp b/test/SemaCXX/alias-template.cpp
new file mode 100644
index 0000000..f29a932
--- /dev/null
+++ b/test/SemaCXX/alias-template.cpp
@@ -0,0 +1,147 @@
+// RUN: %clang_cc1 -verify -std=c++0x %s
+
+namespace RedeclAliasTypedef {
+ template<typename U> using T = int;
+ template<typename U> using T = int;
+ template<typename U> using T = T<U>;
+}
+
+namespace IllegalTypeIds {
+ template<typename U> using A = void(int n = 0); // expected-error {{default arguments can only be specified for parameters in a function declaration}}
+ template<typename U> using B = inline void(int n); // expected-error {{type name does not allow function specifier}}
+ template<typename U> using C = virtual void(int n); // expected-error {{type name does not allow function specifier}}
+ template<typename U> using D = explicit void(int n); // expected-error {{type name does not allow function specifier}}
+ template<typename U> using E = void(int n) throw(); // expected-error {{exception specifications are not allowed in type aliases}}
+ // FIXME: this is illegal; we incorrectly accept it for typedefs too.
+ template<typename U> using F = void(*)(int n) &&; // expected-err
+ template<typename U> using G = __thread void(int n); // expected-error {{type name does not allow storage class to be specified}}
+
+ template<typename U> using H = void(int n); // ok
+ template<typename U> using I = void(int n) &&; // ok
+}
+
+namespace IllegalSyntax {
+ template<typename Z> using ::T = void(int n); // expected-error {{name defined in alias declaration must be an identifier}}
+ template<typename Z> using operator int = void(int n); // expected-error {{name defined in alias declaration must be an identifier}}
+ template<typename Z> using typename U = void; // expected-error {{name defined in alias declaration must be an identifier}}
+ template<typename Z> using typename ::V = void(int n); // expected-error {{name defined in alias declaration must be an identifier}}
+ template<typename Z> using typename ::operator bool = void(int n); // expected-error {{name defined in alias declaration must be an identifier}}
+}
+
+namespace VariableLengthArrays {
+ template<typename Z> using T = int[42]; // ok
+
+ int n = 32;
+ template<typename Z> using T = int[n]; // expected-error {{variable length array declaration not allowed at file scope}}
+
+ const int m = 42;
+ template<typename Z> using U = int[m]; // expected-note {{previous definition}}
+ template<typename Z> using U = int[42]; // ok
+ template<typename Z> using U = int; // expected-error {{type alias template redefinition with different types ('int' vs 'int [42]')}}
+}
+
+namespace RedeclFunc {
+ int f(int, char**);
+ template<typename Z> using T = int;
+ T<char> f(int, char **); // ok
+}
+
+namespace LookupFilter {
+ namespace N { template<typename U> using S = int; }
+ using namespace N;
+ template<typename U> using S = S<U>*; // ok
+}
+
+namespace InFunctions {
+ template<typename...T> struct S0 {
+ template<typename Z> using U = T*; // expected-error {{declaration type contains unexpanded parameter pack 'T'}}
+ U<char> u;
+ };
+
+ template<typename Z> using T1 = int;
+ template<typename Z> using T2 = int[-1]; // expected-error {{array size is negative}}
+ template<typename...T> struct S3 { // expected-note {{template parameter is declared here}}
+ template<typename Z> using T = int; // expected-error {{declaration of 'T' shadows template parameter}}
+ };
+ template<typename Z> using Z = Z;
+}
+
+namespace ClassNameRedecl {
+ class C0 {
+ // FIXME: this diagnostic is pretty poor
+ template<typename U> using C0 = int; // expected-error {{name defined in alias declaration must be an identifier}}
+ };
+ class C1 {
+ // FIXME: this diagnostic is pretty poor
+ template<typename U> using C1 = C1; // expected-error {{name defined in alias declaration must be an identifier}}
+ };
+ class C2 {
+ template<typename U> using C0 = C1; // ok
+ };
+ template<typename...T> class C3 {
+ template<typename U> using f = T; // expected-error {{declaration type contains unexpanded parameter pack 'T'}}
+ };
+ template<typename T> class C4 { // expected-note {{template parameter is declared here}}
+ template<typename U> using T = int; // expected-error {{declaration of 'T' shadows template parameter}}
+ };
+ class C5 {
+ class c; // expected-note {{previous definition}}
+ template<typename U> using c = int; // expected-error {{redefinition of 'c' as different kind of symbol}}
+ class d; // expected-note {{previous definition}}
+ template<typename U> using d = d; // expected-error {{redefinition of 'd' as different kind of symbol}}
+ };
+ class C6 {
+ class c { template<typename U> using C6 = int; }; // ok
+ };
+}
+
+class CtorDtorName {
+ template<typename T> using X = CtorDtorName;
+ X<int>(); // expected-error {{expected member name}}
+ ~X<int>(); // expected-error {{destructor cannot be declared using a type alias}}
+};
+
+namespace TagName {
+ template<typename Z> using S = struct { int n; }; // expected-error {{can not be defined}}
+ template<typename Z> using T = class { int n; }; // expected-error {{can not be defined}}
+ template<typename Z> using U = enum { a, b, c }; // expected-error {{can not be defined}}
+ template<typename Z> using V = struct V { int n; }; // expected-error {{redefinition of 'V' as different kind of symbol}} \
+ expected-error {{'TagName::V' can not be defined in a type alias template}} \
+ expected-note {{previous definition is here}}
+}
+
+namespace StdExample {
+ template<typename T, typename U> struct pair;
+
+ template<typename T> using handler_t = void (*)(T);
+ extern handler_t<int> ignore;
+ extern void (*ignore)(int);
+ // FIXME: we recover as if cell is an undeclared variable. the diagnostics are terrible!
+ template<typename T> using cell = pair<T*, cell<T>*>; // expected-error {{use of undeclared identifier 'cell'}} \
+ expected-error {{'T' does not refer to a value}} \
+ expected-note {{declared here}} \
+ expected-error {{expected ';' after alias declaration}}
+}
+
+namespace Access {
+ class C0 {
+ template<typename Z> using U = int; // expected-note {{declared private here}}
+ };
+ C0::U<int> v; // expected-error {{'U' is a private member}}
+ class C1 {
+ public:
+ template<typename Z> using U = int;
+ };
+ C1::U<int> w; // ok
+}
+
+namespace VoidArg {
+ template<typename Z> using V = void;
+ V<int> f(int); // ok
+ V<char> g(V<double>); // expected-error {{empty parameter list defined with a type alias of 'void' not allowed}}
+}
+
+namespace Curried {
+ template<typename T, typename U> struct S;
+ template<typename T> template<typename U> using SS = S<T, U>; // expected-error {{extraneous template parameter list in alias template declaration}}
+}
diff --git a/test/SemaCXX/anonymous-union.cpp b/test/SemaCXX/anonymous-union.cpp
index 553ae65..2dd7ab8 100644
--- a/test/SemaCXX/anonymous-union.cpp
+++ b/test/SemaCXX/anonymous-union.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
struct X {
union {
float f3;
@@ -17,7 +17,7 @@ struct X {
void test_unqual_references();
- struct {
+ struct { // expected-warning{{anonymous structs are a GNU extension}}
int a;
float b;
};
@@ -125,7 +125,7 @@ typedef struct _s {
// <rdar://problem/7987650>
namespace test4 {
class A {
- struct {
+ struct { // expected-warning{{anonymous structs are a GNU extension}}
int s0; // expected-note {{declared private here}}
double s1; // expected-note {{declared private here}}
union {
@@ -136,7 +136,7 @@ namespace test4 {
union {
int u0; // expected-note {{declared private here}}
double u1; // expected-note {{declared private here}}
- struct {
+ struct { // expected-warning{{anonymous structs are a GNU extension}}
int us0; // expected-note {{declared private here}}
double us1; // expected-note {{declared private here}}
};
@@ -175,3 +175,25 @@ void foo_PR6741() {
};
}
}
+
+namespace PR8326 {
+ template <class T>
+ class Foo {
+ public:
+ Foo()
+ : x(0)
+ , y(1){
+ }
+
+ private:
+ const union { // expected-warning{{anonymous union cannot be 'const'}}
+ struct { // expected-warning{{anonymous structs are a GNU extension}}
+ T x;
+ T y;
+ };
+ T v[2];
+ };
+ };
+
+ Foo<int> baz;
+}
diff --git a/test/SemaCXX/attr-cxx0x.cpp b/test/SemaCXX/attr-cxx0x.cpp
index 40fe0e0..725f018 100644
--- a/test/SemaCXX/attr-cxx0x.cpp
+++ b/test/SemaCXX/attr-cxx0x.cpp
@@ -9,8 +9,13 @@ struct align_member {
int member [[align(8)]];
};
+typedef char align_typedef [[align(8)]];
+template<typename T> using align_alias_template = align_typedef;
+
static_assert(alignof(align_big) == alignof(int), "k's alignment is wrong");
static_assert(alignof(align_small) == 1, "j's alignment is wrong");
static_assert(alignof(align_multiple) == 8, "l's alignment is wrong");
static_assert(alignof(align_member) == 8, "quuux's alignment is wrong");
static_assert(sizeof(align_member) == 8, "quuux's size is wrong");
+static_assert(alignof(align_typedef) == 8, "typedef's alignment is wrong");
+static_assert(alignof(align_alias_template<int>) == 8, "alias template's alignment is wrong");
diff --git a/test/SemaCXX/attr-noreturn.cpp b/test/SemaCXX/attr-noreturn.cpp
index b7d3999..eaf0d0c 100644
--- a/test/SemaCXX/attr-noreturn.cpp
+++ b/test/SemaCXX/attr-noreturn.cpp
@@ -1,5 +1,22 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
+// Reachability tests have to come first because they get suppressed
+// if any errors have occurred.
+namespace test5 {
+ struct A {
+ __attribute__((noreturn)) void fail();
+ void nofail();
+ } a;
+
+ int &test1() {
+ a.nofail();
+ } // expected-warning {{control reaches end of non-void function}}
+
+ int &test2() {
+ a.fail();
+ }
+}
+
// PR5620
void f0() __attribute__((__noreturn__));
void f1(void (*)());
diff --git a/test/SemaCXX/attr-regparm.cpp b/test/SemaCXX/attr-regparm.cpp
index b98631a..91ee613 100644
--- a/test/SemaCXX/attr-regparm.cpp
+++ b/test/SemaCXX/attr-regparm.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-pc-linux-gnu %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-apple-darwin10 %s
// PR7025
struct X0 {
diff --git a/test/SemaCXX/class.cpp b/test/SemaCXX/class.cpp
index 52140cb..44fa0ce 100644
--- a/test/SemaCXX/class.cpp
+++ b/test/SemaCXX/class.cpp
@@ -34,7 +34,7 @@ public:
enum E1 { en1, en2 };
- int i = 0; // expected-error {{fields can only be initialized in constructors}}
+ int i = 0; // expected-warning {{in-class initialization of non-static data member accepted as a C++0x extension}}
static int si = 0; // expected-error {{non-const static data member must be initialized out of line}}
static const NestedC ci = 0; // expected-error {{static data member of type 'const C::NestedC' must be initialized out of line}}
static const int nci = vs; // expected-error {{in-class initializer is not a constant expression}}
diff --git a/test/SemaCXX/conversion.cpp b/test/SemaCXX/conversion.cpp
index fdda7ac..b069abc 100644
--- a/test/SemaCXX/conversion.cpp
+++ b/test/SemaCXX/conversion.cpp
@@ -1,5 +1,7 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -Wconversion -verify %s
+#include <stddef.h>
+
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
@@ -50,3 +52,12 @@ namespace test2 {
A() : x(10) {} // expected-warning {{implicit truncation from 'int' to bitfield changes value from 10 to 2}}
};
}
+
+void test3() {
+ int a = NULL; // expected-warning {{implicit conversion of NULL constant to integer}}
+ int b;
+ b = NULL; // expected-warning {{implicit conversion of NULL constant to integer}}
+ int c = ((((NULL)))); // expected-warning {{implicit conversion of NULL constant to integer}}
+ int d;
+ d = ((((NULL)))); // expected-warning {{implicit conversion of NULL constant to integer}}
+}
diff --git a/test/SemaCXX/copy-constructor-error.cpp b/test/SemaCXX/copy-constructor-error.cpp
index 9809bfc..64a7d58 100644
--- a/test/SemaCXX/copy-constructor-error.cpp
+++ b/test/SemaCXX/copy-constructor-error.cpp
@@ -13,10 +13,10 @@ void g() {
namespace PR6064 {
struct A {
A() { }
- inline A(A&, int);
+ inline A(A&, int); // expected-note {{was not a special member function}}
};
- A::A(A&, int = 0) { }
+ A::A(A&, int = 0) { } // expected-warning {{makes this constructor a copy constructor}}
void f() {
A const a;
diff --git a/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/test/SemaCXX/cxx0x-cursory-default-delete.cpp
new file mode 100644
index 0000000..61aee0e
--- /dev/null
+++ b/test/SemaCXX/cxx0x-cursory-default-delete.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+struct non_copiable {
+ non_copiable(const non_copiable&) = delete; // expected-note {{marked deleted here}}
+ non_copiable& operator = (const non_copiable&) = delete; // expected-note {{explicitly deleted}}
+ non_copiable() = default;
+};
+
+struct non_const_copy {
+ non_const_copy(non_const_copy&) = default; // expected-note {{not viable}}
+ non_const_copy& operator = (non_const_copy&) & = default; // expected-note {{not viable}}
+ non_const_copy& operator = (non_const_copy&) && = default; // expected-note {{not viable}}
+ non_const_copy() = default; // expected-note {{not viable}}
+};
+
+void fn1 () {
+ non_copiable nc;
+ non_copiable nc2 = nc; // expected-error {{deleted constructor}}
+ nc = nc; // expected-error {{deleted operator}}
+
+ non_const_copy ncc;
+ non_const_copy ncc2 = ncc;
+ ncc = ncc2;
+ const non_const_copy cncc;
+ non_const_copy ncc3 = cncc; // expected-error {{no matching}}
+ ncc = cncc; // expected-error {{no viable overloaded}}
+};
+
+struct non_const_derived : non_const_copy {
+ non_const_derived(const non_const_derived&) = default; // expected-error {{requires it to be non-const}}
+ non_const_derived& operator =(non_const_derived&) = default;
+};
+
+struct bad_decls {
+ bad_decls(volatile bad_decls&) = default; // expected-error {{may not be volatile}}
+ bad_decls&& operator = (bad_decls) = default; // expected-error 2{{lvalue reference}}
+ bad_decls& operator = (volatile bad_decls&) = default; // expected-error {{may not be volatile}}
+ bad_decls& operator = (const bad_decls&) const = default; // expected-error {{may not have 'const' or 'volatile' qualifiers}}
+};
+
+struct A {}; struct B {};
+
+struct except_spec_a {
+ virtual ~except_spec_a() throw(A);
+ except_spec_a() throw(A);
+};
+struct except_spec_b {
+ virtual ~except_spec_b() throw(B);
+ except_spec_b() throw(B);
+};
+
+struct except_spec_d_good : except_spec_a, except_spec_b {
+ ~except_spec_d_good();
+};
+except_spec_d_good::~except_spec_d_good() = default;
+// FIXME: This should error in the virtual override check.
+// It doesn't because we generate the implicit specification later than
+// appropriate.
+struct except_spec_d_bad : except_spec_a, except_spec_b {
+ ~except_spec_d_bad() = default;
+};
+
+// FIXME: This should error because the exceptions spec doesn't match.
+struct except_spec_d_mismatch : except_spec_a, except_spec_b {
+ except_spec_d_mismatch() throw(A) = default;
+};
+struct except_spec_d_match : except_spec_a, except_spec_b {
+ except_spec_d_match() throw(A, B) = default;
+};
diff --git a/test/SemaCXX/cxx0x-defaulted-functions.cpp b/test/SemaCXX/cxx0x-defaulted-functions.cpp
new file mode 100644
index 0000000..86c5fd1
--- /dev/null
+++ b/test/SemaCXX/cxx0x-defaulted-functions.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+void fn() = default; // expected-error {{only special member}}
+struct foo {
+ void fn() = default; // expected-error {{only special member}}
+
+ foo() = default;
+ foo(const foo&) = default;
+ foo(foo&) = default;
+ foo& operator = (const foo&) = default;
+ foo& operator = (foo&) = default;
+ ~foo() = default;
+};
+
+struct bar {
+ bar();
+ bar(const bar&);
+ bar(bar&);
+ bar& operator = (const bar&);
+ bar& operator = (bar&);
+ ~bar();
+};
+
+bar::bar() = default;
+bar::bar(const bar&) = default;
+bar::bar(bar&) = default;
+bar& bar::operator = (const bar&) = default;
+bar& bar::operator = (bar&) = default;
+bar::~bar() = default;
+
+// FIXME: static_assert(__is_trivial(foo), "foo should be trivial");
+
+static_assert(!__has_trivial_destructor(bar), "bar's destructor isn't trivial");
+static_assert(!__has_trivial_constructor(bar),
+ "bar's default constructor isn't trivial");
+static_assert(!__has_trivial_copy(bar), "bar has no trivial copy");
+static_assert(!__has_trivial_assign(bar), "bar has no trivial assign");
+
+void tester() {
+ foo f, g(f);
+ bar b, c(b);
+ f = g;
+ b = c;
+}
+
diff --git a/test/SemaCXX/cxx0x-delegating-ctors.cpp b/test/SemaCXX/cxx0x-delegating-ctors.cpp
index b211cb1..a3e6ff3 100644
--- a/test/SemaCXX/cxx0x-delegating-ctors.cpp
+++ b/test/SemaCXX/cxx0x-delegating-ctors.cpp
@@ -7,8 +7,9 @@ struct foo {
foo(int, int);
foo(bool);
foo(char);
- foo(float*);
- foo(float&);
+ foo(const float*);
+ foo(const float&);
+ foo(void*);
};
// Good
@@ -21,16 +22,27 @@ foo::foo () : foo(-1) {
foo::foo (int, int) : foo() {
}
-foo::foo (bool) : foo(true) { // expected-error{{delegates to itself}}
+foo::foo (bool) : foo(true) { // expected-error{{creates a delegation cycle}}
}
// Good
-foo::foo (float* f) : foo(*f) {
+foo::foo (const float* f) : foo(*f) { // expected-note{{it delegates to}}
}
-// FIXME: This should error
-foo::foo (float &f) : foo(&f) {
+foo::foo (const float &f) : foo(&f) { //expected-error{{creates a delegation cycle}} \
+ //expected-note{{which delegates to}}
}
foo::foo (char) : i(3), foo(3) { // expected-error{{must appear alone}}
}
+
+// This should not cause an infinite loop
+foo::foo (void*) : foo(4.0f) {
+}
+
+struct deleted_dtor {
+ ~deleted_dtor() = delete; // expected-note{{function has been explicitly marked deleted here}}
+ deleted_dtor();
+ deleted_dtor(int) : deleted_dtor() // expected-error{{attempt to use a deleted function}}
+ {}
+};
diff --git a/test/SemaCXX/cxx0x-deleted-default-ctor.cpp b/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
new file mode 100644
index 0000000..dcb6ba2
--- /dev/null
+++ b/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
@@ -0,0 +1,120 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+struct non_trivial {
+ non_trivial();
+ non_trivial(const non_trivial&);
+ non_trivial& operator = (const non_trivial&);
+ ~non_trivial();
+};
+
+union bad_union { // expected-note {{marked deleted here}}
+ non_trivial nt;
+};
+bad_union u; // expected-error {{call to deleted constructor}}
+union bad_union2 { // expected-note {{marked deleted here}}
+ const int i;
+};
+bad_union2 u2; // expected-error {{call to deleted constructor}}
+
+struct bad_anon { // expected-note {{marked deleted here}}
+ union {
+ non_trivial nt;
+ };
+};
+bad_anon a; // expected-error {{call to deleted constructor}}
+struct bad_anon2 { // expected-note {{marked deleted here}}
+ union {
+ const int i;
+ };
+};
+bad_anon2 a2; // expected-error {{call to deleted constructor}}
+
+// This would be great except that we implement
+union good_union {
+ const int i;
+ float f;
+};
+good_union gu;
+struct good_anon {
+ union {
+ const int i;
+ float f;
+ };
+};
+good_anon ga;
+
+struct good : non_trivial {
+ non_trivial nt;
+};
+good g;
+
+struct bad_const { // expected-note {{marked deleted here}}
+ const good g;
+};
+bad_const bc; // expected-error {{call to deleted constructor}}
+
+struct good_const {
+ const non_trivial nt;
+};
+good_const gc;
+
+struct no_default {
+ no_default() = delete;
+};
+struct no_dtor {
+ ~no_dtor() = delete;
+};
+
+struct bad_field_default { // expected-note {{marked deleted here}}
+ no_default nd;
+};
+bad_field_default bfd; // expected-error {{call to deleted constructor}}
+struct bad_base_default : no_default { // expected-note {{marked deleted here}}
+};
+bad_base_default bbd; // expected-error {{call to deleted constructor}}
+
+struct bad_field_dtor { // expected-note {{marked deleted here}}
+ no_dtor nd;
+};
+bad_field_dtor bfx; // expected-error {{call to deleted constructor}}
+struct bad_base_dtor : no_dtor { // expected-note {{marked deleted here}}
+};
+bad_base_dtor bbx; // expected-error {{call to deleted constructor}}
+
+struct ambiguous_default {
+ ambiguous_default();
+ ambiguous_default(int = 2);
+};
+struct has_amb_field { // expected-note {{marked deleted here}}
+ ambiguous_default ad;
+};
+has_amb_field haf; // expected-error {{call to deleted constructor}}
+
+class inaccessible_default {
+ inaccessible_default();
+};
+struct has_inacc_field { // expected-note {{marked deleted here}}
+ inaccessible_default id;
+};
+has_inacc_field hif; // expected-error {{call to deleted constructor}}
+
+class friend_default {
+ friend struct has_friend;
+ friend_default();
+};
+struct has_friend {
+ friend_default fd;
+};
+has_friend hf;
+
+struct defaulted_delete {
+ no_default nd;
+ defaulted_delete() = default; // expected-note {{marked deleted here}}
+};
+defaulted_delete dd; // expected-error {{call to deleted constructor}}
+
+struct late_delete {
+ no_default nd;
+ late_delete();
+};
+late_delete::late_delete() = default; // expected-error {{would delete it}}
diff --git a/test/SemaCXX/cxx0x-nontrivial-union.cpp b/test/SemaCXX/cxx0x-nontrivial-union.cpp
new file mode 100644
index 0000000..666e64b
--- /dev/null
+++ b/test/SemaCXX/cxx0x-nontrivial-union.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+struct non_trivial {
+ non_trivial();
+ non_trivial(const non_trivial&);
+ non_trivial& operator = (const non_trivial&);
+ ~non_trivial();
+};
+
+union u {
+ non_trivial nt;
+};
+
+union bad {
+ static int i; // expected-error {{static data member}}
+};
+
+struct s {
+ union {
+ non_trivial nt;
+ };
+};
diff --git a/test/SemaCXX/default-arg-special-member.cpp b/test/SemaCXX/default-arg-special-member.cpp
new file mode 100644
index 0000000..8402d382
--- /dev/null
+++ b/test/SemaCXX/default-arg-special-member.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -Wno-default-arg-special-member -Werror -fsyntax-only %s
+
+class foo {
+ foo(foo&, int); // expected-note {{was not a special member function}}
+ foo(int); // expected-note {{was not a special member function}}
+ foo(const foo&); // expected-note {{was a copy constructor}}
+};
+
+foo::foo(foo&, int = 0) { } // expected-warning {{makes this constructor a copy constructor}}
+foo::foo(int = 0) { } // expected-warning {{makes this constructor a default constructor}}
+foo::foo(const foo& = 0) { } //expected-warning {{makes this constructor a default constructor}}
diff --git a/test/SemaCXX/default-constructor-initializers.cpp b/test/SemaCXX/default-constructor-initializers.cpp
index 9da8556..e783f49 100644
--- a/test/SemaCXX/default-constructor-initializers.cpp
+++ b/test/SemaCXX/default-constructor-initializers.cpp
@@ -59,3 +59,10 @@ namespace PR7948 {
struct S { const int x; ~S(); };
const S arr[2] = { { 42 } };
}
+
+// This is valid
+union U {
+ const int i;
+ float f;
+};
+U u;
diff --git a/test/SemaCXX/defaulted-ctor-loop.cpp b/test/SemaCXX/defaulted-ctor-loop.cpp
new file mode 100644
index 0000000..6a41972
--- /dev/null
+++ b/test/SemaCXX/defaulted-ctor-loop.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+// WARNING: This test may recurse infinitely if failing.
+
+struct foo;
+struct bar {
+ bar(foo&);
+};
+struct foo {
+ bar b;
+ foo()
+ : b(b) // expected-warning{{field is uninitialized}}
+ {}
+};
diff --git a/test/SemaCXX/deleted-function-extension.cpp b/test/SemaCXX/deleted-function-extension.cpp
deleted file mode 100644
index fdf5ac8..0000000
--- a/test/SemaCXX/deleted-function-extension.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
-
-struct A {
- A(const A&) = delete; // expected-warning {{deleted function definition accepted as a C++0x extension}}
- A& operator=(const A&) = delete; // expected-warning {{deleted function definition accepted as a C++0x extension}}
-};
-
-void f() = delete; // expected-warning {{deleted function definition accepted as a C++0x extension}}
diff --git a/test/SemaCXX/deleted-function.cpp b/test/SemaCXX/deleted-function.cpp
index b3e1296..6a8965c 100644
--- a/test/SemaCXX/deleted-function.cpp
+++ b/test/SemaCXX/deleted-function.cpp
@@ -7,9 +7,8 @@ void fn() = delete; // expected-note {{candidate function has been explicitly de
void fn2(); // expected-note {{previous declaration is here}}
void fn2() = delete; // expected-error {{deleted definition must be first declaration}}
-void fn3() = delete;
-void fn3() {
- // FIXME: This definition should be invalid.
+void fn3() = delete; // expected-note {{previous definition is here}}
+void fn3() { // expected-error {{redefinition}}
}
void ov(int) {} // expected-note {{candidate function}}
diff --git a/test/SemaCXX/dependent-noexcept-unevaluated.cpp b/test/SemaCXX/dependent-noexcept-unevaluated.cpp
new file mode 100644
index 0000000..5bf6f9e
--- /dev/null
+++ b/test/SemaCXX/dependent-noexcept-unevaluated.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++0x %s
+
+template <class T>
+T&&
+declval() noexcept;
+
+template <class T>
+struct some_trait
+{
+ static const bool value = false;
+};
+
+template <class T>
+void swap(T& x, T& y) noexcept(some_trait<T>::value)
+{
+ T tmp(static_cast<T&&>(x));
+ x = static_cast<T&&>(y);
+ y = static_cast<T&&>(tmp);
+}
+
+template <class T, unsigned N>
+struct array
+{
+ T data[N];
+
+ void swap(array& a) noexcept(noexcept(swap(declval<T&>(), declval<T&>())));
+};
+
+struct DefaultOnly
+{
+ DefaultOnly() = default;
+ DefaultOnly(const DefaultOnly&) = delete;
+ DefaultOnly& operator=(const DefaultOnly&) = delete;
+ ~DefaultOnly() = default;
+};
+
+int main()
+{
+ array<DefaultOnly, 1> a, b;
+}
+
diff --git a/test/SemaCXX/dependent-types.cpp b/test/SemaCXX/dependent-types.cpp
index d9b5323..053e79b 100644
--- a/test/SemaCXX/dependent-types.cpp
+++ b/test/SemaCXX/dependent-types.cpp
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify -std=c++0x %s
+
+template<typename T> using U = int &;
template<typename T, int Size> void f() {
T x1;
@@ -7,4 +9,5 @@ template<typename T, int Size> void f() {
T x4[]; // expected-error{{needs an explicit size or an initializer}}
T x5[Size];
int x6[Size];
+ U<T> x7; // expected-error{{declaration of reference variable 'x7' requires an initializer}}
}
diff --git a/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp
index 01f21de..ec0539b 100644
--- a/test/SemaCXX/destructor.cpp
+++ b/test/SemaCXX/destructor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wnon-virtual-dtor -verify %s
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s
class A {
public:
~A();
@@ -173,6 +173,179 @@ template<class T> class TS2 { // expected-warning {{'nonvirtualdtor::TS2<int>' h
TS2<int> foo; // expected-note {{instantiation}}
}
+namespace dnvd { // delete-non-virtual-dtor warning
+struct NP {};
+
+struct B { // expected-warning {{has virtual functions but non-virtual destructor}}
+ virtual void foo();
+};
+
+struct D: B {}; // expected-warning {{has virtual functions but non-virtual destructor}}
+
+struct F final: B {}; // expected-warning {{has virtual functions but non-virtual destructor}}
+
+struct VB {
+ virtual void foo();
+ virtual ~VB();
+};
+
+struct VD: VB {};
+
+struct VF final: VB {};
+
+template <typename T>
+class simple_ptr {
+public:
+ simple_ptr(T* t): _ptr(t) {}
+ ~simple_ptr() { delete _ptr; } // \
+ // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}} \
+ // expected-warning {{delete called on 'dnvd::D' that has virtual functions but non-virtual destructor}}
+ T& operator*() const { return *_ptr; }
+private:
+ T* _ptr;
+};
+
+template <typename T>
+class simple_ptr2 {
+public:
+ simple_ptr2(T* t): _ptr(t) {}
+ ~simple_ptr2() { delete _ptr; } // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}}
+ T& operator*() const { return *_ptr; }
+private:
+ T* _ptr;
+};
+
+void use(B&);
+void use(VB&);
+
+void nowarnstack() {
+ B b; use(b);
+ D d; use(d);
+ F f; use(f);
+ VB vb; use(vb);
+ VD vd; use(vd);
+ VF vf; use(vf);
+}
+
+void nowarnnonpoly() {
+ {
+ NP* np = new NP();
+ delete np;
+ }
+ {
+ NP* np = new NP[4];
+ delete[] np;
+ }
+}
+
+void nowarnarray() {
+ {
+ B* b = new B[4];
+ delete[] b;
+ }
+ {
+ D* d = new D[4];
+ delete[] d;
+ }
+ {
+ VB* vb = new VB[4];
+ delete[] vb;
+ }
+ {
+ VD* vd = new VD[4];
+ delete[] vd;
+ }
+}
+
+template <typename T>
+void nowarntemplate() {
+ {
+ T* t = new T();
+ delete t;
+ }
+ {
+ T* t = new T[4];
+ delete[] t;
+ }
+}
+
+void nowarn0() {
+ {
+ F* f = new F();
+ delete f;
+ }
+ {
+ VB* vb = new VB();
+ delete vb;
+ }
+ {
+ VB* vb = new VD();
+ delete vb;
+ }
+ {
+ VD* vd = new VD();
+ delete vd;
+ }
+ {
+ VF* vf = new VF();
+ delete vf;
+ }
+}
+
+void warn0() {
+ {
+ B* b = new B();
+ delete b; // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}}
+ }
+ {
+ B* b = new D();
+ delete b; // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}}
+ }
+ {
+ D* d = new D();
+ delete d; // expected-warning {{delete called on 'dnvd::D' that has virtual functions but non-virtual destructor}}
+ }
+}
+
+void nowarn1() {
+ {
+ simple_ptr<F> f(new F());
+ use(*f);
+ }
+ {
+ simple_ptr<VB> vb(new VB());
+ use(*vb);
+ }
+ {
+ simple_ptr<VB> vb(new VD());
+ use(*vb);
+ }
+ {
+ simple_ptr<VD> vd(new VD());
+ use(*vd);
+ }
+ {
+ simple_ptr<VF> vf(new VF());
+ use(*vf);
+ }
+}
+
+void warn1() {
+ {
+ simple_ptr<B> b(new B()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr<dnvd::B>::~simple_ptr' requested here}}
+ use(*b);
+ }
+ {
+ simple_ptr2<B> b(new D()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr2<dnvd::B>::~simple_ptr2' requested here}}
+ use(*b);
+ }
+ {
+ simple_ptr<D> d(new D()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr<dnvd::D>::~simple_ptr' requested here}}
+ use(*d);
+ }
+}
+}
+
namespace PR9238 {
class B { public: ~B(); };
class C : virtual B { public: ~C() { } };
diff --git a/test/SemaCXX/enum-scoped.cpp b/test/SemaCXX/enum-scoped.cpp
index 8c4bfe7..fc871cf 100644
--- a/test/SemaCXX/enum-scoped.cpp
+++ b/test/SemaCXX/enum-scoped.cpp
@@ -109,3 +109,13 @@ void PR9333() {
scoped_enum e = scoped_enum::yes;
if (e == scoped_enum::no) { }
}
+
+// <rdar://problem/9366066>
+namespace rdar9366066 {
+ enum class X : unsigned { value };
+
+ void f(X x) {
+ x % X::value; // expected-error{{invalid operands to binary expression ('rdar9366066::X' and 'rdar9366066::X')}}
+ x % 8; // expected-error{{invalid operands to binary expression ('rdar9366066::X' and 'int')}}
+ }
+}
diff --git a/test/SemaCXX/expressions.cpp b/test/SemaCXX/expressions.cpp
index c4e9dcc..95ece48 100644
--- a/test/SemaCXX/expressions.cpp
+++ b/test/SemaCXX/expressions.cpp
@@ -32,3 +32,34 @@ namespace test1 {
bar(x += E_zero); // expected-error {{incompatible type}}
}
}
+
+int test2(int x) {
+ return x && 4; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+
+ return x && sizeof(int) == 4; // no warning, RHS is logical op.
+ return x && true;
+ return x && false;
+ return x || true;
+ return x || false;
+
+ return x && (unsigned)0; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+
+ return x || (unsigned)1; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+
+ return x || 0; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+ return x || 1; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+ return x || -1; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+ return x || 5; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+ return x && 0; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+ return x && 1; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+ return x && -1; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+ return x && 5; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+ return x || (0); // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+ return x || (1); // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+ return x || (-1); // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+ return x || (5); // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+ return x && (0); // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+ return x && (1); // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+ return x && (-1); // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+ return x && (5); // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+}
diff --git a/test/SemaCXX/generalized-initializers.cpp b/test/SemaCXX/generalized-initializers.cpp
new file mode 100644
index 0000000..ec37a0c
--- /dev/null
+++ b/test/SemaCXX/generalized-initializers.cpp
@@ -0,0 +1,174 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+// XFAIL: *
+
+template <typename T, typename U>
+struct same_type { static const bool value = false; };
+template <typename T>
+struct same_type<T, T> { static const bool value = true; };
+
+namespace std {
+ typedef decltype(sizeof(int)) size_t;
+
+ // libc++'s implementation
+ template <class _E>
+ class initializer_list
+ {
+ const _E* __begin_;
+ size_t __size_;
+
+ 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;
+
+ initializer_list() : __begin_(nullptr), __size_(0) {}
+
+ size_t size() const {return __size_;}
+ const _E* begin() const {return __begin_;}
+ const _E* end() const {return __begin_ + __size_;}
+ };
+}
+
+namespace integral {
+
+ void initialization() {
+ { const int a{}; static_assert(a == 0, ""); }
+ { const int a = {}; static_assert(a == 0, ""); }
+ { const int a{1}; static_assert(a == 1, ""); }
+ { const int a = {1}; static_assert(a == 1, ""); }
+ { const int a{1, 2}; } // expected-error {{excess elements}}
+ { const int a = {1, 2}; } // expected-error {{excess elements}}
+ { const short a{100000}; } // expected-error {{narrowing conversion}}
+ { const short a = {100000}; } // expected-error {{narrowing conversion}}
+ }
+
+ int function_call() {
+ void takes_int(int);
+ takes_int({1});
+
+ int ar[10];
+ (void) ar[{1}]; // expected-error {{initializer list is illegal with the built-in index operator}}
+
+ return {1};
+ }
+
+ void inline_init() {
+ (void) int{1};
+ (void) new int{1};
+ }
+
+ void initializer_list() {
+ std::initializer_list<int> il = { 1, 2, 3 };
+ std::initializer_list<double> dl = { 1.0, 2.0, 3 };
+ auto l = {1, 2, 3, 4};
+ static_assert(same_type<decltype(l), std::initializer_list<int>>::value, "");
+ auto bl = {1, 2.0}; // expected-error {{cannot deduce}}
+
+ for (int i : {1, 2, 3, 4}) {}
+ }
+
+ struct A {
+ int i;
+ A() : i{1} {}
+ };
+
+}
+
+namespace objects {
+
+ template <int N>
+ struct A {
+ A() { static_assert(N == 0, ""); }
+ A(int, double) { static_assert(N == 1, ""); }
+ A(int, int) { static_assert(N == 2, ""); }
+ A(std::initializer_list<int>) { static_assert(N == 3, ""); }
+ };
+
+ void initialization() {
+ { A<0> a{}; }
+ { A<0> a = {}; }
+ { A<1> a{1, 1.0}; }
+ { A<1> a = {1, 1.0}; }
+ { A<3> a{1, 2, 3, 4, 5, 6, 7, 8}; }
+ { A<3> a = {1, 2, 3, 4, 5, 6, 7, 8}; }
+ { A<3> a{1, 2, 3, 4, 5, 6, 7, 8}; }
+ { A<3> a{1, 2}; }
+ }
+
+ struct C {
+ C();
+ C(int, double);
+ C(int, int);
+ C(std::initializer_list<int>);
+
+ int operator[](C);
+ };
+
+ C function_call() {
+ void takes_C(C);
+ takes_C({1, 1.0});
+
+ C c;
+ c[{1, 1.0}];
+
+ return {1, 1.0};
+ }
+
+ void inline_init() {
+ (void) A<1>{1, 1.0};
+ (void) new A<1>{1, 1.0};
+ }
+
+ struct B {
+ B(C, int, C);
+ };
+
+ void nested_init() {
+ B b{{1, 1.0}, 2, {3, 4, 5, 6, 7}};
+ }
+}
+
+namespace litb {
+
+ // invalid
+ struct A { int a[2]; A():a({1, 2}) { } }; // expected-error {{}}
+
+ // invalid
+ int a({0}); // expected-error {{}}
+
+ // invalid
+ int const &b({0}); // expected-error {{}}
+
+ struct C { explicit C(int, int); C(int, long); };
+
+ // invalid
+ C c({1, 2}); // expected-error {{}}
+
+ // valid (by copy constructor).
+ C d({1, 2L}); // expected-error {{}}
+
+ // valid
+ C e{1, 2};
+
+ struct B {
+ template<typename ...T>
+ B(std::initializer_list<int>, T ...);
+ };
+
+ // invalid (the first phase only considers init-list ctors)
+ // (for the second phase, no constructor is viable)
+ B f{1, 2, 3};
+
+ // valid (T deduced to <>).
+ B g({1, 2, 3});
+
+}
diff --git a/test/SemaCXX/implicit-exception-spec.cpp b/test/SemaCXX/implicit-exception-spec.cpp
new file mode 100644
index 0000000..81babc0
--- /dev/null
+++ b/test/SemaCXX/implicit-exception-spec.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -std=c++0x -Wall %s
+
+template<bool b> struct ExceptionIf { static int f(); };
+template<> struct ExceptionIf<false> { typedef int f; };
+
+// The exception specification of a defaulted default constructor depends on
+// the contents of in-class member initializers. However, the in-class member
+// initializers can depend on the exception specification of the constructor,
+// since the class is considered complete within them. We reject any such cases.
+namespace InClassInitializers {
+ // Noexcept::Noexcept() is implicitly declared as noexcept(false), because it
+ // directly invokes ThrowSomething(). However...
+ //
+ // If noexcept(Noexcept()) is false, then Noexcept() is a constant expression,
+ // so noexcept(Noexcept()) is true. But if noexcept(Noexcept()) is true, then
+ // Noexcept::Noexcept is not declared constexpr, therefore noexcept(Noexcept())
+ // is false.
+ bool ThrowSomething() noexcept(false);
+ struct ConstExpr {
+ bool b = noexcept(ConstExpr()) && ThrowSomething(); // expected-error {{exception specification is not available until end of class definition}}
+ };
+ // We can use it now.
+ bool w = noexcept(ConstExpr());
+
+ // Much more obviously broken: we can't parse the initializer without already
+ // knowing whether it produces a noexcept expression.
+ struct TemplateArg {
+ int n = ExceptionIf<noexcept(TemplateArg())>::f(); // expected-error {{exception specification is not available until end of class definition}}
+ };
+ bool x = noexcept(TemplateArg());
+
+ // And within a nested class.
+ struct Nested {
+ struct Inner {
+ int n = ExceptionIf<noexcept(Nested())>::f(); // expected-error {{exception specification is not available until end of class definition}}
+ } inner;
+ };
+ bool y = noexcept(Nested());
+ bool z = noexcept(Nested::Inner());
+}
+
+// FIXME:
+// The same problem arises in delayed parsing of exception specifications,
+// which clang does not yet support.
+namespace ExceptionSpecification {
+ struct Nested { // expected-note {{not complete}}
+ struct T {
+ T() noexcept(!noexcept(Nested())); // expected-error {{incomplete type}}
+ } t;
+ };
+}
+
+// FIXME:
+// The same problem arises in delayed parsing of default arguments,
+// which clang does not yet support.
+namespace DefaultArgument {
+ // FIXME: this diagnostic is completely wrong.
+ struct Default { // expected-note {{explicitly marked deleted here}}
+ struct T {
+ T(int = ExceptionIf<noexcept(Default())::f()); // expected-error {{call to deleted constructor}}
+ } t;
+ };
+}
diff --git a/test/SemaCXX/implicit-member-functions.cpp b/test/SemaCXX/implicit-member-functions.cpp
index 5333094..8451739 100644
--- a/test/SemaCXX/implicit-member-functions.cpp
+++ b/test/SemaCXX/implicit-member-functions.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
struct A { };
-A::A() { } // expected-error {{definition of implicitly declared constructor}}
+A::A() { } // expected-error {{definition of implicitly declared default constructor}}
struct B { };
B::B(const B&) { } // expected-error {{definition of implicitly declared copy constructor}}
diff --git a/test/SemaCXX/member-expr.cpp b/test/SemaCXX/member-expr.cpp
index 68af415..981bae7 100644
--- a/test/SemaCXX/member-expr.cpp
+++ b/test/SemaCXX/member-expr.cpp
@@ -124,10 +124,10 @@ namespace PR9025 {
return fun.x; // expected-error{{base of member reference is an overloaded function; perhaps you meant to call it with no arguments?}}
}
- S fun2(); // expected-note{{possibly valid overload here}}
- S fun2(int i); // expected-note{{possibly valid overload here}}
+ S fun2();
+ S fun2(int i);
int g2() {
- return fun2.x; // expected-error{{base of member reference is an overloaded function; perhaps you meant to call it?}}
+ return fun2.x; // expected-error{{base of member reference is an overloaded function; perhaps you meant to call it with no arguments?}}
}
S fun3(int i=0);
@@ -140,4 +140,10 @@ namespace PR9025 {
int g4() {
return fun4.x; // expected-error{{base of member reference is a function; perhaps you meant to call it?}}
}
+
+ S fun5(int i); // expected-note{{possibly valid overload here}}
+ S fun5(float f); // expected-note{{possibly valid overload here}}
+ int g5() {
+ return fun5.x; // expected-error{{base of member reference is an overloaded function; perhaps you meant to call it?}}
+ }
}
diff --git a/test/SemaCXX/member-init.cpp b/test/SemaCXX/member-init.cpp
new file mode 100644
index 0000000..1b8c523
--- /dev/null
+++ b/test/SemaCXX/member-init.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -std=c++0x -Wall %s
+
+struct Bitfield {
+ int n : 3 = 7; // expected-error {{bitfield member cannot have an in-class initializer}}
+};
+
+int a;
+class NoWarning {
+ int &n = a;
+public:
+ int &GetN() { return n; }
+};
+
+bool b();
+int k;
+struct Recurse {
+ int &n = b() ? Recurse().n : k; // ok
+};
+
+struct UnknownBound {
+ int as[] = { 1, 2, 3 }; // expected-error {{array bound cannot be deduced from an in-class initializer}}
+ int bs[4] = { 4, 5, 6, 7 };
+ int cs[] = { 8, 9, 10 }; // expected-error {{array bound cannot be deduced from an in-class initializer}}
+};
+
+template<int n> struct T { static const int B; };
+template<> struct T<2> { template<int C, int D> using B = int; };
+const int C = 0, D = 0;
+struct S {
+ int as[] = { decltype(x)::B<C, D>(0) }; // expected-error {{array bound cannot be deduced from an in-class initializer}}
+ T<sizeof(as) / sizeof(int)> x; // expected-error {{requires a type specifier}}
+};
+
+struct ThrowCtor { ThrowCtor(int) noexcept(false); };
+struct NoThrowCtor { NoThrowCtor(int) noexcept(true); };
+
+struct Throw { ThrowCtor tc = 42; };
+struct NoThrow { NoThrowCtor tc = 42; };
+
+static_assert(!noexcept(Throw()), "incorrect exception specification");
+static_assert(noexcept(NoThrow()), "incorrect exception specification");
+
+struct CheckExcSpec {
+ CheckExcSpec() noexcept(true) = default;
+ int n = 0;
+};
+struct CheckExcSpecFail {
+ CheckExcSpecFail() noexcept(true) = default; // expected-error {{exception specification of explicitly defaulted default constructor does not match the calculated one}}
+ ThrowCtor tc = 123;
+};
diff --git a/test/SemaCXX/member-pointer.cpp b/test/SemaCXX/member-pointer.cpp
index 31c651a..de3b211 100644
--- a/test/SemaCXX/member-pointer.cpp
+++ b/test/SemaCXX/member-pointer.cpp
@@ -271,3 +271,28 @@ namespace rdar8358512 {
template void B<int>::test0b(); // expected-note {{in instantiation}}
}
+
+namespace PR9973 {
+ template<class R, class T> struct dm
+ {
+ typedef R T::*F;
+ F f_;
+ template<class U> int & call(U u)
+ { return u->*f_; } // expected-error{{non-const lvalue reference to type 'int' cannot bind to a temporary of type '<bound member function type>'}}
+
+ template<class U> int operator()(U u)
+ { call(u); } // expected-note{{in instantiation of}}
+ };
+
+ template<class R, class T>
+ dm<R, T> mem_fn(R T::*) ;
+
+ struct test
+ { int nullary_v(); };
+
+ void f()
+ {
+ test* t;
+ mem_fn(&test::nullary_v)(t); // expected-note{{in instantiation of}}
+ }
+}
diff --git a/test/SemaCXX/nullptr.cpp b/test/SemaCXX/nullptr.cpp
index 84c80aa..d69af58 100644
--- a/test/SemaCXX/nullptr.cpp
+++ b/test/SemaCXX/nullptr.cpp
@@ -60,6 +60,10 @@ nullptr_t f(nullptr_t null)
// You can reinterpret_cast nullptr to an integer.
(void)reinterpret_cast<uintptr_t>(nullptr);
+ (void)reinterpret_cast<uintptr_t>(*pn);
+
+ int *ip = *pn;
+ if (*pn) { }
// You can throw nullptr.
throw nullptr;
@@ -104,3 +108,56 @@ namespace test3 {
f("%p", nullptr);
}
}
+
+int array0[__is_scalar(nullptr_t)? 1 : -1];
+int array1[__is_pod(nullptr_t)? 1 : -1];
+int array2[sizeof(nullptr_t) == sizeof(void*)? 1 : -1];
+
+// FIXME: when we implement constexpr, this will be testable.
+#if 0
+int relational0[nullptr < nullptr? -1 : 1];
+int relational1[nullptr > nullptr? -1 : 1];
+int relational2[nullptr <= nullptr? 1 : -1];
+int relational3[nullptr >= nullptr? 1 : -1];
+int equality[nullptr == nullptr? 1 : -1];
+int inequality[nullptr != nullptr? -1 : 1];
+#endif
+
+namespace overloading {
+ int &f1(int*);
+ float &f1(bool);
+
+ void test_f1() {
+ int &ir = (f1)(nullptr);
+ }
+
+ struct ConvertsToNullPtr {
+ operator nullptr_t() const;
+ };
+
+ void test_conversion(ConvertsToNullPtr ctn) {
+ (void)(ctn == ctn);
+ (void)(ctn != ctn);
+ (void)(ctn <= ctn);
+ (void)(ctn >= ctn);
+ (void)(ctn < ctn);
+ (void)(ctn > ctn);
+ }
+}
+
+namespace templates {
+ template<typename T, nullptr_t Value>
+ struct X {
+ X() { ptr = Value; }
+
+ T *ptr;
+ };
+
+ X<int, nullptr> x;
+
+
+ template<int (*fp)(int), int* p, int A::* pmd, int (A::*pmf)(int)>
+ struct X2 {};
+
+ X2<nullptr, nullptr, nullptr, nullptr> x2;
+}
diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp
index 81a88a3..9cc4899 100644
--- a/test/SemaCXX/overload-call.cpp
+++ b/test/SemaCXX/overload-call.cpp
@@ -503,3 +503,25 @@ namespace rdar8499524 {
g(W());
}
}
+
+namespace rdar9173984 {
+ template <typename T, unsigned long N> int &f(const T (&)[N]);
+ template <typename T> float &f(const T *);
+
+ void test() {
+ int arr[2] = {0, 0};
+ int *arrp = arr;
+ int &ir = f(arr);
+ float &fr = f(arrp);
+ }
+}
+
+namespace PR9507 {
+ void f(int * const&); // expected-note{{candidate function}}
+ void f(int const(&)[1]); // expected-note{{candidate function}}
+
+ int main() {
+ int n[1];
+ f(n); // expected-error{{call to 'f' is ambiguous}}
+ }
+}
diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp
index 44d013f..462d023 100644
--- a/test/SemaCXX/overloaded-operator.cpp
+++ b/test/SemaCXX/overloaded-operator.cpp
@@ -33,7 +33,7 @@ struct A {
A make_A();
-bool operator==(A&, Z&); // expected-note 2{{candidate function}}
+bool operator==(A&, Z&); // expected-note 3{{candidate function}}
void h(A a, const A ac, Z z) {
make_A() == z;
@@ -68,7 +68,7 @@ struct E2 {
};
// C++ [over.match.oper]p3 - enum restriction.
-float& operator==(E1, E2);
+float& operator==(E1, E2); // expected-note{{candidate function}}
void enum_test(Enum1 enum1, Enum2 enum2, E1 e1, E2 e2, Enum1 next_enum1) {
float &f1 = (e1 == e2);
@@ -85,8 +85,8 @@ class pr5244_foo
pr5244_foo(char);
};
-bool operator==(const pr5244_foo& s1, const pr5244_foo& s2);
-bool operator==(char c, const pr5244_foo& s);
+bool operator==(const pr5244_foo& s1, const pr5244_foo& s2); // expected-note{{candidate function}}
+bool operator==(char c, const pr5244_foo& s); // expected-note{{candidate function}}
enum pr5244_bar
{
@@ -399,3 +399,12 @@ namespace rdar9136502 {
y << x.i; // expected-error{{a bound member function may only be called}}
}
}
+
+namespace rdar9222009 {
+class StringRef {
+ inline bool operator==(StringRef LHS, StringRef RHS) { // expected-error{{overloaded 'operator==' must be a binary operator (has 3 parameters)}}
+ return !(LHS == RHS); // expected-error{{invalid operands to binary expression ('rdar9222009::StringRef' and 'rdar9222009::StringRef')}}
+ }
+};
+
+}
diff --git a/test/SemaCXX/redeclared-alias-template.cpp b/test/SemaCXX/redeclared-alias-template.cpp
new file mode 100644
index 0000000..b368fcf
--- /dev/null
+++ b/test/SemaCXX/redeclared-alias-template.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+template<typename T> using A = int; // expected-note 2{{previous}}
+template<typename T> using A = char; // expected-error {{type alias template redefinition with different types ('char' vs 'int')}}
+template<typename T1, typename T2> using A = T1; // expected-error {{too many template parameters in template redeclaration}}
+
+template<typename T1, typename T2> using B = T1; // expected-note {{previous}}
+template<typename T2, typename T1> using B = T1; // expected-error {{type alias template redefinition with different types}}
+
+
+template<typename> struct S;
+template<template<typename> class F> using FInt = F<int>;
+template<typename X> using SXRInt = FInt<S<X>::template R>;
+template<typename X> using SXRInt = typename S<X>::template R<int>; // ok, redeclaration.
+
+template<template<typename> class> struct TT;
+
+namespace FilterLookup {
+ TT<A> f(); // expected-note {{previous declaration is here}}
+
+ template<typename> using A = int;
+ TT<A> f(); // expected-error {{functions that differ only in their return type cannot be overloaded}}
+}
diff --git a/test/SemaCXX/reinterpret-cast.cpp b/test/SemaCXX/reinterpret-cast.cpp
index f526249..68005a5 100644
--- a/test/SemaCXX/reinterpret-cast.cpp
+++ b/test/SemaCXX/reinterpret-cast.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -ffreestanding %s
+// RUN: %clang_cc1 -fsyntax-only -verify -ffreestanding -Wundefined-reinterpret-cast %s
#include <stdint.h>
@@ -116,3 +116,163 @@ namespace PR9564 {
__attribute((ext_vector_type(4))) typedef float v4;
float& w(v4 &a) { return reinterpret_cast<float&>(a[1]); } // expected-error {{not allowed}}
}
+
+void dereference_reinterpret_cast() {
+ struct A {};
+ typedef A A2;
+ class B {};
+ typedef B B2;
+ A a;
+ B b;
+ A2 a2;
+ B2 b2;
+ long l;
+ double d;
+ float f;
+ char c;
+ unsigned char uc;
+ void* v_ptr;
+ (void)reinterpret_cast<double&>(l); // expected-warning {{reinterpret_cast from 'long' to 'double &' has undefined behavior}}
+ (void)*reinterpret_cast<double*>(&l); // expected-warning {{dereference of type 'double *' that was reinterpret_cast from type 'long *' has undefined behavior}}
+ (void)reinterpret_cast<double&>(f); // expected-warning {{reinterpret_cast from 'float' to 'double &' has undefined behavior}}
+ (void)*reinterpret_cast<double*>(&f); // expected-warning {{dereference of type 'double *' that was reinterpret_cast from type 'float *' has undefined behavior}}
+ (void)reinterpret_cast<float&>(l); // expected-warning {{reinterpret_cast from 'long' to 'float &' has undefined behavior}}
+ (void)*reinterpret_cast<float*>(&l); // expected-warning {{dereference of type 'float *' that was reinterpret_cast from type 'long *' has undefined behavior}}
+ (void)reinterpret_cast<float&>(d); // expected-warning {{reinterpret_cast from 'double' to 'float &' has undefined behavior}}
+ (void)*reinterpret_cast<float*>(&d); // expected-warning {{dereference of type 'float *' that was reinterpret_cast from type 'double *' has undefined behavior}}
+
+ // TODO: add warning for tag types
+ (void)reinterpret_cast<A&>(b);
+ (void)*reinterpret_cast<A*>(&b);
+ (void)reinterpret_cast<B&>(a);
+ (void)*reinterpret_cast<B*>(&a);
+ (void)reinterpret_cast<A2&>(b2);
+ (void)*reinterpret_cast<A2*>(&b2);
+ (void)reinterpret_cast<B2&>(a2);
+ (void)*reinterpret_cast<B2*>(&a2);
+
+ // Casting to itself is allowed
+ (void)reinterpret_cast<A&>(a);
+ (void)*reinterpret_cast<A*>(&a);
+ (void)reinterpret_cast<B&>(b);
+ (void)*reinterpret_cast<B*>(&b);
+ (void)reinterpret_cast<long&>(l);
+ (void)*reinterpret_cast<long*>(&l);
+ (void)reinterpret_cast<double&>(d);
+ (void)*reinterpret_cast<double*>(&d);
+ (void)reinterpret_cast<char&>(c);
+ (void)*reinterpret_cast<char*>(&c);
+
+ // Casting to and from chars are allowable
+ (void)reinterpret_cast<A&>(c);
+ (void)*reinterpret_cast<A*>(&c);
+ (void)reinterpret_cast<B&>(c);
+ (void)*reinterpret_cast<B*>(&c);
+ (void)reinterpret_cast<long&>(c);
+ (void)*reinterpret_cast<long*>(&c);
+ (void)reinterpret_cast<double&>(c);
+ (void)*reinterpret_cast<double*>(&c);
+ (void)reinterpret_cast<char&>(l);
+ (void)*reinterpret_cast<char*>(&l);
+ (void)reinterpret_cast<char&>(d);
+ (void)*reinterpret_cast<char*>(&d);
+ (void)reinterpret_cast<char&>(f);
+ (void)*reinterpret_cast<char*>(&f);
+
+ // Casting from void pointer.
+ (void)*reinterpret_cast<A*>(v_ptr);
+ (void)*reinterpret_cast<B*>(v_ptr);
+ (void)*reinterpret_cast<long*>(v_ptr);
+ (void)*reinterpret_cast<double*>(v_ptr);
+ (void)*reinterpret_cast<float*>(v_ptr);
+
+ // Casting to void pointer
+ (void)*reinterpret_cast<void*>(&a);
+ (void)*reinterpret_cast<void*>(&b);
+ (void)*reinterpret_cast<void*>(&l);
+ (void)*reinterpret_cast<void*>(&d);
+ (void)*reinterpret_cast<void*>(&f);
+}
+
+void reinterpret_cast_whitelist () {
+ // the dynamic type of the object
+ int a;
+ float b;
+ (void)reinterpret_cast<int&>(a);
+ (void)*reinterpret_cast<int*>(&a);
+ (void)reinterpret_cast<float&>(b);
+ (void)*reinterpret_cast<float*>(&b);
+
+ // a cv-qualified version of the dynamic object
+ (void)reinterpret_cast<const int&>(a);
+ (void)*reinterpret_cast<const int*>(&a);
+ (void)reinterpret_cast<volatile int&>(a);
+ (void)*reinterpret_cast<volatile int*>(&a);
+ (void)reinterpret_cast<const volatile int&>(a);
+ (void)*reinterpret_cast<const volatile int*>(&a);
+ (void)reinterpret_cast<const float&>(b);
+ (void)*reinterpret_cast<const float*>(&b);
+ (void)reinterpret_cast<volatile float&>(b);
+ (void)*reinterpret_cast<volatile float*>(&b);
+ (void)reinterpret_cast<const volatile float&>(b);
+ (void)*reinterpret_cast<const volatile float*>(&b);
+
+ // a type that is the signed or unsigned type corresponding to the dynamic
+ // type of the object
+ signed d;
+ unsigned e;
+ (void)reinterpret_cast<signed&>(d);
+ (void)*reinterpret_cast<signed*>(&d);
+ (void)reinterpret_cast<signed&>(e);
+ (void)*reinterpret_cast<signed*>(&e);
+ (void)reinterpret_cast<unsigned&>(d);
+ (void)*reinterpret_cast<unsigned*>(&d);
+ (void)reinterpret_cast<unsigned&>(e);
+ (void)*reinterpret_cast<unsigned*>(&e);
+
+ // a type that is the signed or unsigned type corresponding a cv-qualified
+ // version of the dynamic type the object
+ (void)reinterpret_cast<const signed&>(d);
+ (void)*reinterpret_cast<const signed*>(&d);
+ (void)reinterpret_cast<const signed&>(e);
+ (void)*reinterpret_cast<const signed*>(&e);
+ (void)reinterpret_cast<const unsigned&>(d);
+ (void)*reinterpret_cast<const unsigned*>(&d);
+ (void)reinterpret_cast<const unsigned&>(e);
+ (void)*reinterpret_cast<const unsigned*>(&e);
+ (void)reinterpret_cast<volatile signed&>(d);
+ (void)*reinterpret_cast<volatile signed*>(&d);
+ (void)reinterpret_cast<volatile signed&>(e);
+ (void)*reinterpret_cast<volatile signed*>(&e);
+ (void)reinterpret_cast<volatile unsigned&>(d);
+ (void)*reinterpret_cast<volatile unsigned*>(&d);
+ (void)reinterpret_cast<volatile unsigned&>(e);
+ (void)*reinterpret_cast<volatile unsigned*>(&e);
+ (void)reinterpret_cast<const volatile signed&>(d);
+ (void)*reinterpret_cast<const volatile signed*>(&d);
+ (void)reinterpret_cast<const volatile signed&>(e);
+ (void)*reinterpret_cast<const volatile signed*>(&e);
+ (void)reinterpret_cast<const volatile unsigned&>(d);
+ (void)*reinterpret_cast<const volatile unsigned*>(&d);
+ (void)reinterpret_cast<const volatile unsigned&>(e);
+ (void)*reinterpret_cast<const volatile unsigned*>(&e);
+
+ // an aggregate or union type that includes one of the aforementioned types
+ // among its members (including, recursively, a member of a subaggregate or
+ // contained union)
+ // TODO: checking is not implemented for tag types
+
+ // a type that is a (possible cv-qualified) base class type of the dynamic
+ // type of the object
+ // TODO: checking is not implemented for tag types
+
+ // a char or unsigned char type
+ (void)reinterpret_cast<char&>(a);
+ (void)*reinterpret_cast<char*>(&a);
+ (void)reinterpret_cast<unsigned char&>(a);
+ (void)*reinterpret_cast<unsigned char*>(&a);
+ (void)reinterpret_cast<char&>(b);
+ (void)*reinterpret_cast<char*>(&b);
+ (void)reinterpret_cast<unsigned char&>(b);
+ (void)*reinterpret_cast<unsigned char*>(&b);
+}
diff --git a/test/SemaCXX/return.cpp b/test/SemaCXX/return.cpp
index af7f50c..b457f6a 100644
--- a/test/SemaCXX/return.cpp
+++ b/test/SemaCXX/return.cpp
@@ -39,6 +39,11 @@ g();
char* const h(); // expected-warning{{'const' type qualifier on return type has no effect}}
char* volatile i(); // expected-warning{{'volatile' type qualifier on return type has no effect}}
+char*
+volatile // expected-warning{{'const volatile' type qualifiers on return type have no effect}}
+const
+j();
+
const volatile int scalar_cv(); // expected-warning{{'const volatile' type qualifiers on return type have no effect}}
}
@@ -53,3 +58,14 @@ namespace PR9328 {
class foo {
operator int * const ();
};
+
+namespace PR10057 {
+ struct S {
+ ~S();
+ };
+
+ template <class VarType>
+ void Test(const VarType& value) {
+ return S() = value;
+ }
+}
diff --git a/test/SemaCXX/struct-class-redecl.cpp b/test/SemaCXX/struct-class-redecl.cpp
index d3d6d79..5c59578 100644
--- a/test/SemaCXX/struct-class-redecl.cpp
+++ b/test/SemaCXX/struct-class-redecl.cpp
@@ -1,8 +1,164 @@
// RUN: %clang_cc1 -fsyntax-only -Wmismatched-tags -verify %s
+// RUN: %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}}
-template<typename T> struct Y; // expected-note{{previous}}
+template<typename T> struct Y; // expected-note{{did you mean class here?}}
template<class U> class Y { }; // expected-warning{{previously declared}}
-union X { int x; float y; }; // expected-error{{use of 'X' with tag type that does not match previous declaration}}
+class A;
+class A; // expected-note{{previous use is here}}
+struct A; // expected-warning{{struct 'A' was previously declared as a class}}
+
+class B; // expected-note{{did you mean struct here?}}
+class B; // expected-note{{previous use is here}}\
+ // expected-note{{did you mean struct here?}}
+struct B; // expected-warning{{struct 'B' was previously declared as a class}}
+struct B {}; // expected-warning{{'B' defined as a struct here but previously declared as a class}}
+
+class C; // expected-note{{previous use is here}}
+struct C; // expected-warning{{struct 'C' was previously declared as a class}}\
+ // expected-note{{previous use is here}}\
+ // expected-note{{did you mean class here?}}
+class C; // expected-warning{{class 'C' was previously declared as a struct}}\
+ // expected-note{{previous use is here}}
+struct C; // expected-warning{{struct 'C' was previously declared as a class}}\
+ // expected-note{{did you mean class here?}}
+class C {}; // expected-warning{{'C' defined as a class here but previously declared as a struct}}
+
+struct D {}; // expected-note{{previous definition is here}}\
+ // expected-note{{previous use is here}}
+class D {}; // expected-error{{redefinition of 'D'}}
+struct D;
+class D; // expected-warning{{class 'D' was previously declared as a struct}}\
+ // expected-note{{did you mean struct here?}}
+
+class E;
+class E;
+class E {};
+class E;
+
+struct F;
+struct F;
+struct F {};
+struct F;
+
+template<class U> class G; // expected-note{{previous use is here}}\
+ // expected-note{{did you mean struct here?}}
+template<class U> struct G; // expected-warning{{struct template 'G' was previously declared as a class template}}
+template<class U> struct G {}; // expected-warning{{'G' defined as a struct template here but previously declared as a class template}}
+
+/*
+*** 'X' messages ***
+CHECK: warning: struct 'X' was previously declared as a class
+CHECK: {{^}}typedef struct X * X_t;
+CHECK: {{^}} ^{{$}}
+CHECK: note: previous use is here
+CHECK: {{^}}class X;
+CHECK: {{^}} ^{{$}}
+CHECK: error: use of 'X' with tag type that does not match previous declaration
+CHECK: {{^}}union X { int x; float y; };
+CHECK: {{^}}^~~~~{{$}}
+CHECK: {{^}}class{{$}}
+CHECK: note: previous use is here
+CHECK: {{^}}class X;
+CHECK: {{^}} ^{{$}}
+*** 'Y' messages ***
+CHECK: warning: 'Y' defined as a class template here but
+ previously declared as a struct template
+CHECK: {{^}}template<class U> class Y { };
+CHECK: {{^}} ^{{$}}
+CHECK: note: did you mean class here?
+CHECK: {{^}}template<typename T> struct Y;
+CHECK: {{^}} ^~~~~~{{$}}
+CHECK: {{^}} class{{$}}
+*** 'A' messages ***
+CHECK: warning: struct 'A' was previously declared as a class
+CHECK: {{^}}struct A;
+CHECK: {{^}}^{{$}}
+CHECK: note: previous use is here
+CHECK: {{^}}class A;
+CHECK: {{^}} ^{{$}}
+*** 'B' messages ***
+CHECK: warning: struct 'B' was previously declared as a class
+CHECK: {{^}}struct B;
+CHECK: {{^}}^{{$}}
+CHECK: note: previous use is here
+CHECK: {{^}}class B;
+CHECK: {{^}} ^{{$}}
+CHECK: 'B' defined as a struct here but previously declared as a class
+CHECK: {{^}}struct B {};
+CHECK: {{^}}^{{$}}
+CHECK: note: did you mean struct here?
+CHECK: {{^}}class B;
+CHECK: {{^}}^~~~~{{$}}
+CHECK: {{^}}struct{{$}}
+CHECK: note: did you mean struct here?
+CHECK: {{^}}class B;
+CHECK: {{^}}^~~~~{{$}}
+CHECK: {{^}}struct{{$}}
+*** 'C' messages ***
+CHECK: warning: struct 'C' was previously declared as a class
+CHECK: {{^}}struct C;
+CHECK: {{^}}^{{$}}
+CHECK: note: previous use is here
+CHECK: {{^}}class C;
+CHECK: {{^}} ^{{$}}
+CHECK: warning: class 'C' was previously declared as a struct
+CHECK: {{^}}class C;
+CHECK: {{^}}^{{$}}
+CHECK: note: previous use is here
+CHECK: {{^}}struct C;
+CHECK: {{^}} ^{{$}}
+CHECK: warning: struct 'C' was previously declared as a class
+CHECK: {{^}}struct C;
+CHECK: {{^}}^{{$}}
+CHECK: note: previous use is here
+CHECK: {{^}}class C;
+CHECK: {{^}} ^{{$}}
+CHECK: warning: 'C' defined as a class here but previously declared as a struct
+CHECK: {{^}}class C {};
+CHECK: {{^}}^{{$}}
+CHECK: note: did you mean class here?
+CHECK: {{^}}struct C;
+CHECK: {{^}}^~~~~~{{$}}
+CHECK: {{^}}class{{$}}
+CHECK: note: did you mean class here?
+CHECK: {{^}}struct C;
+CHECK: {{^}}^~~~~~{{$}}
+CHECK: {{^}}class{{$}}
+*** 'D' messages ***
+CHECK: error: redefinition of 'D'
+CHECK: {{^}}class D {};
+CHECK: {{^}} ^{{$}}
+CHECK: note: previous definition is here
+CHECK: {{^}}struct D {};
+CHECK: {{^}} ^{{$}}
+CHECK: warning: class 'D' was previously declared as a struct
+CHECK: {{^}}class D;
+CHECK: {{^}}^{{$}}
+CHECK: note: previous use is here
+CHECK: {{^}}struct D {};
+CHECK: {{^}} ^{{$}}
+CHECK: note: did you mean struct here?
+CHECK: {{^}}class D;
+CHECK: {{^}}^~~~~{{$}}
+CHECK: {{^}}struct{{$}}
+*** 'E' messages ***
+*** 'F' messages ***
+*** 'G' messages ***
+CHECK: warning: struct template 'G' was previously declared as a class template
+CHECK: {{^}}template<class U> struct G;
+CHECK: {{^}} ^{{$}}
+CHECK: note: previous use is here
+CHECK: {{^}}template<class U> class G;
+CHECK: {{^}} ^{{$}}
+CHECK: warning: 'G' defined as a struct template here but previously declared as a class template
+CHECK: {{^}}template<class U> struct G {};
+CHECK: {{^}} ^{{$}}
+CHECK: note: did you mean struct here?
+CHECK: {{^}}template<class U> class G;
+CHECK: {{^}} ^~~~~
+CHECK: {{^}} struct
+*/
diff --git a/test/SemaCXX/switch.cpp b/test/SemaCXX/switch.cpp
index 3882a1f..8a8cf33 100644
--- a/test/SemaCXX/switch.cpp
+++ b/test/SemaCXX/switch.cpp
@@ -8,7 +8,7 @@ void test() {
}
int n = 3;
- switch (n && 1) { // expected-warning {{bool}}
+ switch (n && true) { // expected-warning {{bool}}
case 1:
break;
}
diff --git a/test/SemaCXX/tag-ambig.cpp b/test/SemaCXX/tag-ambig.cpp
new file mode 100644
index 0000000..6403cf3
--- /dev/null
+++ b/test/SemaCXX/tag-ambig.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// <rdar://problem/9168556>
+typedef struct Point Point;
+
+namespace NameSpace {
+ class Point;
+}
+
+using namespace NameSpace;
+
+class Test
+{
+public:
+ struct Point { };
+ virtual bool testMethod (Test::Point& p) = 0;
+};
+
+// PR8151
+namespace A { struct Face {}; }
+namespace B { struct Face {}; }
+using namespace A;
+using namespace B;
+
+class C {
+ struct Face;
+ Face *mFaces;
+};
diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp
index 96e9696..30cc6a3 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 %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++0x %s
#define T(b) (b) ? 1 : -1
#define F(b) (b) ? -1 : 1
@@ -38,8 +38,7 @@ typedef Derives DerivesArNB[];
struct DerivesEmpty : Empty {};
struct HasCons { HasCons(int); };
struct HasCopyAssign { HasCopyAssign operator =(const HasCopyAssign&); };
-struct HasMoveAssign { HasMoveAssign operator =(const HasMoveAssign&&); }; // \
- // expected-warning {{rvalue references}}
+struct HasMoveAssign { HasMoveAssign operator =(const HasMoveAssign&&); };
struct HasDest { ~HasDest(); };
class HasPriv { int priv; };
class HasProt { protected: int prot; };
@@ -870,6 +869,15 @@ struct NonTrivialStruct {
}
};
+struct SuperNonTrivialStruct {
+ SuperNonTrivialStruct() { }
+ ~SuperNonTrivialStruct() { }
+};
+
+struct NonTCStruct {
+ NonTCStruct(const NonTCStruct&) {}
+};
+
void is_trivial2()
{
int t01[T(__is_trivial(char))];
@@ -897,6 +905,39 @@ void is_trivial2()
int t30[F(__is_trivial(void))];
int t31[F(__is_trivial(NonTrivialStruct))];
+ int t32[F(__is_trivial(SuperNonTrivialStruct))];
+ int t33[F(__is_trivial(NonTCStruct))];
+}
+
+void is_trivially_copyable2()
+{
+ int t01[T(__is_trivially_copyable(char))];
+ int t02[T(__is_trivially_copyable(int))];
+ int t03[T(__is_trivially_copyable(long))];
+ int t04[T(__is_trivially_copyable(short))];
+ int t05[T(__is_trivially_copyable(signed char))];
+ int t06[T(__is_trivially_copyable(wchar_t))];
+ int t07[T(__is_trivially_copyable(bool))];
+ int t08[T(__is_trivially_copyable(float))];
+ int t09[T(__is_trivially_copyable(double))];
+ int t10[T(__is_trivially_copyable(long double))];
+ int t11[T(__is_trivially_copyable(unsigned char))];
+ int t12[T(__is_trivially_copyable(unsigned int))];
+ int t13[T(__is_trivially_copyable(unsigned long long))];
+ int t14[T(__is_trivially_copyable(unsigned long))];
+ int t15[T(__is_trivially_copyable(unsigned short))];
+ int t16[T(__is_trivially_copyable(ClassType))];
+ int t17[T(__is_trivially_copyable(Derives))];
+ int t18[T(__is_trivially_copyable(Enum))];
+ int t19[T(__is_trivially_copyable(IntAr))];
+ int t20[T(__is_trivially_copyable(Union))];
+ int t21[T(__is_trivially_copyable(UnionAr))];
+ int t22[T(__is_trivially_copyable(TrivialStruct))];
+ int t23[T(__is_trivially_copyable(NonTrivialStruct))];
+
+ int t30[F(__is_trivially_copyable(void))];
+ int t32[F(__is_trivially_copyable(SuperNonTrivialStruct))];
+ int t31[F(__is_trivially_copyable(NonTCStruct))];
}
struct CStruct {
@@ -1027,7 +1068,7 @@ struct HasCopy {
};
struct HasMove {
- HasMove(HasMove&& cp); // expected-warning {{rvalue references}}
+ HasMove(HasMove&& cp);
};
struct HasTemplateCons {
@@ -1211,6 +1252,9 @@ void has_nothrow_copy() {
{ int arr[F(__has_nothrow_copy(cvoid))]; }
}
+template<bool b> struct assert_expr;
+template<> struct assert_expr<true> {};
+
void has_nothrow_constructor() {
{ int arr[T(__has_nothrow_constructor(Int))]; }
{ int arr[T(__has_nothrow_constructor(IntAr))]; }
@@ -1238,6 +1282,11 @@ void has_nothrow_constructor() {
{ int arr[F(__has_nothrow_constructor(void))]; }
{ int arr[F(__has_nothrow_constructor(cvoid))]; }
{ int arr[F(__has_nothrow_constructor(HasTemplateCons))]; }
+
+ // While parsing an in-class initializer, the constructor is not known to be
+ // non-throwing yet.
+ struct HasInClassInit { int n = (assert_expr<!__has_nothrow_constructor(HasInClassInit)>(), 0); };
+ { int arr[T(__has_nothrow_constructor(HasInClassInit))]; }
}
void has_virtual_destructor() {
@@ -1474,6 +1523,51 @@ void is_trivial()
{ int arr[F(__is_trivial(cvoid))]; }
}
+void is_trivially_copyable()
+{
+ { int arr[T(__is_trivially_copyable(int))]; }
+ { int arr[T(__is_trivially_copyable(Enum))]; }
+ { int arr[T(__is_trivially_copyable(POD))]; }
+ { int arr[T(__is_trivially_copyable(Int))]; }
+ { int arr[T(__is_trivially_copyable(IntAr))]; }
+ { int arr[T(__is_trivially_copyable(IntArNB))]; }
+ { int arr[T(__is_trivially_copyable(Statics))]; }
+ { int arr[T(__is_trivially_copyable(Empty))]; }
+ { int arr[T(__is_trivially_copyable(EmptyUnion))]; }
+ { int arr[T(__is_trivially_copyable(Union))]; }
+ { int arr[T(__is_trivially_copyable(Derives))]; }
+ { int arr[T(__is_trivially_copyable(DerivesAr))]; }
+ { int arr[T(__is_trivially_copyable(DerivesArNB))]; }
+ { int arr[T(__is_trivially_copyable(DerivesEmpty))]; }
+ { int arr[T(__is_trivially_copyable(HasFunc))]; }
+ { int arr[T(__is_trivially_copyable(HasOp))]; }
+ { int arr[T(__is_trivially_copyable(HasConv))]; }
+ { int arr[T(__is_trivially_copyable(HasAssign))]; }
+ { int arr[T(__is_trivially_copyable(HasAnonymousUnion))]; }
+ { int arr[T(__is_trivially_copyable(HasPriv))]; }
+ { int arr[T(__is_trivially_copyable(HasProt))]; }
+ { int arr[T(__is_trivially_copyable(DerivesHasPriv))]; }
+ { int arr[T(__is_trivially_copyable(DerivesHasProt))]; }
+ { int arr[T(__is_trivially_copyable(Vector))]; }
+ { int arr[T(__is_trivially_copyable(VectorExt))]; }
+ { int arr[T(__is_trivially_copyable(HasCons))]; }
+ { int arr[T(__is_trivially_copyable(HasRef))]; }
+ { int arr[T(__is_trivially_copyable(HasNonPOD))]; }
+ { int arr[T(__is_trivially_copyable(DerivesHasCons))]; }
+ { int arr[T(__is_trivially_copyable(DerivesHasRef))]; }
+
+ { int arr[F(__is_trivially_copyable(HasCopyAssign))]; }
+ { int arr[F(__is_trivially_copyable(HasMoveAssign))]; }
+ { int arr[F(__is_trivially_copyable(HasDest))]; }
+ { int arr[F(__is_trivially_copyable(HasVirt))]; }
+ { int arr[F(__is_trivially_copyable(DerivesHasCopyAssign))]; }
+ { int arr[F(__is_trivially_copyable(DerivesHasMoveAssign))]; }
+ { int arr[F(__is_trivially_copyable(DerivesHasDest))]; }
+ { int arr[F(__is_trivially_copyable(DerivesHasVirt))]; }
+ { int arr[F(__is_trivially_copyable(void))]; }
+ { int arr[F(__is_trivially_copyable(cvoid))]; }
+}
+
void array_rank() {
int t01[T(__array_rank(IntAr) == 1)];
int t02[T(__array_rank(ConstIntArAr) == 2)];
diff --git a/test/SemaCXX/underlying_type.cpp b/test/SemaCXX/underlying_type.cpp
new file mode 100644
index 0000000..607d9ad
--- /dev/null
+++ b/test/SemaCXX/underlying_type.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -ffreestanding -fsyntax-only -verify -std=c++0x %s
+
+#include "limits.h"
+
+template<typename T, typename U>
+struct is_same_type {
+ static const bool value = false;
+};
+template <typename T>
+struct is_same_type<T, T> {
+ static const bool value = true;
+};
+
+__underlying_type(int) a; // expected-error {{only enumeration types}}
+__underlying_type(struct b) c; // expected-error {{only enumeration types}}
+
+enum class f : char;
+static_assert(is_same_type<char, __underlying_type(f)>::value,
+ "f has the wrong underlying type");
+
+enum g {d = INT_MIN };
+static_assert(is_same_type<int, __underlying_type(g)>::value,
+ "g has the wrong underlying type");
+
+__underlying_type(f) h;
+static_assert(is_same_type<char, decltype(h)>::value,
+ "h has the wrong type");
+
+template <typename T>
+struct underlying_type {
+ typedef __underlying_type(T) type; // expected-error {{only enumeration types}}
+};
+
+static_assert(is_same_type<underlying_type<f>::type, char>::value,
+ "f has the wrong underlying type in the template");
+
+underlying_type<int>::type e; // expected-note {{requested here}}
diff --git a/test/SemaCXX/value-initialization.cpp b/test/SemaCXX/value-initialization.cpp
index 10520fb..dfe0f46 100644
--- a/test/SemaCXX/value-initialization.cpp
+++ b/test/SemaCXX/value-initialization.cpp
@@ -1,12 +1,11 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
-struct A { // expected-error {{implicit default constructor for 'A' must explicitly initialize the const member 'i'}} \
- // expected-warning{{struct 'A' does not declare any constructor to initialize its non-modifiable members}}
- const int i; // expected-note {{declared here}} \
- // expected-note{{const member 'i' will never be initialized}}
+struct A { //expected-note {{marked deleted here}} \
+ // expected-warning {{does not declare any constructor to initialize}}
+ const int i; // expected-note{{const member 'i' will never be initialized}}
virtual void f() { }
};
int main () {
- (void)A(); // expected-note {{first required here}}
+ (void)A(); // expected-error {{call to deleted constructor}}
}
diff --git a/test/SemaCXX/vararg-non-pod.cpp b/test/SemaCXX/vararg-non-pod.cpp
index 55ec941..df0080f 100644
--- a/test/SemaCXX/vararg-non-pod.cpp
+++ b/test/SemaCXX/vararg-non-pod.cpp
@@ -56,15 +56,18 @@ void t4()
}
class E {
- E(int, ...);
+ E(int, ...); // expected-note 2{{implicitly declared private here}}
};
void t5()
{
C c(10);
- E e(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}}
- (void)E(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}}
+ E e(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}} \
+ // expected-error{{calling a private constructor of class 'E'}}
+ (void)E(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}} \
+ // expected-error{{calling a private constructor of class 'E'}}
+
}
// PR5761: unevaluated operands and the non-POD warning
diff --git a/test/SemaCXX/vtable-instantiation.cc b/test/SemaCXX/vtable-instantiation.cc
index 49949a7..2a1b989 100644
--- a/test/SemaCXX/vtable-instantiation.cc
+++ b/test/SemaCXX/vtable-instantiation.cc
@@ -1,21 +1,22 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-// PR8640
-template<class T1> struct C1 {
- virtual void c1() {
- T1 t1 = 3; // expected-error {{cannot initialize a variable}}
- }
-};
+namespace PR8640 {
+ template<class T1> struct C1 {
+ virtual void c1() {
+ T1 t1 = 3; // expected-error {{cannot initialize a variable}}
+ }
+ };
-template<class T2> struct C2 {
- void c2() {
- new C1<T2>(); // expected-note {{in instantiation of member function}}
- }
-};
+ template<class T2> struct C2 {
+ void c2() {
+ new C1<T2>(); // expected-note {{in instantiation of member function}}
+ }
+ };
-void f() {
- C2<int*> c2;
- c2.c2(); // expected-note {{in instantiation of member function}}
+ void f() {
+ C2<int*> c2;
+ c2.c2(); // expected-note {{in instantiation of member function}}
+ }
}
namespace PR9325 {
@@ -42,5 +43,26 @@ namespace PR9325 {
{
Target<int*>* traits = &Provider<int*>::Instance;
}
+}
+namespace PR10020 {
+ struct MG {
+ virtual void Accept(int) = 0;
+ };
+
+ template <typename Type>
+ struct GMG : MG {
+ void Accept(int i) {
+ static_cast<Type *>(0)->Accept(i); // expected-error{{member reference base}}
+ }
+ static GMG* Method() { return &singleton; } // expected-note{{in instantiation of}}
+ static GMG singleton;
+ };
+
+ template <typename Type>
+ GMG<Type> GMG<Type>::singleton;
+
+ void test(void) {
+ GMG<int>::Method(); // expected-note{{in instantiation of}}
+ }
}
diff --git a/test/SemaCXX/warn-bad-memaccess.cpp b/test/SemaCXX/warn-bad-memaccess.cpp
new file mode 100644
index 0000000..e7d095f
--- /dev/null
+++ b/test/SemaCXX/warn-bad-memaccess.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -fsyntax-only -Wdynamic-class-memaccess -verify %s
+
+extern "C" void *memset(void *, int, unsigned);
+extern "C" void *memmove(void *s1, const void *s2, unsigned n);
+extern "C" void *memcpy(void *s1, const void *s2, unsigned n);
+
+// Several types that should not warn.
+struct S1 {} s1;
+struct S2 { int x; } s2;
+struct S3 { float x, y; S1 s[4]; void (*f)(S1**); } s3;
+
+class C1 {
+ int x, y, z;
+public:
+ void foo() {}
+} c1;
+
+struct X1 { virtual void f(); } x1;
+struct X2 : virtual S1 {} x2;
+
+void test_warn() {
+ memset(&x1, 0, sizeof x1); // \
+ // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
+ // expected-note {{explicitly cast the pointer to silence this warning}}
+ memset(&x2, 0, sizeof x2); // \
+ // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
+ // expected-note {{explicitly cast the pointer to silence this warning}}
+
+ memmove(&x1, 0, sizeof x1); // \
+ // expected-warning{{destination for this 'memmove' call is a pointer to dynamic class}} \
+ // expected-note {{explicitly cast the pointer to silence this warning}}
+ memmove(0, &x1, sizeof x1); // \
+ // expected-warning{{source of this 'memmove' call is a pointer to dynamic class}} \
+ // expected-note {{explicitly cast the pointer to silence this warning}}
+ memcpy(&x1, 0, sizeof x1); // \
+ // expected-warning{{destination for this 'memcpy' call is a pointer to dynamic class}} \
+ // expected-note {{explicitly cast the pointer to silence this warning}}
+ memcpy(0, &x1, sizeof x1); // \
+ // expected-warning{{source of this 'memcpy' call is a pointer to dynamic class}} \
+ // expected-note {{explicitly cast the pointer to silence this warning}}
+}
+
+void test_nowarn(void *void_ptr) {
+ int i, *iptr;
+ float y;
+ char c;
+
+ memset(&i, 0, sizeof i);
+ memset(&iptr, 0, sizeof iptr);
+ memset(&y, 0, sizeof y);
+ memset(&c, 0, sizeof c);
+ memset(void_ptr, 0, 42);
+ memset(&s1, 0, sizeof s1);
+ memset(&s2, 0, sizeof s2);
+ memset(&s3, 0, sizeof s3);
+ memset(&c1, 0, sizeof c1);
+
+ // Unevaluated code shouldn't warn.
+ (void)sizeof memset(&x1, 0, sizeof x1);
+
+ // Dead code shouldn't warn.
+ if (false) memset(&x1, 0, sizeof x1);
+}
+
+namespace N {
+ void *memset(void *, int, unsigned);
+ void test_nowarn() {
+ N::memset(&x1, 0, sizeof x1);
+ }
+}
diff --git a/test/SemaCXX/warn-non-pod-memset.cpp b/test/SemaCXX/warn-non-pod-memset.cpp
deleted file mode 100644
index fbdcead..0000000
--- a/test/SemaCXX/warn-non-pod-memset.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -Wnon-pod-memset -verify %s
-
-extern void *memset(void *, int, unsigned);
-
-// Several POD types that should not warn.
-struct S1 {} s1;
-struct S2 { int x; } s2;
-struct S3 { float x, y; S1 s[4]; void (*f)(S1**); } s3;
-
-// We use the C++11 concept of POD for this warning, so ensure a non-aggregate
-// still warns.
-class C1 {
- int x, y, z;
-public:
- void foo() {}
-} c1;
-
-// Non-POD types that should warn.
-struct X1 { X1(); } x1;
-struct X2 { ~X2(); } x2;
-struct X3 { virtual void f(); } x3;
-struct X4 : X2 {} x4;
-struct X5 : virtual S1 {} x5;
-
-void test_warn() {
- memset(&x1, 0, sizeof x1); // \
- // expected-warning {{destination for this memset call is a pointer to a non-POD type}} \
- // expected-note {{explicitly cast the pointer to silence this warning}}
- memset(&x2, 0, sizeof x2); // \
- // expected-warning {{destination for this memset call is a pointer to a non-POD type}} \
- // expected-note {{explicitly cast the pointer to silence this warning}}
- memset(&x3, 0, sizeof x3); // \
- // expected-warning {{destination for this memset call is a pointer to a non-POD type}} \
- // expected-note {{explicitly cast the pointer to silence this warning}}
- memset(&x4, 0, sizeof x4); // \
- // expected-warning {{destination for this memset call is a pointer to a non-POD type}} \
- // expected-note {{explicitly cast the pointer to silence this warning}}
- memset(&x5, 0, sizeof x5); // \
- // expected-warning {{destination for this memset call is a pointer to a non-POD type}} \
- // expected-note {{explicitly cast the pointer to silence this warning}}
-}
-
-void test_nowarn(void *void_ptr) {
- int i, *iptr;
- float y;
- char c;
-
- memset(&i, 0, sizeof i);
- memset(&iptr, 0, sizeof iptr);
- memset(&y, 0, sizeof y);
- memset(&c, 0, sizeof c);
- memset(void_ptr, 0, 42);
- memset(&s1, 0, sizeof s1);
- memset(&s2, 0, sizeof s2);
- memset(&s3, 0, sizeof s3);
- memset(&c1, 0, sizeof c1);
-
- // Unevaluated code shouldn't warn.
- (void)sizeof memset(&x1, 0, sizeof x1);
-
- // Dead code shouldn't warn.
- if (false) memset(&x1, 0, sizeof x1);
-}
diff --git a/test/SemaCXX/warn-pure-virtual-call-from-ctor-dtor.cpp b/test/SemaCXX/warn-pure-virtual-call-from-ctor-dtor.cpp
new file mode 100644
index 0000000..698eccd
--- /dev/null
+++ b/test/SemaCXX/warn-pure-virtual-call-from-ctor-dtor.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+struct A {
+ A() { f(); } // expected-warning {{call to pure virtual member function 'f'; overrides of 'f' in subclasses are not available in the constructor of 'A'}}
+ ~A() { f(); } // expected-warning {{call to pure virtual member function 'f'; overrides of 'f' in subclasses are not available in the destructor of 'A'}}
+
+ virtual void f() = 0; // expected-note 2 {{'f' declared here}}
+};
OpenPOWER on IntegriCloud