]> granicus.if.org Git - clang/commitdiff
implement codegen support for sizeof(void), fixing PR2080.
authorChris Lattner <sabre@nondot.org>
Thu, 21 Feb 2008 05:45:29 +0000 (05:45 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 21 Feb 2008 05:45:29 +0000 (05:45 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47429 91177308-0d34-0410-b5e6-96231b3b80d8

AST/Expr.cpp
CodeGen/CGExprScalar.cpp
test/CodeGen/exprs.c

index 7a9a78eb06caddfdd8adde9d963390c3ac8ec771..1a8b46df600f5b982a043d0adf00ad3782f7fa0d 100644 (file)
@@ -580,7 +580,8 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const {
   case SizeOfAlignOfTypeExprClass: {
     const SizeOfAlignOfTypeExpr *Exp = cast<SizeOfAlignOfTypeExpr>(this);
     // alignof always evaluates to a constant.
-    if (Exp->isSizeOf() && !Exp->getArgumentType()->isConstantSizeType()) {
+    if (Exp->isSizeOf() && !Exp->getArgumentType()->isVoidType() &&
+        !Exp->getArgumentType()->isConstantSizeType()) {
       if (Loc) *Loc = Exp->getOperatorLoc();
       return false;
     }
@@ -721,17 +722,23 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
       return true;  // FIXME: this is wrong.
     case UnaryOperator::SizeOf:
     case UnaryOperator::AlignOf:
+      // Return the result in the right width.
+      Result.zextOrTrunc(
+                         static_cast<uint32_t>(Ctx.getTypeSize(getType(),
+                                                       Exp->getOperatorLoc())));
+        
+      // sizeof(void) and __alignof__(void) = 1 as a gcc extension.
+      if (Exp->getSubExpr()->getType()->isVoidType()) {
+        Result = 1;
+        break;
+      }
+        
       // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
       if (!Exp->getSubExpr()->getType()->isConstantSizeType()) {
         if (Loc) *Loc = Exp->getOperatorLoc();
         return false;
       }
       
-      // Return the result in the right width.
-      Result.zextOrTrunc(
-        static_cast<uint32_t>(Ctx.getTypeSize(getType(),
-                                              Exp->getOperatorLoc())));
-
       // Get information about the size or align.
       if (Exp->getSubExpr()->getType()->isFunctionType()) {
         // GCC extension: sizeof(function) = 1.
@@ -771,16 +778,23 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
   }
   case SizeOfAlignOfTypeExprClass: {
     const SizeOfAlignOfTypeExpr *Exp = cast<SizeOfAlignOfTypeExpr>(this);
-    // alignof always evaluates to a constant.
+    
+    // Return the result in the right width.
+    Result.zextOrTrunc(
+      static_cast<uint32_t>(Ctx.getTypeSize(getType(), Exp->getOperatorLoc())));
+    
+    // sizeof(void) and __alignof__(void) = 1 as a gcc extension.
+    if (Exp->getArgumentType()->isVoidType()) {
+      Result = 1;
+      break;
+    }
+    
+    // alignof always evaluates to a constant, sizeof does if arg is not VLA.
     if (Exp->isSizeOf() && !Exp->getArgumentType()->isConstantSizeType()) {
       if (Loc) *Loc = Exp->getOperatorLoc();
       return false;
     }
 
-    // Return the result in the right width.
-    Result.zextOrTrunc(
-      static_cast<uint32_t>(Ctx.getTypeSize(getType(), Exp->getOperatorLoc())));
-    
     // Get information about the size or align.
     if (Exp->getArgumentType()->isFunctionType()) {
       // GCC extension: sizeof(function) = 1.
index 2c7763db8f20d31f3d4f229e43cb5a223ee2a86d..85831d5dd3616aa060b088d66abb1a081663ff50 100644 (file)
@@ -607,6 +607,15 @@ Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) {
 /// an integer (RetType).
 Value *ScalarExprEmitter::EmitSizeAlignOf(QualType TypeToSize, 
                                           QualType RetType,bool isSizeOf){
+  assert(RetType->isIntegerType() && "Result type must be an integer!");
+  uint32_t ResultWidth = 
+    static_cast<uint32_t>(CGF.getContext().getTypeSize(RetType, 
+                                                       SourceLocation()));
+
+  // sizeof(void) and __alignof__(void) = 1 as a gcc extension.
+  if (TypeToSize->isVoidType())
+    return llvm::ConstantInt::get(llvm::APInt(ResultWidth, 1));
+  
   /// FIXME: This doesn't handle VLAs yet!
   std::pair<uint64_t, unsigned> Info =
     CGF.getContext().getTypeInfo(TypeToSize, SourceLocation());
@@ -614,10 +623,6 @@ Value *ScalarExprEmitter::EmitSizeAlignOf(QualType TypeToSize,
   uint64_t Val = isSizeOf ? Info.first : Info.second;
   Val /= 8;  // Return size in bytes, not bits.
   
-  assert(RetType->isIntegerType() && "Result type must be an integer!");
-  
-  uint32_t ResultWidth = static_cast<uint32_t>(
-    CGF.getContext().getTypeSize(RetType, SourceLocation()));
   return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val));
 }
 
index 16b63f8883bb6681761c72f9135c23662afeacb5..b4384ee0c2ae3e1b03eab1653416e438f774ebb5 100644 (file)
@@ -23,3 +23,14 @@ int test3() {
   bp -= (short)1;
 }
 
+// PR2080 - sizeof void
+int t1 = sizeof(void);
+int t2 = __alignof__(void);
+void test4() {
+  t1 = sizeof(void);
+  t2 = __alignof__(void);
+  
+  t1 = sizeof(test4());
+  t2 = __alignof__(test4());
+}
+