aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/AST/ExprConstant.cpp10
-rw-r--r--test/SemaCXX/constant-expression-cxx11.cpp15
2 files changed, 20 insertions, 5 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index ac21b46941..fb0c4d26ea 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -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);
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp
index 984ee1b08b..930e70d4f3 100644
--- a/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/test/SemaCXX/constant-expression-cxx11.cpp
@@ -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();
}