[cfe-commits] r64780 - in /cfe/trunk: lib/CodeGen/CGDecl.cpp lib/CodeGen/CGExprConstant.cpp lib/CodeGen/CodeGenModule.h test/CodeGen/staticinit.c

Daniel Dunbar daniel at zuster.org
Tue Feb 17 10:43:33 PST 2009


Author: ddunbar
Date: Tue Feb 17 12:43:32 2009
New Revision: 64780

URL: http://llvm.org/viewvc/llvm-project?rev=64780&view=rev
Log:
Change EmitConstantExpr to allow failure.

IRgen no longer relies on isConstantInitializer, instead we just try
to emit the constant. If that fails then in C we emit an error
unsupported (this occurs when Sema accepted something that it doesn't
know how to fold, and IRgen doesn't know how to emit) and in C++ we
emit a guarded initializer.

This ends up handling a few more cases, because IRgen was actually
able to emit some of the constants Sema accepts but can't Evaluate().
For example, PR3398.

Modified:
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/test/CodeGen/staticinit.c

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=64780&r1=64779&r2=64780&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Tue Feb 17 12:43:32 2009
@@ -88,12 +88,17 @@
   if ((D.getInit() == 0) || NoInit) {
     Init = llvm::Constant::getNullValue(LTy);
   } else {
-    if (D.getInit()->isConstantInitializer(getContext()))
-      Init = CGM.EmitConstantExpr(D.getInit(), this);
-    else {
-      assert(getContext().getLangOptions().CPlusPlus && 
-             "only C++ supports non-constant static initializers!");
-      return GenerateStaticCXXBlockVarDecl(D);
+    Init = CGM.EmitConstantExpr(D.getInit(), this);
+
+    // If constant emission failed, then this should be a C++ static
+    // initializer.
+    if (!Init) {
+      if (!getContext().getLangOptions().CPlusPlus) {
+        CGM.ErrorUnsupported(D.getInit(), "constant l-value expression");
+        Init = llvm::Constant::getNullValue(LTy);
+      } else {
+        return GenerateStaticCXXBlockVarDecl(D);
+      }
     }
   }
 

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=64780&r1=64779&r2=64780&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Tue Feb 17 12:43:32 2009
@@ -61,7 +61,6 @@
     }
 
     llvm::Constant *C = Visit(E->getSubExpr());
-    
     return EmitConversion(C, E->getSubExpr()->getType(), E->getType());    
   }
 
@@ -90,6 +89,8 @@
     bool RewriteType = false;
     for (; i < NumInitableElts; ++i) {
       llvm::Constant *C = CGM.EmitConstantExpr(ILE->getInit(i), CGF);
+      if (!C)
+        return 0;
       RewriteType |= (C->getType() != ElemTy);
       Elts.push_back(C);
     }
@@ -114,6 +115,9 @@
                                 FieldDecl* Field, Expr* E) {
     // Calculate the value to insert
     llvm::Constant *C = CGM.EmitConstantExpr(E, CGF);
+    if (!C)
+      return;
+
     llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(C);
     if (!CI) {
       CGM.ErrorUnsupported(E, "bitfield initialization");
@@ -198,6 +202,7 @@
       } else {
         unsigned FieldNo = CGM.getTypes().getLLVMFieldNo(*Field);
         llvm::Constant *C = CGM.EmitConstantExpr(ILE->getInit(EltNo), CGF);
+        if (!C) return 0;
         RewriteType |= (C->getType() != Elts[FieldNo]->getType());
         Elts[FieldNo] = C;
       }
@@ -217,6 +222,9 @@
   }
 
   llvm::Constant *EmitUnion(llvm::Constant *C, const llvm::Type *Ty) {
+    if (!C)
+      return 0;
+
     // Build a struct with the union sub-element as the first member,
     // and padded to the appropriate size
     std::vector<llvm::Constant*> Elts;
@@ -289,6 +297,8 @@
     unsigned i = 0;
     for (; i < NumInitableElts; ++i) {
       llvm::Constant *C = CGM.EmitConstantExpr(ILE->getInit(i), CGF);
+      if (!C)
+        return 0;
       Elts.push_back(C);
     }
 
@@ -402,6 +412,9 @@
   
   llvm::Constant *EmitConversion(llvm::Constant *Src, QualType SrcType, 
                                  QualType DstType) {
+    if (!Src)
+      return 0;
+
     SrcType = CGM.getContext().getCanonicalType(SrcType);
     DstType = CGM.getContext().getCanonicalType(DstType);
     if (SrcType == DstType) return Src;
@@ -488,9 +501,12 @@
       // to be the only use of the variable, so we just generate it here.
       CompoundLiteralExpr *CLE = cast<CompoundLiteralExpr>(E);
       llvm::Constant* C = Visit(CLE->getInitializer());
-      C = new llvm::GlobalVariable(C->getType(),E->getType().isConstQualified(), 
-                                   llvm::GlobalValue::InternalLinkage,
-                                   C, ".compoundliteral", &CGM.getModule());
+      // FIXME: "Leaked" on failure.
+      if (C)
+        C = new llvm::GlobalVariable(C->getType(),
+                                     E->getType().isConstQualified(), 
+                                     llvm::GlobalValue::InternalLinkage,
+                                     C, ".compoundliteral", &CGM.getModule());
       return C;
     }
     case Expr::DeclRefExprClass: 
@@ -515,6 +531,8 @@
         Base = Visit(ME->getBase());
       else
         Base = EmitLValue(ME->getBase());
+      if (!Base)
+        return 0;
 
       FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl());
       // FIXME: Handle other kinds of member expressions.
@@ -528,10 +546,13 @@
     }
     case Expr::ArraySubscriptExprClass: {
       ArraySubscriptExpr* ASExpr = cast<ArraySubscriptExpr>(E);
-      llvm::Constant *Base = Visit(ASExpr->getBase());
-      llvm::Constant *Index = Visit(ASExpr->getIdx());
       assert(!ASExpr->getBase()->getType()->isVectorType() &&
              "Taking the address of a vector component is illegal!");
+
+      llvm::Constant *Base = Visit(ASExpr->getBase());
+      llvm::Constant *Index = Visit(ASExpr->getIdx());
+      if (!Base || !Index)
+        return 0;
       return llvm::ConstantExpr::getGetElementPtr(Base, &Index, 1);
     }
     case Expr::StringLiteralClass:
@@ -594,9 +615,8 @@
       return CGM.GetAddrOfConstantCFString(S);
     }
     }
-    CGM.ErrorUnsupported(E, "constant l-value expression");
-    llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType()));
-    return llvm::UndefValue::get(Ty);
+
+    return 0;
   }
 };
   
@@ -604,8 +624,6 @@
 
 llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E,
                                                 CodeGenFunction *CGF) {
-  QualType type = Context.getCanonicalType(E->getType());
-
   Expr::EvalResult Result;
   
   if (E->Evaluate(Result, Context)) {
@@ -613,8 +631,8 @@
            "Constant expr should not have any side effects!");
     switch (Result.Val.getKind()) {
     case APValue::Uninitialized:
-      assert(0 && "Constant expressions should be uninitialized.");
-      return llvm::UndefValue::get(getTypes().ConvertType(type));
+      assert(0 && "Constant expressions should be initialized.");
+      return 0;
     case APValue::LValue: {
       llvm::Constant *Offset = 
         llvm::ConstantInt::get(llvm::Type::Int64Ty, 
@@ -637,7 +655,7 @@
       }
       
       return llvm::ConstantExpr::getIntToPtr(Offset, 
-                                             getTypes().ConvertType(type));
+                                          getTypes().ConvertType(E->getType()));
     }
     case APValue::Int: {
       llvm::Constant *C = llvm::ConstantInt::get(Result.Val.getInt());
@@ -683,7 +701,7 @@
   }
 
   llvm::Constant* C = ConstExprEmitter(*this, CGF).Visit(const_cast<Expr*>(E));
-  if (C->getType() == llvm::Type::Int1Ty) {
+  if (C && C->getType() == llvm::Type::Int1Ty) {
     const llvm::Type *BoolTy = getTypes().ConvertTypeForMem(E->getType());
     C = llvm::ConstantExpr::getZExt(C, BoolTy);
   }

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=64780&r1=64779&r2=64780&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Tue Feb 17 12:43:32 2009
@@ -247,7 +247,12 @@
                                         const std::string &Name);
 
   void UpdateCompletedType(const TagDecl *D);
+
+  /// EmitConstantExpr - Try to emit the given expression as a
+  /// constant; returns 0 if the expression cannot be emitted as a
+  /// constant.
   llvm::Constant *EmitConstantExpr(const Expr *E, CodeGenFunction *CGF = 0);
+
   llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV,
                                    const AnnotateAttr *AA, unsigned LineNo);
 

Modified: cfe/trunk/test/CodeGen/staticinit.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/staticinit.c?rev=64780&r1=64779&r2=64780&view=diff

==============================================================================
--- cfe/trunk/test/CodeGen/staticinit.c (original)
+++ cfe/trunk/test/CodeGen/staticinit.c Tue Feb 17 12:43:32 2009
@@ -1,4 +1,5 @@
-// RUN: clang -emit-llvm < %s | grep "g.b = internal global i8. getelementptr"
+// RUN: clang -arch i386 -emit-llvm -o %t %s &&
+// RUN: grep "g.b = internal global i8. getelementptr" %t &&
 
 struct AStruct { 
 	int i;
@@ -24,3 +25,7 @@
 void foo(void) {
   static struct s var = {((void*)&((char*)0)[0])};
 }
+
+// RUN: grep "f1.l0 = internal global i32 ptrtoint (i32 ()\* @f1 to i32)" %t
+int f1(void) { static int l0 = (unsigned) f1; }
+





More information about the cfe-commits mailing list