forked from OSchip/llvm-project
constexpr: Fix implementation of DR1311: check for volatile qualifiers in
lvalue-to-rvalue conversions on the source type of the conversion, not the target type (which has them removed for non-class types). llvm-svn: 149796
This commit is contained in:
parent
4daa67483d
commit
c82fae6070
|
@ -1560,7 +1560,8 @@ static bool AreElementsOfSameArray(QualType ObjType,
|
|||
/// \param Info - Information about the ongoing evaluation.
|
||||
/// \param Conv - The expression for which we are performing the conversion.
|
||||
/// Used for diagnostics.
|
||||
/// \param Type - The type we expect this conversion to produce.
|
||||
/// \param Type - The type we expect this conversion to produce, before
|
||||
/// stripping cv-qualifiers in the case of a non-clas type.
|
||||
/// \param LVal - The glvalue on which we are attempting to perform this action.
|
||||
/// \param RVal - The produced value will be placed here.
|
||||
static bool HandleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv,
|
||||
|
@ -2536,7 +2537,9 @@ public:
|
|||
if (!EvaluateLValue(E->getSubExpr(), LVal, Info))
|
||||
return false;
|
||||
CCValue RVal;
|
||||
if (!HandleLValueToRValueConversion(Info, E, E->getType(), LVal, RVal))
|
||||
// Note, we use the subexpression's type in order to retain cv-qualifiers.
|
||||
if (!HandleLValueToRValueConversion(Info, E, E->getSubExpr()->getType(),
|
||||
LVal, RVal))
|
||||
return false;
|
||||
return DerivedSuccess(RVal, E);
|
||||
}
|
||||
|
|
|
@ -268,14 +268,12 @@ namespace LValueToRValue {
|
|||
// non-volatile const object with a preceding initialization, initialized
|
||||
// with a constant expression [Note: a string literal (2.14.5 [lex.string])
|
||||
// corresponds to an array of such objects. -end note], or
|
||||
volatile const int vi = 1; // expected-note 2{{here}}
|
||||
volatile const int vi = 1; // expected-note {{here}}
|
||||
const int ci = 1;
|
||||
volatile const int &vrci = ci;
|
||||
static_assert(vi, ""); // expected-error {{constant expression}} expected-note {{read of volatile object 'vi'}}
|
||||
static_assert(vi, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}}
|
||||
static_assert(const_cast<int&>(vi), ""); // expected-error {{constant expression}} expected-note {{read of volatile object 'vi'}}
|
||||
static_assert(vrci, ""); // ok, vrci is converted to a prvalue before
|
||||
// evaluation and loses its volatility in the
|
||||
// conversion.
|
||||
static_assert(vrci, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}}
|
||||
|
||||
// - a non-volatile glvalue of literal type that refers to a non-volatile
|
||||
// object defined with constexpr, or that refers to a sub-object of such an
|
||||
|
@ -287,13 +285,14 @@ namespace LValueToRValue {
|
|||
volatile int v; // expected-note {{here}}
|
||||
};
|
||||
constexpr S s;
|
||||
constexpr volatile S vs; // expected-note 2{{here}}
|
||||
constexpr volatile S vs; // expected-note {{here}}
|
||||
constexpr const volatile S &vrs = s;
|
||||
static_assert(s.i, "");
|
||||
static_assert(s.v, ""); // expected-error {{constant expression}} expected-note {{read of volatile member 'v'}}
|
||||
static_assert(vs.i, ""); // expected-error {{constant expression}} expected-note {{read of volatile object 'vs'}}
|
||||
static_assert(s.v, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}}
|
||||
static_assert(const_cast<int&>(s.v), ""); // expected-error {{constant expression}} expected-note {{read of volatile member 'v'}}
|
||||
static_assert(vs.i, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}}
|
||||
static_assert(const_cast<int&>(vs.i), ""); // expected-error {{constant expression}} expected-note {{read of volatile object 'vs'}}
|
||||
static_assert(vrs.i, ""); // ok
|
||||
static_assert(vrs.i, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}}
|
||||
|
||||
// - a non-volatile glvalue of literal type that refers to a non-volatile
|
||||
// temporary object whose lifetime has not ended, initialized with a
|
||||
|
|
|
@ -1011,17 +1011,23 @@ volatile constexpr int n1 = 0; // expected-note {{here}}
|
|||
volatile const int n2 = 0; // expected-note {{here}}
|
||||
int n3 = 37; // expected-note {{declared here}}
|
||||
|
||||
constexpr int m1 = n1; // expected-error {{constant expression}} expected-note {{read of volatile object 'n1'}}
|
||||
constexpr int m2 = n2; // expected-error {{constant expression}} expected-note {{read of volatile object 'n2'}}
|
||||
constexpr int m1 = n1; // expected-error {{constant expression}} expected-note {{read of volatile-qualified type 'const volatile int'}}
|
||||
constexpr int m2 = n2; // expected-error {{constant expression}} expected-note {{read of volatile-qualified type 'const volatile int'}}
|
||||
constexpr int m1b = const_cast<const int&>(n1); // expected-error {{constant expression}} expected-note {{read of volatile object 'n1'}}
|
||||
constexpr int m2b = const_cast<const int&>(n2); // expected-error {{constant expression}} expected-note {{read of volatile object 'n2'}}
|
||||
|
||||
struct T { int n; };
|
||||
const T t = { 42 }; // expected-note {{declared here}}
|
||||
|
||||
constexpr int f(volatile int &&r) {
|
||||
return r; // expected-note {{read of volatile temporary is not allowed in a constant expression}}
|
||||
return r; // expected-note {{read of volatile-qualified type 'volatile int'}}
|
||||
}
|
||||
constexpr int g(volatile int &&r) {
|
||||
return const_cast<int&>(r); // expected-note {{read of volatile temporary is not allowed in a constant expression}}
|
||||
}
|
||||
struct S {
|
||||
int k : f(0); // expected-error {{constant expression}} expected-note {{temporary created here}} expected-note {{in call to 'f(0)'}}
|
||||
int j : f(0); // expected-error {{constant expression}} expected-note {{in call to 'f(0)'}}
|
||||
int k : g(0); // expected-error {{constant expression}} expected-note {{temporary created here}} expected-note {{in call to 'g(0)'}}
|
||||
int l : n3; // expected-error {{constant expression}} expected-note {{read of non-const variable}}
|
||||
int m : t.n; // expected-error {{constant expression}} expected-note {{read of non-constexpr variable}}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue