[cfe-commits] [PATCH] Handle evaluation and ICE-checking of self-referencing constant integers without crashing

Douglas Gregor dgregor at apple.com
Mon Nov 30 06:14:44 PST 2009


On Nov 27, 2009, at 1:00 PM, Eli Friedman wrote:

> Examples of issues:
> 
> (C or C++):
> int a() { const int t=t; switch(1) { case t:; } }
> 
> (C++)
> extern const int a,b;
> const int a=b,b=a;
> int a() { if (a) return 1; return 0; }
> 
> Doug, since you were the last person to touch this code recently,
> would you mind taking a look?  I somehow get the feeling I'm missing
> something, but I'm not sure what.


This looks fine, although I have a couple of comments.

Index: include/clang/AST/Decl.h
===================================================================
--- include/clang/AST/Decl.h	(revision 89989)
+++ include/clang/AST/Decl.h	(working copy)
@@ -351,10 +351,17 @@
   /// \brief Whether this statement was already evaluated.
   bool WasEvaluated : 1;
 
+  /// \brief Whether this statement is being evaluated.
+  bool IsEvaluating : 1;
+
   /// \brief Whether we already checked whether this statement was an
   /// integral constant expression.
   bool CheckedICE : 1;
 
+  /// \brief Whether we are checking whether this statement is an
+  /// integral constant expression.
+  bool CheckingICE : 1;

Make sure that you add IsValuating(false) and CheckingICE(false) to the default constructor for EvaluatedStmt.

-  /// \brief Note that constant evaluation has computed the given
-  /// value for this variable's initializer.
-  void setEvaluatedValue(ASTContext &C, const APValue &Value) const {
+  EvaluatedStmt *EnsureEvaluatedStmt(ASTContext &C) const {

Since you're changing signatures anyway... you don't actually need to pass an ASTContext into any of the Decl member functions, since you can use getASTContext().

+  /// \brief Note that constant evaluation has computed the given
+  /// value for this variable's initializer.
+  void setEvaluatedValue(ASTContext &C, const APValue &Value) const {
+    EvaluatedStmt *Eval = EnsureEvaluatedStmt(C);
     Eval->WasEvaluated = true;
     Eval->Evaluated = Value;
   }

Also: 

  Eval->IsEvaluating = false;

Thanks, Eli!

	- Doug



More information about the cfe-commits mailing list