]> granicus.if.org Git - clang/commitdiff
Minor enhancements to Evaluate.
authorEli Friedman <eli.friedman@gmail.com>
Mon, 23 Mar 2009 04:38:34 +0000 (04:38 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Mon, 23 Mar 2009 04:38:34 +0000 (04:38 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67503 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ExprConstant.cpp
test/Sema/const-eval.c

index a0ef7460c5f96a3b70f4a16b0e241446a9185939..529b4d49c550b4b6657949573a6071be8177c15c 100644 (file)
@@ -71,7 +71,7 @@ static bool HandleConversionToBool(Expr* E, bool& Result, EvalInfo &Info) {
       return false;
     Result = !FloatResult.isZero();
     return true;
-  } else if (E->getType()->isPointerType()) {
+  } else if (E->getType()->hasPointerRepresentation()) {
     APValue PointerResult;
     if (!EvaluatePointer(E, PointerResult, Info))
       return false;
@@ -79,8 +79,19 @@ static bool HandleConversionToBool(Expr* E, bool& Result, EvalInfo &Info) {
     // the check look like?
     Result = PointerResult.getLValueBase() || PointerResult.getLValueOffset();
     return true;
+  } else if (E->getType()->isAnyComplexType()) {
+    APValue ComplexResult;
+    if (!EvaluateComplex(E, ComplexResult, Info))
+      return false;
+    if (ComplexResult.isComplexFloat()) {
+      Result = !ComplexResult.getComplexFloatReal().isZero() ||
+               !ComplexResult.getComplexFloatImag().isZero();
+    } else {
+      Result = ComplexResult.getComplexIntReal().getBoolValue() ||
+               ComplexResult.getComplexIntImag().getBoolValue();
+    }
+    return true;
   }
-  // FIXME: Handle pointer-like types, complex types
 
   return false;
 }
@@ -890,21 +901,22 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
       APValue LHSValue;
       if (!EvaluatePointer(E->getLHS(), LHSValue, Info))
         return false;
-      
+
       APValue RHSValue;
       if (!EvaluatePointer(E->getRHS(), RHSValue, Info))
         return false;
-      
-      // FIXME: Is this correct? What if only one of the operands has a base?
+
+      // Reject any bases; this is conservative, but good enough for
+      // common uses
       if (LHSValue.getLValueBase() || RHSValue.getLValueBase())
         return false;
-      
+
       const QualType Type = E->getLHS()->getType();
       const QualType ElementType = Type->getAsPointerType()->getPointeeType();
 
       uint64_t D = LHSValue.getLValueOffset() - RHSValue.getLValueOffset();
       D /= Info.Ctx.getTypeSize(ElementType) / 8;
-      
+
       return Success(D, E);
     }
   }
@@ -980,20 +992,20 @@ unsigned IntExprEvaluator::GetAlignOfType(QualType T) {
   // __alignof__(void) = 1 as a gcc extension.
   if (Ty->isVoidType())
     return 1;
-  
+
   // GCC extension: alignof(function) = 4.
   // FIXME: AlignOf shouldn't be unconditionally 4!  It should listen to the
   // attribute(align) directive.
   if (Ty->isFunctionType())
     return 4;
-  
+
   if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(Ty))
     return GetAlignOfType(QualType(EXTQT->getBaseType(), 0));
 
   // alignof VLA/incomplete array.
   if (const ArrayType *VAT = dyn_cast<ArrayType>(Ty))
     return GetAlignOfType(VAT->getElementType());
-  
+
   // sizeof (objc class)?
   if (isa<ObjCInterfaceType>(Ty))
     return 1;  // FIXME: This probably isn't right.
@@ -1010,7 +1022,7 @@ unsigned IntExprEvaluator::GetAlignOfExpr(const Expr *E) {
   // to 1 in those cases. 
   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
     return Info.Ctx.getDeclAlignInBytes(DRE->getDecl());
-    
+
   if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
     return Info.Ctx.getDeclAlignInBytes(ME->getMemberDecl());
 
@@ -1030,14 +1042,14 @@ bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
     else
       return Success(GetAlignOfExpr(E->getArgumentExpr()), E);
   }
-  
+
   QualType SrcTy = E->getTypeOfArgument();
 
   // sizeof(void), __alignof__(void), sizeof(function) = 1 as a gcc
   // extension.
   if (SrcTy->isVoidType() || SrcTy->isFunctionType())
     return Success(1, E);
-  
+
   // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
   if (!SrcTy->isConstantSizeType())
     return false;
index 7714f488171530380bc8db49286ba7bca28e6ae0..03aeb2a0b3a0d2685a1d3f27be35809c86dc80af 100644 (file)
@@ -50,3 +50,8 @@ EVAL_EXPR(22, (__real__ (2i+3)) == 3 ? 1 : -1);
 int g23[(int)(1.0 / 1.0)] = { 1 };
 int g24[(int)(1.0 / 1.0)] = { 1 , 2 }; // expected-warning {{excess elements in array initializer}}
 int g25[(int)(1.0 + 1.0)], g26 = sizeof(g25);
+
+EVAL_EXPR(26, (_Complex double)0 ? -1 : 1)
+EVAL_EXPR(27, (_Complex int)0 ? -1 : 1)
+EVAL_EXPR(28, (_Complex double)1 ? 1 : -1)
+EVAL_EXPR(29, (_Complex int)1 ? 1 : -1)