From 2f36dae5c01d46c8c71af594601f125a604226a1 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Sun, 28 Oct 2012 06:18:02 +0000 Subject: [PATCH] When determining whether to try evaluating the initializer of a variable, check whether the initializer is value-dependent rather than whether we are in a dependent context. This allows us to detect some errors sooner, and fixes a crash-on-invalid if a dependent type leaks out to a non-dependent context in error recovery. llvm-svn: 166898 --- clang/lib/Sema/SemaDecl.cpp | 2 +- clang/test/SemaCXX/constant-expression-cxx11.cpp | 9 ++++++++- clang/test/SemaCXX/cxx11-crashes.cpp | 12 ++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 3576190..6eef427 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -7201,7 +7201,7 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { Expr *Init = var->getInit(); bool IsGlobal = var->hasGlobalStorage() && !var->isStaticLocal(); - if (!var->getDeclContext()->isDependentContext() && Init) { + if (Init && !Init->isValueDependent()) { if (IsGlobal && !var->isConstexpr() && getDiagnostics().getDiagnosticLevel(diag::warn_global_constructor, var->getLocation()) diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp index 9ce5b85..9a9746e 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -521,12 +521,19 @@ namespace DependentValues { struct I { int n; typedef I V[10]; }; I::V x, y; -template struct S { +int g(); // expected-note {{here}} +template struct S : T { int k; void f() { I::V &cells = B ? x : y; 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'}} + + constexpr int m = this->g(); // ok, could be constexpr } }; diff --git a/clang/test/SemaCXX/cxx11-crashes.cpp b/clang/test/SemaCXX/cxx11-crashes.cpp index 66b182b..bd51af1 100644 --- a/clang/test/SemaCXX/cxx11-crashes.cpp +++ b/clang/test/SemaCXX/cxx11-crashes.cpp @@ -62,3 +62,15 @@ void foobar() } } + +namespace b6981007 { + struct S {}; // expected-note 3{{candidate}} + void f() { + S s(1, 2, 3); // expected-error {{no matching}} + for (auto x : s) { + // We used to attempt to evaluate the initializer of this variable, + // and crash because it has an undeduced type. + const int &n(x); + } + } +} -- 2.7.4