[cfe-commits] r138239 - in /cfe/trunk: lib/AST/ExprConstant.cpp test/SemaCXX/references.cpp

Chandler Carruth chandlerc at gmail.com
Mon Aug 22 10:24:56 PDT 2011


Author: chandlerc
Date: Mon Aug 22 12:24:56 2011
New Revision: 138239

URL: http://llvm.org/viewvc/llvm-project?rev=138239&view=rev
Log:
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.

Modified:
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/test/SemaCXX/references.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=138239&r1=138238&r2=138239&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Mon Aug 22 12:24:56 2011
@@ -447,6 +447,7 @@
 class LValueExprEvaluator
   : public ExprEvaluatorBase<LValueExprEvaluator, bool> {
   LValue &Result;
+  const Decl *PrevDecl;
 
   bool Success(const Expr *E) {
     Result.Base = E;
@@ -456,7 +457,7 @@
 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 @@
       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);

Modified: cfe/trunk/test/SemaCXX/references.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/references.cpp?rev=138239&r1=138238&r2=138239&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/references.cpp (original)
+++ cfe/trunk/test/SemaCXX/references.cpp Mon Aug 22 12:24:56 2011
@@ -134,3 +134,6 @@
 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;





More information about the cfe-commits mailing list