From 222e2a7620e6520ffaf4fc4e69d79c18da31542e Mon Sep 17 00:00:00 2001 From: "Zancanaro; Carlo" Date: Mon, 24 Sep 2012 09:58:17 +1000 Subject: Add the clang library to the repo (with some of my changes, too). --- .../CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp | 78 ++++++++ .../CXX/dcl.decl/dcl.init/dcl.init.aggr/p4.cpp | 18 ++ .../CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp | 17 ++ .../dcl.init/dcl.init.list/p7-0x-fixits.cpp | 33 ++++ .../CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp | 209 ++++++++++++++++++++ .../dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp | 210 +++++++++++++++++++++ .../CXX/dcl.decl/dcl.init/dcl.init.ref/basic.cpp | 19 ++ .../test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp | 14 ++ .../test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp | 3 + .../CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp | 194 +++++++++++++++++++ .../dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp | 77 ++++++++ .../dcl.init.ref/p5-cxx0x-no-extra-copy.cpp | 64 +++++++ .../dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp | 53 ++++++ .../CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp | 135 +++++++++++++ .../test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp | 40 ++++ .../CXX/dcl.decl/dcl.init/dcl.init.string/p1.cpp | 19 ++ .../CXX/dcl.decl/dcl.init/dcl.init.string/p2.cpp | 2 + clang/test/CXX/dcl.decl/dcl.init/p14-0x.cpp | 44 +++++ clang/test/CXX/dcl.decl/dcl.init/p5.cpp | 20 ++ clang/test/CXX/dcl.decl/dcl.init/p6.cpp | 28 +++ 20 files changed, 1277 insertions(+) create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p4.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/basic.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx0x-no-extra-copy.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.string/p1.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/dcl.init.string/p2.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/p14-0x.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/p5.cpp create mode 100644 clang/test/CXX/dcl.decl/dcl.init/p6.cpp (limited to 'clang/test/CXX/dcl.decl/dcl.init') diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp new file mode 100644 index 0000000..7764980 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +// An aggregate is an array or a class... +struct Aggr { +private: + static const int n; + void f(); +protected: + struct Inner { int m; }; +public: + bool &br; // expected-note {{default constructor of 'Aggr' is implicitly deleted because field 'br' of reference type 'bool &' would not be initialized}} +}; +bool b; +Aggr ag = { b }; + +// with no user-provided constructors, ... +struct NonAggr1a { // expected-note 2 {{candidate constructor}} + NonAggr1a(int, int); // expected-note {{candidate constructor}} + int k; +}; +// In C++0x, 'user-provided' is only defined for special member functions, so +// this type is considered to be an aggregate. This is considered to be +// a language defect. +NonAggr1a na1a = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr1a'}} + +struct NonAggr1b { + NonAggr1b(const NonAggr1b &); // expected-note {{candidate constructor}} + int k; +}; +NonAggr1b na1b = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr1b'}} + +// no brace-or-equal-initializers for non-static data members, ... +struct NonAggr2 { // expected-note 3 {{candidate constructor}} + int m = { 123 }; +}; +NonAggr2 na2 = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr2'}} + +// no private... +struct NonAggr3 { // expected-note 3 {{candidate constructor}} +private: + int n; +}; +NonAggr3 na3 = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr3'}} + +// or protected non-static data members, ... +struct NonAggr4 { // expected-note 3 {{candidate constructor}} +protected: + int n; +}; +NonAggr4 na4 = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr4'}} + +// no base classes, ... +struct NonAggr5 : Aggr { // expected-note 3 {{candidate constructor}} +}; +NonAggr5 na5 = { b }; // expected-error {{no matching constructor for initialization of 'NonAggr5'}} +template +struct MaybeAggr5a : BaseList... {}; // expected-note {{default constructor of 'MaybeAggr5a' is implicitly deleted because base class 'Aggr' has a deleted default constructor}} +MaybeAggr5a<> ma5a0 = {}; // ok +MaybeAggr5a ma5a1 = {}; // expected-error {{call to implicitly-deleted default constructor of 'MaybeAggr5a'}} + +// and no virtual functions. +struct NonAggr6 { // expected-note 3 {{candidate constructor}} + virtual void f(); + int n; +}; +NonAggr6 na6 = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr6'}} + +struct DefaultedAggr { + int n; + + DefaultedAggr() = default; + DefaultedAggr(const DefaultedAggr &) = default; + DefaultedAggr(DefaultedAggr &&) = default; + DefaultedAggr &operator=(const DefaultedAggr &) = default; + DefaultedAggr &operator=(DefaultedAggr &) = default; + ~DefaultedAggr() = default; +}; +DefaultedAggr da = { 42 } ; diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p4.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p4.cpp new file mode 100644 index 0000000..1041571 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p4.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 -pedantic -Werror %s +int a1[] = { 1, 3, 5 }; +void f() { + int a2[] = { 1, 3, 5 }; +} +template +void tf() { + T t; + // Element type may be dependent + T a3[] = { 1, 3, 5 }; + // As might be the initializer list, value + int a5[] = { sizeof(T) }; + // or even type. + int a6[] = { t.get() }; +} + +// Allowed by GNU extension +int a4[] = {}; // expected-error {{zero size arrays}} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp new file mode 100644 index 0000000..b30e0ec --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +void f0() { + int &ir = { 17 }; // expected-error{{reference to type 'int' cannot bind to an initializer list}} +} + +namespace PR12453 { + template + void f(int i) { + T x{i}; // expected-error{{non-constant-expression cannot be narrowed from type 'int' to 'float' in initializer list}} \ + // expected-note{{override this message by inserting an explicit cast}} + T y{i}; // expected-error{{non-constant-expression cannot be narrowed from type 'int' to 'float' in initializer list}} \ + // expected-note{{override this message by inserting an explicit cast}} + } + + template void f(int); // expected-note{{in instantiation of function template specialization 'PR12453::f' requested here}} +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp new file mode 100644 index 0000000..0bea4ed --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -fsyntax-only -Wc++11-compat -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s + +// Verify that the appropriate fixits are emitted for narrowing conversions in +// initializer lists. + +typedef short int16_t; + +void fixits() { + int x = 999; + struct {char c;} c2 = {x}; + // CHECK: warning:{{.*}} cannot be narrowed + // CHECK: fix-it:{{.*}}:26}:"static_cast(" + // CHECK: fix-it:{{.*}}:27}:")" + struct {int16_t i;} i16 = {70000}; + // CHECK: warning:{{.*}} cannot be narrowed + // CHECK: fix-it:{{.*}}:30}:"static_cast(" + // CHECK: fix-it:{{.*}}:35}:")" +} + +template +void maybe_shrink_int(T t) { + struct {T t;} t2 = {700}; +} + +void test_template() { + maybe_shrink_int((char)3); + // CHECK: warning:{{.*}} cannot be narrowed + // CHECK: note:{{.*}} in instantiation + // CHECK: note:{{.*}} override + // FIXME: This should be static_cast. + // CHECK: fix-it:{{.*}}"static_cast(" + // CHECK: fix-it:{{.*}}")" +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp new file mode 100644 index 0000000..db20ea6 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp @@ -0,0 +1,209 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -triple x86_64-apple-macosx10.6.7 -verify %s + +// Verify that narrowing conversions in initializer lists cause errors in C++0x +// mode. + +void std_example() { + int x = 999; // x is not a constant expression + const int y = 999; + const int z = 99; + char c1 = x; // OK, though it might narrow (in this case, it does narrow) + char c2{x}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + char c3{y}; // expected-error {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} + char c4{z}; // OK: no narrowing needed + unsigned char uc1 = {5}; // OK: no narrowing needed + unsigned char uc2 = {-1}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + unsigned int ui1 = {-1}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + signed int si1 = + { (unsigned int)-1 }; // expected-error {{ cannot be narrowed }} expected-note {{override}} + int ii = {2.0}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + float f1 { x }; // expected-error {{ cannot be narrowed }} expected-note {{override}} + float f2 { 7 }; // OK: 7 can be exactly represented as a float + int f(int); + int a[] = + { 2, f(2), f(2.0) }; // OK: the double-to-int conversion is not at the top level +} + +// Test each rule individually. + +template +struct Agg { + T t; +}; + +template +struct Convert { + constexpr Convert(T v) : v(v) {} + constexpr operator T() const { return v; } + T v; +}; +template Convert ConvertVar(); + +// C++0x [dcl.init.list]p7: A narrowing conversion is an implicit conversion +// +// * from a floating-point type to an integer type, or + +void float_to_int() { + Agg a1 = {1.0F}; // expected-error {{type 'float' cannot be narrowed to 'char'}} expected-note {{override}} + Agg a2 = {1.0}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg a3 = {1.0L}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + + float f = 1.0; + double d = 1.0; + long double ld = 1.0; + Agg a4 = {f}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg a5 = {d}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg a6 = {ld}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + + Agg ce1 = { Convert(1.0) }; // expected-error {{type 'float' cannot be narrowed to 'char'}} expected-note {{override}} + Agg ce2 = { ConvertVar() }; // expected-error {{type 'double' cannot be narrowed to 'char'}} expected-note {{override}} +} + +// * from long double to double or float, or from double to float, except where +// the source is a constant expression and the actual value after conversion +// is within the range of values that can be represented (even if it cannot be +// represented exactly), or + +void shrink_float() { + // These aren't constant expressions. + float f = 1.0; + double d = 1.0; + long double ld = 1.0; + + // Variables. + Agg f1 = {f}; // OK (no-op) + Agg f2 = {d}; // expected-error {{non-constant-expression cannot be narrowed from type 'double' to 'float'}} expected-note {{override}} + Agg f3 = {ld}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + // Exact constants. + Agg f4 = {1.0}; // OK (double constant represented exactly) + Agg f5 = {1.0L}; // OK (long double constant represented exactly) + // Inexact but in-range constants. + Agg f6 = {0.1}; // OK (double constant in range but rounded) + Agg f7 = {0.1L}; // OK (long double constant in range but rounded) + // Out of range constants. + Agg f8 = {1E50}; // expected-error {{constant expression evaluates to 1.000000e+50 which cannot be narrowed to type 'float'}} expected-note {{override}} + Agg f9 = {1E50L}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + // More complex constant expression. + constexpr long double e40 = 1E40L, e30 = 1E30L, e39 = 1E39L; + Agg f10 = {e40 - 5 * e39 + e30 - 5 * e39}; // OK + + // Variables. + Agg d1 = {f}; // OK (widening) + Agg d2 = {d}; // OK (no-op) + Agg d3 = {ld}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + // Exact constant. + Agg d4 = {1.0L}; // OK (long double constant represented exactly) + // Inexact but in-range constant. + Agg d5 = {0.1L}; // OK (long double constant in range but rounded) + // Out of range constant. + Agg d6 = {1E315L}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + // More complex constant expression. + constexpr long double e315 = 1E315L, e305 = 1E305L, e314 = 1E314L; + Agg d7 = {e315 - 5 * e314 + e305 - 5 * e314}; // OK + + Agg ce1 = { Convert(1e300) }; // expected-error {{constant expression evaluates to 1.000000e+300 which cannot be narrowed to type 'float'}} expected-note {{override}} + Agg ce2 = { ConvertVar() }; // expected-error {{non-constant-expression cannot be narrowed from type 'long double' to 'double'}} expected-note {{override}} +} + +// * from an integer type or unscoped enumeration type to a floating-point type, +// except where the source is a constant expression and the actual value after +// conversion will fit into the target type and will produce the original +// value when converted back to the original type, or +void int_to_float() { + // Not a constant expression. + char c = 1; + + // Variables. Yes, even though all char's will fit into any floating type. + Agg f1 = {c}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg f2 = {c}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg f3 = {c}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + + // Constants. + Agg f4 = {12345678}; // OK (exactly fits in a float) + Agg f5 = {123456789}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + + Agg ce1 = { Convert(123456789) }; // expected-error {{constant expression evaluates to 123456789 which cannot be narrowed to type 'float'}} expected-note {{override}} + Agg ce2 = { ConvertVar() }; // expected-error {{non-constant-expression cannot be narrowed from type 'long long' to 'double'}} expected-note {{override}} +} + +// * from an integer type or unscoped enumeration type to an integer type that +// cannot represent all the values of the original type, except where the +// source is a constant expression and the actual value after conversion will +// fit into the target type and will produce the original value when converted +// back to the original type. +void shrink_int() { + // Not a constant expression. + short s = 1; + unsigned short us = 1; + Agg c1 = {s}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg s1 = {s}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg s2 = {us}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + + // "that cannot represent all the values of the original type" means that the + // validity of the program depends on the relative sizes of integral types. + // This test compiles with -m64, so sizeof(int) i1 = {l1}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + long long ll = 1; + Agg l2 = {ll}; // OK + + // Constants. + Agg c2 = {127}; // OK + Agg c3 = {300}; // expected-error {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} + + Agg i2 = {0x7FFFFFFFU}; // OK + Agg i3 = {0x80000000U}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg i4 = {-0x80000000L}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + + // Bool is also an integer type, but conversions to it are a different AST + // node. + Agg b1 = {0}; // OK + Agg b2 = {1}; // OK + Agg b3 = {-1}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + + // Conversions from pointers to booleans aren't narrowing conversions. + Agg b = {&b1}; // OK + + Agg ce1 = { Convert(100000) }; // expected-error {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{override}} expected-warning {{changes value from 100000 to -31072}} + Agg ce2 = { ConvertVar() }; // expected-error {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{override}} +} + +// Be sure that type- and value-dependent expressions in templates get the error +// too. + +template +void maybe_shrink_int(T t) { + Agg s1 = {t}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg s2 = {I}; // expected-error {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} + Agg t2 = {700}; // expected-error {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} +} + +void test_template() { + maybe_shrink_int<15>((int)3); // expected-note {{in instantiation}} + maybe_shrink_int<70000>((char)3); // expected-note {{in instantiation}} +} + + +// We don't want qualifiers on the types in the diagnostic. + +void test_qualifiers(int i) { + const int j = i; + struct {const unsigned char c;} c1 = {j}; // expected-error {{from type 'int' to 'unsigned char' in}} expected-note {{override}} + // Template arguments make it harder to avoid printing qualifiers: + Agg c2 = {j}; // expected-error {{from type 'int' to 'const unsigned char' in}} expected-note {{override}} +} + +// Test SFINAE checks. +template struct Value { }; + +template +int &check_narrowed(Value); + +template +float &check_narrowed(...); + +void test_narrowed(Value vi, Value vd) { + int &ir = check_narrowed(vd); + float &fr = check_narrowed(vi); +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp new file mode 100644 index 0000000..4bcf113 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp @@ -0,0 +1,210 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wno-error=c++11-narrowing -triple x86_64-apple-macosx10.6.7 -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wno-error=narrowing -triple x86_64-apple-macosx10.6.7 -verify %s + +// Verify that narrowing conversions in initializer lists cause errors in C++0x +// mode. + +void std_example() { + int x = 999; // x is not a constant expression + const int y = 999; + const int z = 99; + char c1 = x; // OK, though it might narrow (in this case, it does narrow) + char c2{x}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + char c3{y}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} + char c4{z}; // OK: no narrowing needed + unsigned char uc1 = {5}; // OK: no narrowing needed + unsigned char uc2 = {-1}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + unsigned int ui1 = {-1}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + signed int si1 = + { (unsigned int)-1 }; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + int ii = {2.0}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + float f1 { x }; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + float f2 { 7 }; // OK: 7 can be exactly represented as a float + int f(int); + int a[] = + { 2, f(2), f(2.0) }; // OK: the double-to-int conversion is not at the top level +} + +// Test each rule individually. + +template +struct Agg { + T t; +}; + +template +struct Convert { + constexpr Convert(T v) : v(v) {} + constexpr operator T() const { return v; } + T v; +}; +template Convert ConvertVar(); + +// C++0x [dcl.init.list]p7: A narrowing conversion is an implicit conversion +// +// * from a floating-point type to an integer type, or + +void float_to_int() { + Agg a1 = {1.0F}; // expected-warning {{type 'float' cannot be narrowed to 'char'}} expected-note {{override}} + Agg a2 = {1.0}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg a3 = {1.0L}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + + float f = 1.0; + double d = 1.0; + long double ld = 1.0; + Agg a4 = {f}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg a5 = {d}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg a6 = {ld}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + + Agg ce1 = { Convert(1.0) }; // expected-warning {{type 'float' cannot be narrowed to 'char'}} expected-note {{override}} + Agg ce2 = { ConvertVar() }; // expected-warning {{type 'double' cannot be narrowed to 'char'}} expected-note {{override}} +} + +// * from long double to double or float, or from double to float, except where +// the source is a constant expression and the actual value after conversion +// is within the range of values that can be represented (even if it cannot be +// represented exactly), or + +void shrink_float() { + // These aren't constant expressions. + float f = 1.0; + double d = 1.0; + long double ld = 1.0; + + // Variables. + Agg f1 = {f}; // OK (no-op) + Agg f2 = {d}; // expected-warning {{non-constant-expression cannot be narrowed from type 'double' to 'float'}} expected-note {{override}} + Agg f3 = {ld}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + // Exact constants. + Agg f4 = {1.0}; // OK (double constant represented exactly) + Agg f5 = {1.0L}; // OK (long double constant represented exactly) + // Inexact but in-range constants. + Agg f6 = {0.1}; // OK (double constant in range but rounded) + Agg f7 = {0.1L}; // OK (long double constant in range but rounded) + // Out of range constants. + Agg f8 = {1E50}; // expected-warning {{constant expression evaluates to 1.000000e+50 which cannot be narrowed to type 'float'}} expected-note {{override}} + Agg f9 = {1E50L}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + // More complex constant expression. + constexpr long double e40 = 1E40L, e30 = 1E30L, e39 = 1E39L; + Agg f10 = {e40 - 5 * e39 + e30 - 5 * e39}; // OK + + // Variables. + Agg d1 = {f}; // OK (widening) + Agg d2 = {d}; // OK (no-op) + Agg d3 = {ld}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + // Exact constant. + Agg d4 = {1.0L}; // OK (long double constant represented exactly) + // Inexact but in-range constant. + Agg d5 = {0.1L}; // OK (long double constant in range but rounded) + // Out of range constant. + Agg d6 = {1E315L}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + // More complex constant expression. + constexpr long double e315 = 1E315L, e305 = 1E305L, e314 = 1E314L; + Agg d7 = {e315 - 5 * e314 + e305 - 5 * e314}; // OK + + Agg ce1 = { Convert(1e300) }; // expected-warning {{constant expression evaluates to 1.000000e+300 which cannot be narrowed to type 'float'}} expected-note {{override}} + Agg ce2 = { ConvertVar() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'long double' to 'double'}} expected-note {{override}} +} + +// * from an integer type or unscoped enumeration type to a floating-point type, +// except where the source is a constant expression and the actual value after +// conversion will fit into the target type and will produce the original +// value when converted back to the original type, or +void int_to_float() { + // Not a constant expression. + char c = 1; + + // Variables. Yes, even though all char's will fit into any floating type. + Agg f1 = {c}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg f2 = {c}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg f3 = {c}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + + // Constants. + Agg f4 = {12345678}; // OK (exactly fits in a float) + Agg f5 = {123456789}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + + Agg ce1 = { Convert(123456789) }; // expected-warning {{constant expression evaluates to 123456789 which cannot be narrowed to type 'float'}} expected-note {{override}} + Agg ce2 = { ConvertVar() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'long long' to 'double'}} expected-note {{override}} +} + +// * from an integer type or unscoped enumeration type to an integer type that +// cannot represent all the values of the original type, except where the +// source is a constant expression and the actual value after conversion will +// fit into the target type and will produce the original value when converted +// back to the original type. +void shrink_int() { + // Not a constant expression. + short s = 1; + unsigned short us = 1; + Agg c1 = {s}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg s1 = {s}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg s2 = {us}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + + // "that cannot represent all the values of the original type" means that the + // validity of the program depends on the relative sizes of integral types. + // This test compiles with -m64, so sizeof(int) i1 = {l1}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + long long ll = 1; + Agg l2 = {ll}; // OK + + // Constants. + Agg c2 = {127}; // OK + Agg c3 = {300}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} + + Agg i2 = {0x7FFFFFFFU}; // OK + Agg i3 = {0x80000000U}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg i4 = {-0x80000000L}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + + // Bool is also an integer type, but conversions to it are a different AST + // node. + Agg b1 = {0}; // OK + Agg b2 = {1}; // OK + Agg b3 = {-1}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + + // Conversions from pointers to booleans aren't narrowing conversions. + Agg b = {&b1}; // OK + + Agg ce1 = { Convert(100000) }; // expected-warning {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{override}} expected-warning {{changes value from 100000 to -31072}} + Agg ce2 = { ConvertVar() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{override}} +} + +// Be sure that type- and value-dependent expressions in templates get the warning +// too. + +template +void maybe_shrink_int(T t) { + Agg s1 = {t}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg s2 = {I}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} + Agg t2 = {700}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} +} + +void test_template() { + maybe_shrink_int<15>((int)3); // expected-note {{in instantiation}} + maybe_shrink_int<70000>((char)3); // expected-note {{in instantiation}} +} + + +// We don't want qualifiers on the types in the diagnostic. + +void test_qualifiers(int i) { + const int j = i; + struct {const unsigned char c;} c1 = {j}; // expected-warning {{from type 'int' to 'unsigned char' in}} expected-note {{override}} + // Template arguments make it harder to avoid printing qualifiers: + Agg c2 = {j}; // expected-warning {{from type 'int' to 'const unsigned char' in}} expected-note {{override}} +} + +// Make sure we still get the right SFINAE behavior. +template struct Value { }; + +template +int &check_narrowed(Value); + +template +float &check_narrowed(...); + +void test_narrowed(Value vi, Value vd) { + int &ir = check_narrowed(vd); + float &fr = check_narrowed(vi); +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/basic.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/basic.cpp new file mode 100644 index 0000000..885d11b --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/basic.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// PR5787 +class C { + public: + ~C() {} +}; + +template +class E { + public: + E& Foo(const C&); + E& Bar() { return Foo(C()); } +}; + +void Test() { + E e; + e.Bar(); +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp new file mode 100644 index 0000000..20c059e --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +int g(int); +void f() { + int i; + int& r = i; + r = 1; + int* p = &r; + int &rr=r; + int (&rg)(int) = g; + rg(i); + int a[3]; + int (&ra)[3] = a; + ra[1] = i; +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp new file mode 100644 index 0000000..47e215a --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +int& r1; // expected-error{{declaration of reference variable 'r1' requires an initializer}} +extern int& r2; diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp new file mode 100644 index 0000000..adbdff6 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp @@ -0,0 +1,194 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -pedantic %s + +// Test the c++0x-specific reference initialization rules, e.g., the +// rules for rvalue references. +template T prvalue(); +template T&& xvalue(); +template T& lvalue(); + +struct Base { }; +struct Derived : Base { }; + +struct HasArray { + int array[5]; +}; + +int f(int); + +template +struct ConvertsTo { + operator T(); // expected-note 2{{candidate function}} +}; + +void test_rvalue_refs() { + // If the initializer expression... + // - is an xvalue, class prvalue, array prvalue or function lvalue + // and "cv1 T1" is reference-compatible with "cv2 T2", or + + // xvalue case + Base&& base0 = xvalue(); + Base&& base1 = xvalue(); + int&& int0 = xvalue(); + + // class prvalue case + Base&& base2 = prvalue(); + Base&& base3 = prvalue(); + + // array prvalue case + int (&&array0)[5] = HasArray().array; + + // function lvalue case + int (&&function0)(int) = f; + + // - has a class type (i.e., T2 is a class type), where T1 is not + // reference-related to T2, and can be implicitly converted to + // an xvalue, class prvalue, or function lvalue of type "cv3 + // T3", where "cv1 T1" is reference-compatible with "cv3 T3", + + // xvalue + Base&& base4 = ConvertsTo(); + Base&& base5 = ConvertsTo(); + int && int1 = ConvertsTo(); + + // class prvalue + Base&& base6 = ConvertsTo(); + Base&& base7 = ConvertsTo(); + + // function lvalue + int (&&function1)(int) = ConvertsTo(); + + // In the second case, if the reference is an rvalue reference and + // the second standard conversion sequence of the user-defined + // conversion sequence includes an lvalue-to-rvalue conversion, the + // program is ill-formed. + int &&int2 = ConvertsTo(); // expected-error{{no viable conversion from 'ConvertsTo' to 'int'}} + int &&int3 = ConvertsTo(); // expected-error{{no viable conversion from 'ConvertsTo' to 'int'}} +} + +class NonCopyable { + NonCopyable(const NonCopyable&); +}; + +class NonCopyableDerived : public NonCopyable { + NonCopyableDerived(const NonCopyableDerived&); +}; + +// Make sure we get direct bindings with no copies. +void test_direct_binding() { + NonCopyable &&nc0 = prvalue(); + NonCopyable &&nc1 = prvalue(); + NonCopyable &&nc2 = xvalue(); + NonCopyable &&nc3 = xvalue(); + const NonCopyable &nc4 = prvalue(); + const NonCopyable &nc5 = prvalue(); + const NonCopyable &nc6 = xvalue(); + const NonCopyable &nc7 = xvalue(); + NonCopyable &&nc8 = ConvertsTo(); + NonCopyable &&nc9 = ConvertsTo(); + const NonCopyable &nc10 = ConvertsTo(); + const NonCopyable &nc11 = ConvertsTo(); +} + +namespace std_example_1 { + double d = 2.0; + double& rd = d; + const double& rcd = d; + struct A { }; + struct B : A { + operator int&(); + } b; + A& ra = b; + const A& rca = b; + int& ir = B(); +} + +namespace std_example_2 { + double& rd2 = 2.0; // expected-error{{non-const lvalue reference to type 'double' cannot bind to a temporary of type 'double'}} + int i = 2; + double& rd3 = i; // expected-error{{non-const lvalue reference to type 'double' cannot bind to a value of unrelated type 'int'}} + struct A { }; + struct B : A { } b; + extern B f(); + const A& rca = f(); + A&& rra = f(); + struct X { + operator B(); // expected-note{{candidate function}} + operator int&(); // expected-note{{candidate function}} + } x; + const A& r = x; + int&& rri = static_cast(i); + B&& rrb = x; + int&& rri2 = X(); // expected-error{{no viable conversion from 'std_example_2::X' to 'int'}} + + const double& rcd2 = 2; + double&& rrd = 2; + const volatile int cvi = 1; + const int& r2 = cvi; // expected-error{{binding of reference to type 'const int' to a value of type 'const volatile int' drops qualifiers}} + + double d; + double&& rrd2 = d; // expected-error{{rvalue reference to type 'double' cannot bind to lvalue of type 'double'}} + double&& rrd3 = i; +} + +namespace argument_passing { + void base_rvalue_ref(Base&&); + void int_rvalue_ref(int&&); // expected-note{{candidate function not viable: no known conversion from 'ConvertsTo' to 'int &&' for 1st argument}} \ + // expected-note{{candidate function not viable: no known conversion from 'ConvertsTo' to 'int &&' for 1st argument}} + + void array_rvalue_ref(int (&&)[5]); + void function_rvalue_ref(int (&&)(int)); + + void test() { + base_rvalue_ref(xvalue()); + base_rvalue_ref(xvalue()); + int_rvalue_ref(xvalue()); + + base_rvalue_ref(prvalue()); + base_rvalue_ref(prvalue()); + + array_rvalue_ref(HasArray().array); + + function_rvalue_ref(f); + + base_rvalue_ref(ConvertsTo()); + base_rvalue_ref(ConvertsTo()); + int_rvalue_ref(ConvertsTo()); + + base_rvalue_ref(ConvertsTo()); + base_rvalue_ref(ConvertsTo()); + + function_rvalue_ref(ConvertsTo()); + + int_rvalue_ref(ConvertsTo()); // expected-error{{no matching function for call to 'int_rvalue_ref'}} + int_rvalue_ref(ConvertsTo()); // expected-error{{no matching function for call to 'int_rvalue_ref'}} + } + +} + +namespace pr10644 { + struct string { + string(const char* __s); + }; + class map { + int& operator[](const string& __k); + public: + int& operator[](const string&& __k); + }; + void foo() { + static map key_map; + key_map["line"]; + } +} + +namespace PR11003 { + class Value { + }; + struct MoveRef { + operator Value &() const ; + }; + MoveRef Move(int); + void growTo() { + Value x = Move(0); + Value y(Move(0)); + } +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp new file mode 100644 index 0000000..d58a129 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp @@ -0,0 +1,77 @@ +// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-option -verify %s + +// C++03 requires that we check for a copy constructor when binding a +// reference to a temporary, since we are allowed to make a copy, Even +// though we don't actually make that copy, make sure that we diagnose +// cases where that copy constructor is somehow unavailable. As an +// extension, this is only a warning. + +struct X1 { + X1(); + explicit X1(const X1&); +}; + +struct X2 { + X2(); + +private: + X2(const X2&); // expected-note{{declared private here}} +}; + +struct X3 { + X3(); + +private: + X3(X3&); // expected-note{{candidate constructor not viable: no known conversion from 'X3' to 'X3 &' for 1st argument}} +}; + +// Check for instantiation of default arguments +template +T get_value_badly() { + double *dp = 0; + // The extension doesn't extend far enough to turn this error into a warning. + T *tp = dp; // expected-error{{cannot initialize a variable of type 'int *' with an lvalue of type 'double *'}} + return T(); +} + +template +struct X4 { + X4(); + X4(const X4&, T = get_value_badly()); // expected-note{{in instantiation of}} +}; + +// Check for "dangerous" default arguments that could cause recursion. +struct X5 { + X5(); + X5(const X5&, const X5& = X5()); // expected-warning{{no viable constructor copying parameter of type 'X5'}} +}; + +void g1(const X1&); +void g2(const X2&); +void g3(const X3&); +void g4(const X4&); +void g5(const X5&); + +void test() { + g1(X1()); + g2(X2()); // expected-warning{{C++98 requires an accessible copy constructor for class 'X2' when binding a reference to a temporary; was private}} + g3(X3()); // expected-warning{{no viable constructor copying parameter of type 'X3'}} + g4(X4()); + g5(X5()); // Generates a warning in the default argument. +} + +// Check that unavailable copy constructors still cause SFINAE failures. +template struct int_c { }; + +template T f(const T&); + +// Would be ambiguous with the next g(), except the instantiation failure in +// sizeof() prevents that. +template +int &g(int_c * = 0); + +template float &g(); + +void h() { + float &fp2 = g(); // Not ambiguous. +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx0x-no-extra-copy.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx0x-no-extra-copy.cpp new file mode 100644 index 0000000..27eb6d1 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx0x-no-extra-copy.cpp @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +// C++03 requires that we check for a copy constructor when binding a +// reference to a reference-compatible rvalue, since we are allowed to +// make a copy. C++0x does not permit the copy, so ensure that we +// don't diagnose cases where the copy constructor is unavailable. + +struct X1 { + X1(); + explicit X1(const X1&); +}; + +struct X2 { + X2(); + +private: + X2(const X2&); +}; + +struct X3 { + X3(); + +private: + X3(X3&); +}; + +template +T get_value_badly() { + double *dp = 0; + T *tp = dp; + return T(); +} + +template +struct X4 { + X4(); + X4(const X4&, T = get_value_badly()); +}; + +void g1(const X1&); +void g2(const X2&); +void g3(const X3&); +void g4(const X4&); + +void test() { + g1(X1()); + g2(X2()); + g3(X3()); + g4(X4()); +} + +// Check that unavailable copy constructors do not cause SFINAE failures. +template struct int_c { }; + +template T f(const T&); + +template +int &g(int_c * = 0); // expected-note{{candidate function [with T = X3]}} + +template float &g(); // expected-note{{candidate function [with T = X3]}} + +void h() { + float &fp = g(); // expected-error{{call to 'g' is ambiguous}} +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp new file mode 100644 index 0000000..08d9639 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -ast-dump %s 2>&1 | FileCheck %s + +// CHECK: example0 +void example0() { + double d = 2.0; + // CHECK: double &rd = + // CHECK-NEXT: DeclRefExpr + double &rd = d; + // CHECK: const double &rcd = + // CHECK-NEXT: ImplicitCastExpr{{.*}}'const double' lvalue + const double &rcd = d; +} + +struct A { }; +struct B : A { } b; + +// CHECK: example1 +void example1() { + // CHECK: A &ra = + // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue + A &ra = b; + // CHECK: const A &rca = + // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue + // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue + const A& rca = b; +} + +extern B f(); + +struct X { + operator B(); +} x; + +// CHECK: example2 +void example2() { + // CHECK: const A &rca = + // CHECK: ImplicitCastExpr{{.*}}'const struct A' + // CHECK: ImplicitCastExpr{{.*}}'struct A' + // CHECK: CallExpr{{.*}}B + const A &rca = f(); + // CHECK: const A &r = + // CHECK: ImplicitCastExpr{{.*}}'const struct A' + // CHECK: ImplicitCastExpr{{.*}}'struct A' + // CHECK: CXXMemberCallExpr{{.*}}'struct B' + const A& r = x; +} + +// CHECK: example3 +void example3() { + // CHECK: const double &rcd2 = + // CHECK: ImplicitCastExpr{{.*}} + const double& rcd2 = 2; +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp new file mode 100644 index 0000000..fee5f96 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp @@ -0,0 +1,135 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct Base { }; +struct Derived : Base { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}} +struct Unrelated { }; +struct Derived2 : Base { }; +struct Diamond : Derived, Derived2 { }; + +struct ConvertibleToBaseRef { + operator Base&() const; +}; + +struct ConvertibleToDerivedRef { + operator Derived&() const; +}; + +struct ConvertibleToBothDerivedRef { + operator Derived&(); // expected-note{{candidate function}} + operator Derived2&(); // expected-note{{candidate function}} +}; + +struct ConvertibleToIntRef { + operator int&(); +}; + +struct ConvertibleToBase { + operator Base() const; +}; + +struct ConvertibleToDerived { + operator Derived() const; +}; + +struct ConvertibleToBothDerived { + operator Derived(); // expected-note{{candidate function}} + operator Derived2(); // expected-note{{candidate function}} +}; + +struct ConvertibleToInt { + operator int(); +}; + +template T create(); + +// First bullet: lvalue references binding to lvalues (the simple cases). +void bind_lvalue_to_lvalue(Base b, Derived d, + const Base bc, const Derived dc, + Diamond diamond, + int i) { + // Reference-compatible + Base &br1 = b; + Base &br2 = d; + Derived &dr1 = d; + Derived &dr2 = b; // expected-error{{non-const lvalue reference to type 'Derived' cannot bind to a value of unrelated type 'Base'}} + Base &br3 = bc; // expected-error{{drops qualifiers}} + Base &br4 = dc; // expected-error{{drops qualifiers}} + Base &br5 = diamond; // expected-error{{ambiguous conversion from derived class 'Diamond' to base class 'Base':}} + int &ir = i; + long &lr = i; // expected-error{{non-const lvalue reference to type 'long' cannot bind to a value of unrelated type 'int'}} +} + +void bind_lvalue_quals(volatile Base b, volatile Derived d, + volatile const Base bvc, volatile const Derived dvc, + volatile const int ivc) { + volatile Base &bvr1 = b; + volatile Base &bvr2 = d; + volatile Base &bvr3 = bvc; // expected-error{{binding of reference to type 'volatile Base' to a value of type 'const volatile Base' drops qualifiers}} + volatile Base &bvr4 = dvc; // expected-error{{binding of reference to type 'volatile Base' to a value of type 'const volatile Derived' drops qualifiers}} + + volatile int &ir = ivc; // expected-error{{binding of reference to type 'volatile int' to a value of type 'const volatile int' drops qualifiers}} + + const volatile Base &bcvr1 = b; + const volatile Base &bcvr2 = d; +} + +void bind_lvalue_to_rvalue() { + Base &br1 = Base(); // expected-error{{non-const lvalue reference to type 'Base' cannot bind to a temporary of type 'Base'}} + Base &br2 = Derived(); // expected-error{{non-const lvalue reference to type 'Base' cannot bind to a temporary of type 'Derived'}} + const volatile Base &br3 = Base(); // expected-error{{volatile lvalue reference to type 'const volatile Base' cannot bind to a temporary of type 'Base'}} + const volatile Base &br4 = Derived(); // expected-error{{volatile lvalue reference to type 'const volatile Base' cannot bind to a temporary of type 'Derived'}} + + int &ir = 17; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}} +} + +void bind_lvalue_to_unrelated(Unrelated ur) { + Base &br1 = ur; // expected-error{{non-const lvalue reference to type 'Base' cannot bind to a value of unrelated type 'Unrelated'}} + const volatile Base &br2 = ur; // expected-error{{volatile lvalue reference to type 'const volatile Base' cannot bind to a value of unrelated type 'Unrelated'}} +} + +void bind_lvalue_to_conv_lvalue() { + // Not reference-related, but convertible + Base &nbr1 = ConvertibleToBaseRef(); + Base &nbr2 = ConvertibleToDerivedRef(); + Derived &ndr1 = ConvertibleToDerivedRef(); + int &ir = ConvertibleToIntRef(); +} + +void bind_lvalue_to_conv_lvalue_ambig(ConvertibleToBothDerivedRef both) { + Derived &dr1 = both; + Base &br1 = both; // expected-error{{reference initialization of type 'Base &' with initializer of type 'ConvertibleToBothDerivedRef' is ambiguous}} +} + +struct IntBitfield { + int i : 17; // expected-note{{bit-field is declared here}} +}; + +void test_bitfield(IntBitfield ib) { + int & ir1 = (ib.i); // expected-error{{non-const reference cannot bind to bit-field 'i'}} +} + +// Second bullet: const lvalue reference binding to an rvalue with +// similar type (both of which are class types). +void bind_const_lvalue_to_rvalue() { + const Base &br1 = create(); + const Base &br2 = create(); + const Derived &dr1 = create(); // expected-error{{no viable conversion}} + + const Base &br3 = create(); + const Base &br4 = create(); + + const Base &br5 = create(); // expected-error{{binding of reference to type 'const Base' to a value of type 'const volatile Base' drops qualifiers}} + const Base &br6 = create(); // expected-error{{binding of reference to type 'const Base' to a value of type 'const volatile Derived' drops qualifiers}} + + const int &ir = create(); +} + +// Second bullet: const lvalue reference binds to the result of a conversion. +void bind_const_lvalue_to_class_conv_temporary() { + const Base &br1 = ConvertibleToBase(); + const Base &br2 = ConvertibleToDerived(); +} +void bind_lvalue_to_conv_rvalue_ambig(ConvertibleToBothDerived both) { + const Derived &dr1 = both; + const Base &br1 = both; // expected-error{{reference initialization of type 'const Base &' with initializer of type 'ConvertibleToBothDerived' is ambiguous}} +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp new file mode 100644 index 0000000..51d61a5 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace PR5909 { + struct Foo { + int x : 20; + }; + + bool Test(const int& foo); + + const Foo f = { 0 }; // It compiles without the 'const'. + bool z = Test(f.x); +} + +namespace PR6264 { + typedef int (&T)[3]; + struct S + { + operator T (); + }; + void f() + { + T bar = S(); + } +} + +namespace PR6066 { + struct B { }; + struct A : B { + operator B*(); + operator B&(); // expected-warning{{conversion function converting 'PR6066::A' to its base class 'PR6066::B' will never be used}} + }; + + void f(B&); // no rvalues accepted + void f(B*); + + int g() { + f(A()); // calls f(B*) + return 0; + } +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.string/p1.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.string/p1.cpp new file mode 100644 index 0000000..3631af1 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.string/p1.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +char x1[]("hello"); +extern char x1[6]; + +char x2[] = "hello"; +extern char x2[6]; + +char x3[] = { "hello" }; +extern char x3[6]; + +wchar_t x4[](L"hello"); +extern wchar_t x4[6]; + +wchar_t x5[] = L"hello"; +extern wchar_t x5[6]; + +wchar_t x6[] = { L"hello" }; +extern wchar_t x6[6]; diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.string/p2.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.string/p2.cpp new file mode 100644 index 0000000..3d67fcc --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.string/p2.cpp @@ -0,0 +1,2 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +char test1[1]="f"; // expected-error {{initializer-string for char array is too long}} diff --git a/clang/test/CXX/dcl.decl/dcl.init/p14-0x.cpp b/clang/test/CXX/dcl.decl/dcl.init/p14-0x.cpp new file mode 100644 index 0000000..419f2bf --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/p14-0x.cpp @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +struct NoDefault { + NoDefault() = delete; // expected-note {{here}} + NoDefault(int); +}; +struct Explicit { // expected-note 2 {{candidate}} expected-note {{here}} + explicit Explicit(int); +}; +struct NoCopy { + NoCopy(); + NoCopy(const NoCopy &) = delete; // expected-note {{here}} +}; +struct NoMove { + NoMove(); + NoMove(NoMove &&) = delete; // expected-note {{here}} +}; +class Private { + Private(int); // expected-note {{here}} +public: + Private(); +}; +class Friend { + friend class S; + Friend(int); +}; + + +class S { + NoDefault nd1; + NoDefault nd2 = 42; + Explicit e1; // expected-note {{here}} + Explicit e2 = 42; // expected-error {{no viable conversion}} + NoCopy nc = NoCopy(); // expected-error {{call to deleted}} + NoMove nm = NoMove(); // expected-error {{call to deleted}} + Private p = 42; // expected-error {{private constructor}} + Friend f = 42; + + S() {} // expected-error {{call to deleted constructor of 'NoDefault'}} \ + expected-error {{must explicitly initialize the member 'e1' which does not have a default constructor}} + S(int) : nd1(42), e1(42) {} +}; + +// FIXME: test the other forms which use copy-initialization diff --git a/clang/test/CXX/dcl.decl/dcl.init/p5.cpp b/clang/test/CXX/dcl.decl/dcl.init/p5.cpp new file mode 100644 index 0000000..b50e8d7 --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/p5.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// FIXME: Very incomplete! + +// A program that calls for default-initialization or value-initialization of +// an entity of reference type is illformed. If T is a cv-qualified type, the +// cv-unqualified version of T is used for these definitions of +// zero-initialization, default-initialization, and value-initialization. +// +// FIXME: The diagnostics for these errors are terrible because they fall out +// of the AST representation rather than being explicitly issued during the +// respective initialization forms. +struct S { // expected-error {{implicit default constructor for 'S' must explicitly initialize the reference member}} \ + // expected-note {{candidate constructor (the implicit copy constructor) not viable}} + int& x; // expected-note {{declared here}} +}; +S s; // expected-note {{implicit default constructor for 'S' first required here}} +S f() { + return S(); // expected-error {{no matching constructor for initialization of 'S'}} +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/p6.cpp b/clang/test/CXX/dcl.decl/dcl.init/p6.cpp new file mode 100644 index 0000000..514fd0c --- /dev/null +++ b/clang/test/CXX/dcl.decl/dcl.init/p6.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// FIXME: Very incomplete! + +// If a program calls for the default initialization of an object of a +// const-qualified type T, T shall be a class type with a +// user-provided default constructor. +struct MakeNonPOD { MakeNonPOD(); }; +struct NoUserDefault : public MakeNonPOD { }; +struct HasUserDefault { HasUserDefault(); }; + +void test_const_default_init() { + const NoUserDefault x1; // expected-error{{default initialization of an object of const type 'const NoUserDefault' requires a user-provided default constructor}} + const HasUserDefault x2; + const int x3; // expected-error{{default initialization of an object of const type 'const int'}} +} + +// rdar://8501008 +struct s0 {}; +struct s1 { static const s0 foo; }; +const struct s0 s1::foo; // expected-error{{default initialization of an object of const type 'const struct s0' requires a user-provided default constructor}} + +template +struct s2 { + static const s0 foo; +}; + +template<> const struct s0 s2::foo; // okay -- cgit v1.2.3