[PATCH] D23493: Fix PR28366: Teach the const-expression evaluator to be more fault tolerant with non-const enclosing local variables, or otherwise fold them if const.
Faisal Vali via cfe-commits
cfe-commits at lists.llvm.org
Sun Aug 14 15:41:44 PDT 2016
faisalv created this revision.
faisalv added reviewers: rsmith, hans.
faisalv added a subscriber: cfe-commits.
faisalv set the repository for this revision to rL LLVM.
Fix the following Bug:
https://llvm.org/bugs/show_bug.cgi?id=28366
This patch teaches the constant expression evaluator to search the frame stack for a local variable (instead of assuming a local variable is on the current frame).
This has the following benefits:
- if the local variable from an enclosing scope was an error during parsing/instantiation - it remains an error (instead of a compiler crash) during constant expression evaluation
- a local variable that is a constant expression from an enclosing scope is now evaluatable
Additionally, fix SemaTemplateInstantiateDecl so that when it instantiates the enable_if attribute it uses the instantiated declaration (instead of the template) when evaluating the condition (so that the instantiated param's decl context is correctly found). This was done to fix the following regression:
template <typename T> T templatedBar(T m) __attribute__((enable_if(m > 0, ""))) { return T(); }
Repository:
rL LLVM
https://reviews.llvm.org/D23493
Files:
lib/AST/ExprConstant.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
test/SemaCXX/constant-expression-cxx11.cpp
Index: test/SemaCXX/constant-expression-cxx11.cpp
===================================================================
--- test/SemaCXX/constant-expression-cxx11.cpp
+++ test/SemaCXX/constant-expression-cxx11.cpp
@@ -2066,3 +2066,33 @@
constexpr Z z(1);
static_assert(z.w == 1 && z.x == 2 && z.y == 3 && z.z == 4, "");
}
+
+
+namespace PR28366 {
+namespace ns1 {
+
+void f(char c) { //expected-note2{{declared here}}
+ struct X {
+ static constexpr char f() { //expected-error{{never produces a constant expression}}
+ return c; //expected-error{{reference to local}} expected-note{{non-const variable}}
+ }
+ };
+ int I = X::f();
+}
+
+void g() {
+ const int c = 'c';
+ static const int d = 'd';
+ struct X {
+ static constexpr int f() {
+ return c + d;
+ }
+ };
+ constexpr int CD = X::f();
+}
+
+
+} // end ns1
+
+} //end ns PR28366
+
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -187,7 +187,7 @@
SmallVector<PartialDiagnosticAt, 8> Diags;
if (A->getCond()->isValueDependent() && !Cond->isValueDependent() &&
- !Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(Tmpl),
+ !Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(New),
Diags)) {
S.Diag(A->getLocation(), diag::err_enable_if_never_constant_expr);
for (int I = 0, N = Diags.size(); I != N; ++I)
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -4788,10 +4788,24 @@
return Error(E);
}
+CallStackFrame *getNearestContainingCallFrame(CallStackFrame *CurFrame,
+ const VarDecl *VD) {
+ if (auto *FD =
+ dyn_cast<FunctionDecl>(VD->getDeclContext()->getRedeclContext())) {
+ FD = FD->getFirstDecl();
+ for (CallStackFrame *It = CurFrame; It; It = It->Caller) {
+ if (It->Callee && FD == It->Callee->getFirstDecl())
+ return It;
+ }
+ }
+ return nullptr;
+}
+
bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {
CallStackFrame *Frame = nullptr;
- if (VD->hasLocalStorage() && Info.CurrentCall->Index > 1)
- Frame = Info.CurrentCall;
+ if (VD->hasLocalStorage() && Info.CurrentCall->Index > 1) {
+ Frame = getNearestContainingCallFrame(Info.CurrentCall, VD);
+ }
if (!VD->getType()->isReferenceType()) {
if (Frame) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D23493.67990.patch
Type: text/x-patch
Size: 2622 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160814/a9e1dd8a/attachment.bin>
More information about the cfe-commits
mailing list