aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-08-22 17:24:56 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-08-22 17:24:56 +0000
commit0124839d7fb3d846795190ba2ccf3951f27784fe (patch)
tree7478b216ba45fdd2962dcfc0ef5b8c935b50b137
parent80f775359357f90f34b6adb8104506f13a816a67 (diff)
Fix a crash-on-valid that has been here for a very long time:
const int &x = x; This crashed by inifinetly recursing within the lvalue evaluation routine. I've added a (somewhat) braindead way of preventing this recursion. If folks have better suggestions for how to avoid it I'm all ears. That said, we have some work to do. This doesn't trigger a single warning for uninitialized, self-initialized or otherwise completely wrong code. In some senses, the crash was almost better. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138239 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AST/ExprConstant.cpp11
-rw-r--r--test/SemaCXX/references.cpp3
2 files changed, 12 insertions, 2 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index fdcff0a4da..2cd85a104a 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -447,6 +447,7 @@ namespace {
class LValueExprEvaluator
: public ExprEvaluatorBase<LValueExprEvaluator, bool> {
LValue &Result;
+ const Decl *PrevDecl;
bool Success(const Expr *E) {
Result.Base = E;
@@ -456,7 +457,7 @@ class LValueExprEvaluator
public:
LValueExprEvaluator(EvalInfo &info, LValue &Result) :
- ExprEvaluatorBaseTy(info), Result(Result) {}
+ ExprEvaluatorBaseTy(info), Result(Result), PrevDecl(0) {}
bool Success(const APValue &V, const Expr *E) {
Result.setFrom(V);
@@ -501,10 +502,16 @@ bool LValueExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) {
return Success(E);
// Reference parameters can refer to anything even if they have an
// "initializer" in the form of a default argument.
- if (!isa<ParmVarDecl>(VD))
+ if (!isa<ParmVarDecl>(VD)) {
// FIXME: Check whether VD might be overridden!
+
+ // Check for recursive initializers of references.
+ if (PrevDecl == VD)
+ return Error(E);
+ PrevDecl = VD;
if (const Expr *Init = VD->getAnyInitializer())
return Visit(Init);
+ }
}
return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
diff --git a/test/SemaCXX/references.cpp b/test/SemaCXX/references.cpp
index ab44e78453..70d3799a0e 100644
--- a/test/SemaCXX/references.cpp
+++ b/test/SemaCXX/references.cpp
@@ -134,3 +134,6 @@ namespace PR7149 {
namespace PR8608 {
bool& f(unsigned char& c) { return (bool&)c; }
}
+
+// The following crashed trying to recursively evaluate the LValue.
+const int &do_not_crash = do_not_crash;