diff options
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 3 | ||||
-rw-r--r-- | test/SemaCXX/constant-expression-cxx11.cpp | 27 |
2 files changed, 25 insertions, 5 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 0eb123105b..52ee80f833 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -7200,7 +7200,8 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { Expr *Init = var->getInit(); bool IsGlobal = var->hasGlobalStorage() && !var->isStaticLocal(); - if (Init && !Init->isValueDependent()) { + if (!var->getDeclContext()->isDependentContext() && + Init && !Init->isValueDependent()) { if (IsGlobal && !var->isConstexpr() && getDiagnostics().getDiagnosticLevel(diag::warn_global_constructor, var->getLocation()) diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp index 9a9746ee29..0dd7ffe5a9 100644 --- a/test/SemaCXX/constant-expression-cxx11.cpp +++ b/test/SemaCXX/constant-expression-cxx11.cpp @@ -521,7 +521,7 @@ namespace DependentValues { struct I { int n; typedef I V[10]; }; I::V x, y; -int g(); // expected-note {{here}} +int g(); template<bool B, typename T> struct S : T { int k; void f() { @@ -529,9 +529,8 @@ template<bool B, typename T> struct S : T { I &i = cells[k]; switch (i.n) {} - constexpr int n = g(); // \ - // expected-error {{must be initialized by a constant expression}} \ - // expected-note {{non-constexpr function 'g'}} + // FIXME: We should be able to diagnose this. + constexpr int n = g(); constexpr int m = this->g(); // ok, could be constexpr } @@ -1435,3 +1434,23 @@ namespace TypeId { constexpr auto &y = typeid(g()); // expected-error{{constant expression}} \ // expected-note{{typeid applied to expression of polymorphic type 'TypeId::A' is not allowed in a constant expression}} } + +namespace PR14203 { + struct duration { + constexpr duration() {} + constexpr operator int() const { return 0; } + }; + template<typename T> void f() { + // If we want to evaluate this at the point of the template definition, we + // need to trigger the implicit definition of the move constructor at that + // point. + // FIXME: C++ does not permit us to implicitly define it at the appropriate + // times, since it is only allowed to be implicitly defined when it is + // odr-used. + constexpr duration d = duration(); + } + // FIXME: It's unclear whether this is valid. On the one hand, we're not + // allowed to generate a move constructor. On the other hand, if we did, + // this would be a constant expression. + int n = sizeof(short{duration(duration())}); // expected-error {{non-constant-expression cannot be narrowed}} expected-note {{override}} +} |