aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaDecl.cpp3
-rw-r--r--test/SemaCXX/constant-expression-cxx11.cpp27
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}}
+}