[cfe-commits] r52120 - in /cfe/trunk: lib/Sema/SemaDecl.cpp test/CodeGen/struct-init.c

Eli Friedman eli.friedman at gmail.com
Sun Jun 8 22:05:08 PDT 2008


Author: efriedma
Date: Mon Jun  9 00:05:07 2008
New Revision: 52120

URL: http://llvm.org/viewvc/llvm-project?rev=52120&view=rev
Log:
Add code to make test/CodeGen/struct-init.c work correctly without the 
pointer cast hack currently in isIntegerConstantExpr 
(in lib/AST/Expr.cpp).  Also removes an odd test that even gcc doesn't accept.

The reason the pointer cast hack is relevant here is that it makes Sema 
end up misinterpreting the relevant expression as a null pointer constant.

The reason for this patch is that I plan to remove the pointer cast hack 
sometime soon because it causes strange issues, especially in its 
current form; see my recent email to cfe-dev
"[PATCH] add constant expression evaluation to the AST and fix PR2413".


Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/CodeGen/struct-init.c

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=52120&r1=52119&r2=52120&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Jun  9 00:05:07 2008
@@ -935,6 +935,97 @@
   }
 }
 
+static const Expr* FindExpressionBaseAddress(const Expr* E);
+
+static const Expr* FindExpressionBaseAddressLValue(const Expr* E) {
+  switch (E->getStmtClass()) {
+  default:
+    return E;
+  case Expr::ParenExprClass: {
+    const ParenExpr* PE = cast<ParenExpr>(E);
+    return FindExpressionBaseAddressLValue(PE->getSubExpr());
+  }
+  case Expr::MemberExprClass: {
+    const MemberExpr *M = cast<MemberExpr>(E);
+    if (M->isArrow())
+      return FindExpressionBaseAddress(M->getBase());
+    return FindExpressionBaseAddressLValue(M->getBase());
+  }
+  case Expr::ArraySubscriptExprClass: {
+    const ArraySubscriptExpr *ASE = cast<ArraySubscriptExpr>(E);
+    return FindExpressionBaseAddress(ASE->getBase());
+  }
+  case Expr::UnaryOperatorClass: {
+    const UnaryOperator *Exp = cast<UnaryOperator>(E);
+
+    if (Exp->getOpcode() == UnaryOperator::Deref)
+      return FindExpressionBaseAddress(Exp->getSubExpr());
+
+    return E;
+  }
+  }
+}
+
+static const Expr* FindExpressionBaseAddress(const Expr* E) {
+  switch (E->getStmtClass()) {
+  default:
+    return E;
+  case Expr::ParenExprClass: {
+    const ParenExpr* PE = cast<ParenExpr>(E);
+    return FindExpressionBaseAddress(PE->getSubExpr());
+  }
+  case Expr::UnaryOperatorClass: {
+    const UnaryOperator *Exp = cast<UnaryOperator>(E);
+
+    // C99 6.6p9
+    if (Exp->getOpcode() == UnaryOperator::AddrOf)
+      return FindExpressionBaseAddressLValue(Exp->getSubExpr());
+
+    if (Exp->getOpcode() == UnaryOperator::Extension)
+      return FindExpressionBaseAddress(Exp->getSubExpr());
+  
+    return E;
+  }
+  case Expr::BinaryOperatorClass: {
+    const BinaryOperator *Exp = cast<BinaryOperator>(E);
+
+    Expr *PExp = Exp->getLHS();
+    Expr *IExp = Exp->getRHS();
+    if (IExp->getType()->isPointerType())
+      std::swap(PExp, IExp);
+
+    return FindExpressionBaseAddress(PExp);
+  }
+  case Expr::ImplicitCastExprClass: {
+    const Expr* SubExpr = cast<ImplicitCastExpr>(E)->getSubExpr();
+
+    // Check for implicit promotion
+    if (SubExpr->getType()->isFunctionType() ||
+        SubExpr->getType()->isArrayType())
+      return FindExpressionBaseAddressLValue(SubExpr);
+
+    // Check for pointer->pointer cast
+    if (SubExpr->getType()->isPointerType())
+      return FindExpressionBaseAddress(SubExpr);
+
+    // We assume that we have an arithmetic expression here;
+    // if we don't, we'll figure it out later
+    return 0;
+  }
+  case Expr::CastExprClass: {
+    const Expr* SubExpr = cast<CastExpr>(E)->getSubExpr();
+
+    // Check for pointer->pointer cast
+    if (SubExpr->getType()->isPointerType())
+      return FindExpressionBaseAddress(SubExpr);
+
+    // We assume that we have an arithmetic expression here;
+    // if we don't, we'll figure it out later
+    return 0;
+  }
+  }
+}
+
 bool Sema::CheckArithmeticConstantExpression(const Expr* Init) {
   switch (Init->getStmtClass()) {
   default:
@@ -1027,6 +1118,20 @@
              CheckArithmeticConstantExpression(Exp->getRHS());
     }
 
+    if (Exp->getLHS()->getType()->isPointerType() &&
+        Exp->getRHS()->getType()->isPointerType()) {
+      const Expr* LHSBase = FindExpressionBaseAddress(Exp->getLHS());
+      const Expr* RHSBase = FindExpressionBaseAddress(Exp->getRHS());
+
+      // Only allow a null (constant integer) base; we could
+      // allow some additional cases if necessary, but this
+      // is sufficient to cover offsetof-like constructs.
+      if (!LHSBase && !RHSBase) {
+        return CheckAddressConstantExpression(Exp->getLHS()) ||
+               CheckAddressConstantExpression(Exp->getRHS());
+      }
+    }
+
     Diag(Init->getExprLoc(),
          diag::err_init_element_not_constant, Init->getSourceRange());
     return true;

Modified: cfe/trunk/test/CodeGen/struct-init.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/struct-init.c?rev=52120&r1=52119&r2=52120&view=diff

==============================================================================
--- cfe/trunk/test/CodeGen/struct-init.c (original)
+++ cfe/trunk/test/CodeGen/struct-init.c Mon Jun  9 00:05:07 2008
@@ -9,5 +9,4 @@
 
 const zend_ini_entry ini_entries[] = {
 	{  ((char*)&((zend_ini_entry*)0)->mh_arg1 - (char*)(void*)0)},
-	{  ((long long*)&a - (long long*)(void*)2)},
 };





More information about the cfe-commits mailing list