зеркало из https://github.com/microsoft/clang-1.git
Move TLS check from LValueExprEvaluator::VisitVarDecl to
CheckLValueConstantExpression. Richard pointed out that using the address of a TLS variable is ok in a core C++11 constant expression, as long as it isn't part of the eventual result of constant expression evaluation. Having the check in CheckLValueConstantExpression accomplishes this. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162850 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
a414a2f3ae
Коммит
48def65d1c
|
@ -987,6 +987,14 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
|
|||
LVal.getLValueCallIndex() == 0) &&
|
||||
"have call index for global lvalue");
|
||||
|
||||
// Check if this is a thread-local variable.
|
||||
if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
|
||||
if (const VarDecl *Var = dyn_cast<const VarDecl>(VD)) {
|
||||
if (Var->isThreadSpecified())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow address constant expressions to be past-the-end pointers. This is
|
||||
// an extension: the standard requires them to point to an object.
|
||||
if (!IsReferenceType)
|
||||
|
@ -2832,8 +2840,6 @@ bool LValueExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) {
|
|||
}
|
||||
|
||||
bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {
|
||||
if (VD->isThreadSpecified())
|
||||
return Error(E);
|
||||
if (!VD->getType()->isReferenceType()) {
|
||||
if (isa<ParmVarDecl>(VD)) {
|
||||
Result.set(VD, Info.CurrentCall->Index);
|
||||
|
|
|
@ -1377,7 +1377,16 @@ namespace ConditionalLValToRVal {
|
|||
|
||||
namespace TLS {
|
||||
__thread int n;
|
||||
constexpr int &f() { // expected-error {{constexpr function never produces a constant expression}}
|
||||
return n; // expected-note {{subexpression not valid in a constant expression}}
|
||||
}
|
||||
int m;
|
||||
|
||||
constexpr bool b = &n == &n;
|
||||
|
||||
constexpr int *p = &n; // expected-error{{constexpr variable 'p' must be initialized by a constant expression}}
|
||||
|
||||
constexpr int *f() { return &n; }
|
||||
constexpr int *q = f(); // expected-error{{constexpr variable 'q' must be initialized by a constant expression}}
|
||||
constexpr bool c = f() == f();
|
||||
|
||||
constexpr int *g() { return &m; }
|
||||
constexpr int *r = g();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче