teak-llvm/clang/test/SemaCXX/i-c-e-cxx.cpp
Richard Smith ef6c43dc0c Refactor checking of switch conditions and case values.
Check each case value in turn while parsing it, performing the
conversion to the switch type within the context of the expression
itself. This will become necessary in order to properly handle cleanups
for temporaries created as part of the case label (in an upcoming
patch). For now it's just good hygiene.

This necessitates moving the checking for the switch condition itself to
earlier, so that the destination type is available when checking the
case labels.

As a nice side-effect, we get slightly improved diagnostic quality and
error recovery by separating the case expression checking from the case
statement checking and from tracking whether there are discarded case
labels.

llvm-svn: 338056
2018-07-26 18:41:30 +00:00

98 lines
2.5 KiB
C++

// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -std=gnu++98 %s
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -std=gnu++11 %s
// C++-specific tests for integral constant expressions.
const int c = 10;
int ar[c];
struct X0 {
static const int value = static_cast<int>(4.0);
};
void f() {
if (const int value = 17) {
int array[value];
}
}
int a() {
const int t=t; // expected-note {{declared here}}
#if __cplusplus <= 199711L
// expected-note@-2 {{read of object outside its lifetime}}
#endif
switch(1) { // do not warn that 1 is not a case value;
// 't' might have been expected to evalaute to 1
case t:; // expected-note {{initializer of 't' is not a constant expression}}
#if __cplusplus <= 199711L
// expected-error@-2 {{not an integral constant expression}}
#else
// expected-error@-4 {{case value is not a constant expression}}
#endif
}
}
// PR6206: out-of-line definitions are legit
namespace pr6206 {
class Foo {
public:
static const int kBar;
};
const int Foo::kBar = 20;
char Test() {
char str[Foo::kBar];
str[0] = '0';
return str[0];
}
}
// PR6373: default arguments don't count.
void pr6373(const unsigned x = 0) {
unsigned max = 80 / x;
}
// rdar://9204520
namespace rdar9204520 {
struct A {
static const int B = int(0.75 * 1000 * 1000);
#if __cplusplus <= 199711L
// expected-warning@-2 {{not a constant expression; folding it to a constant is a GNU extension}}
#endif
};
int foo() { return A::B; }
}
// PR11040
const int x = 10;
int* y = reinterpret_cast<const char&>(x); // expected-error {{cannot initialize}}
// This isn't an integral constant expression, but make sure it folds anyway.
struct PR8836 { char _; long long a; };
#if __cplusplus <= 199711L
// expected-warning@-2 {{'long long' is a C++11 extension}}
#endif
int PR8836test[(__typeof(sizeof(int)))&reinterpret_cast<const volatile char&>((((PR8836*)0)->a))];
// expected-warning@-1 {{folded to constant array as an extension}}
// expected-note@-2 {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
const int nonconst = 1.0;
#if __cplusplus <= 199711L
// expected-note@-2 {{declared here}}
#endif
int arr[nonconst];
#if __cplusplus <= 199711L
// expected-warning@-2 {{folded to constant array as an extension}}
// expected-note@-3 {{initializer of 'nonconst' is not a constant expression}}
#endif
const int castfloat = static_cast<int>(1.0);
int arr2[castfloat]; // ok