Change the AST generated for offsetof a bit so that it looks like a 
normal expression, and change Evaluate and IRGen to evaluate it like a 
normal expression.  This simplifies the code significantly, and fixes 
PR3396.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65622 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 29d5f59..43cbe98 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -4270,16 +4270,17 @@
   if (!Dependent && !ArgTy->isRecordType())
     return Diag(TypeLoc, diag::err_offsetof_record_type) << ArgTy;
 
-  // Otherwise, create a compound literal expression as the base, and
-  // iteratively process the offsetof designators.
-  InitListExpr *IList =
-      new (Context) InitListExpr(SourceLocation(), 0, 0, SourceLocation());
-  IList->setType(ArgTy);
-  Expr *Res =
-      new (Context) CompoundLiteralExpr(SourceLocation(), ArgTy, IList, false);
+  // Otherwise, create a null pointer as the base, and iteratively process
+  // the offsetof designators.
+  QualType ArgTyPtr = Context.getPointerType(ArgTy);
+  Expr* Res = new (Context) ImplicitValueInitExpr(ArgTyPtr);
+  Res = new (Context) UnaryOperator(Res, UnaryOperator::Deref, 
+                                    ArgTy, SourceLocation());
 
   // offsetof with non-identifier designators (e.g. "offsetof(x, a.b[c])") are a
   // GCC extension, diagnose them.
+  // FIXME: This diagnostic isn't actually visible because the location is in
+  // a system header!
   if (NumComponents != 1)
     Diag(BuiltinLoc, diag::ext_offsetof_extended_field_designator)
       << SourceRange(CompPtr[1].LocStart, CompPtr[NumComponents-1].LocEnd);
@@ -4300,6 +4301,10 @@
 
         // FIXME: C++: Verify that operator[] isn't overloaded.
 
+        // Promote the array so it looks more like a normal array subscript
+        // expression.
+        DefaultFunctionArrayConversion(Res);
+
         // C99 6.5.2.1p1
         Expr *Idx = static_cast<Expr*>(OC.U.E);
         if (!Idx->isTypeDependent() && !Idx->getType()->isIntegerType())