[clang] 87461d6 - [clang][Interp] Implement __builtin_offsetof

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 11 03:04:11 PDT 2023


Author: Timm Bäder
Date: 2023-09-11T12:03:47+02:00
New Revision: 87461d669684668f02362f77807f313187667329

URL: https://github.com/llvm/llvm-project/commit/87461d669684668f02362f77807f313187667329
DIFF: https://github.com/llvm/llvm-project/commit/87461d669684668f02362f77807f313187667329.diff

LOG: [clang][Interp] Implement __builtin_offsetof

Differential Revision: https://reviews.llvm.org/D156400

Added: 
    

Modified: 
    clang/lib/AST/Interp/ByteCodeExprGen.cpp
    clang/lib/AST/Interp/ByteCodeExprGen.h
    clang/lib/AST/Interp/Interp.h
    clang/lib/AST/Interp/InterpBuiltin.cpp
    clang/lib/AST/Interp/Opcodes.td
    clang/test/AST/Interp/literals.cpp
    clang/test/SemaCXX/class-layout.cpp
    clang/test/SemaCXX/offsetof-0x.cpp
    clang/test/SemaCXX/offsetof.cpp

Removed: 
    clang/test/AST/Interp/class-layout.cpp


################################################################################
diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 6a492c4c907cde0..4f89cbec76e7930 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1453,6 +1453,41 @@ bool ByteCodeExprGen<Emitter>::VisitSourceLocExpr(const SourceLocExpr *E) {
   return true;
 }
 
+template <class Emitter>
+bool ByteCodeExprGen<Emitter>::VisitOffsetOfExpr(const OffsetOfExpr *E) {
+  unsigned N = E->getNumComponents();
+  if (N == 0)
+    return false;
+
+  for (unsigned I = 0; I != N; ++I) {
+    const OffsetOfNode &Node = E->getComponent(I);
+    if (Node.getKind() == OffsetOfNode::Array) {
+      const Expr *ArrayIndexExpr = E->getIndexExpr(Node.getArrayExprIndex());
+      PrimType IndexT = classifyPrim(ArrayIndexExpr->getType());
+
+      if (DiscardResult) {
+        if (!this->discard(ArrayIndexExpr))
+          return false;
+        continue;
+      }
+
+      if (!this->visit(ArrayIndexExpr))
+        return false;
+      // Cast to Sint64.
+      if (IndexT != PT_Sint64) {
+        if (!this->emitCast(IndexT, PT_Sint64, E))
+          return false;
+      }
+    }
+  }
+
+  if (DiscardResult)
+    return true;
+
+  PrimType T = classifyPrim(E->getType());
+  return this->emitOffsetOf(T, E, E);
+}
+
 template <class Emitter> bool ByteCodeExprGen<Emitter>::discard(const Expr *E) {
   if (E->containsErrors())
     return false;

diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 470d43a5d4c77e3..47a3f75f13459d0 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -105,6 +105,7 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
   bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E);
   bool VisitCXXConstructExpr(const CXXConstructExpr *E);
   bool VisitSourceLocExpr(const SourceLocExpr *E);
+  bool VisitOffsetOfExpr(const OffsetOfExpr *E);
 
 protected:
   bool visitExpr(const Expr *E) override;

diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 5006f72fe7237f5..d33c22ad60f9c02 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -181,6 +181,10 @@ bool Interpret(InterpState &S, APValue &Result);
 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
                       const CallExpr *Call);
 
+/// Interpret an offsetof operation.
+bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E,
+                       llvm::ArrayRef<int64_t> ArrayIndices, int64_t &Result);
+
 enum class ArithOp { Add, Sub };
 
 //===----------------------------------------------------------------------===//
@@ -1839,6 +1843,21 @@ inline bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind) {
   return false;
 }
 
+template <PrimType Name, class T = typename PrimConv<Name>::T>
+inline bool OffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E) {
+  llvm::SmallVector<int64_t> ArrayIndices;
+  for (size_t I = 0; I != E->getNumExpressions(); ++I)
+    ArrayIndices.emplace_back(S.Stk.pop<int64_t>());
+
+  int64_t Result;
+  if (!InterpretOffsetOf(S, OpPC, E, ArrayIndices, Result))
+    return false;
+
+  S.Stk.push<T>(T::from(Result));
+
+  return true;
+}
+
 //===----------------------------------------------------------------------===//
 // Read opcode arguments
 //===----------------------------------------------------------------------===//

diff  --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp
index c607368f3b65824..4536e335bf1a162 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -8,6 +8,7 @@
 #include "Boolean.h"
 #include "Interp.h"
 #include "PrimType.h"
+#include "clang/AST/RecordLayout.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/TargetInfo.h"
 
@@ -519,5 +520,79 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
   return false;
 }
 
+bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E,
+                       llvm::ArrayRef<int64_t> ArrayIndices,
+                       int64_t &IntResult) {
+  CharUnits Result;
+  unsigned N = E->getNumComponents();
+  assert(N > 0);
+
+  unsigned ArrayIndex = 0;
+  QualType CurrentType = E->getTypeSourceInfo()->getType();
+  for (unsigned I = 0; I != N; ++I) {
+    const OffsetOfNode &Node = E->getComponent(I);
+    switch (Node.getKind()) {
+    case OffsetOfNode::Field: {
+      const FieldDecl *MemberDecl = Node.getField();
+      const RecordType *RT = CurrentType->getAs<RecordType>();
+      if (!RT)
+        return false;
+      RecordDecl *RD = RT->getDecl();
+      if (RD->isInvalidDecl())
+        return false;
+      const ASTRecordLayout &RL = S.getCtx().getASTRecordLayout(RD);
+      unsigned FieldIndex = MemberDecl->getFieldIndex();
+      assert(FieldIndex < RL.getFieldCount() && "offsetof field in wrong type");
+      Result += S.getCtx().toCharUnitsFromBits(RL.getFieldOffset(FieldIndex));
+      CurrentType = MemberDecl->getType().getNonReferenceType();
+      break;
+    }
+    case OffsetOfNode::Array: {
+      // When generating bytecode, we put all the index expressions as Sint64 on
+      // the stack.
+      int64_t Index = ArrayIndices[ArrayIndex];
+      const ArrayType *AT = S.getCtx().getAsArrayType(CurrentType);
+      if (!AT)
+        return false;
+      CurrentType = AT->getElementType();
+      CharUnits ElementSize = S.getCtx().getTypeSizeInChars(CurrentType);
+      Result += Index * ElementSize;
+      ++ArrayIndex;
+      break;
+    }
+    case OffsetOfNode::Base: {
+      const CXXBaseSpecifier *BaseSpec = Node.getBase();
+      if (BaseSpec->isVirtual())
+        return false;
+
+      // Find the layout of the class whose base we are looking into.
+      const RecordType *RT = CurrentType->getAs<RecordType>();
+      if (!RT)
+        return false;
+      const RecordDecl *RD = RT->getDecl();
+      if (RD->isInvalidDecl())
+        return false;
+      const ASTRecordLayout &RL = S.getCtx().getASTRecordLayout(RD);
+
+      // Find the base class itself.
+      CurrentType = BaseSpec->getType();
+      const RecordType *BaseRT = CurrentType->getAs<RecordType>();
+      if (!BaseRT)
+        return false;
+
+      // Add the offset to the base.
+      Result += RL.getBaseClassOffset(cast<CXXRecordDecl>(BaseRT->getDecl()));
+      break;
+    }
+    case OffsetOfNode::Identifier:
+      llvm_unreachable("Dependent OffsetOfExpr?");
+    }
+  }
+
+  IntResult = Result.getQuantity();
+
+  return true;
+}
+
 } // namespace interp
 } // namespace clang

diff  --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td
index 8bdc4432e89b410..e0c7cf1eaf92489 100644
--- a/clang/lib/AST/Interp/Opcodes.td
+++ b/clang/lib/AST/Interp/Opcodes.td
@@ -53,6 +53,7 @@ def ArgRoundingMode : ArgType { let Name = "llvm::RoundingMode"; }
 def ArgLETD: ArgType { let Name = "const LifetimeExtendedTemporaryDecl *"; }
 def ArgCastKind : ArgType { let Name = "CastKind"; }
 def ArgCallExpr : ArgType { let Name = "const CallExpr *"; }
+def ArgOffsetOfExpr : ArgType { let Name = "const OffsetOfExpr *"; }
 
 //===----------------------------------------------------------------------===//
 // Classes of types instructions operate on.
@@ -198,6 +199,12 @@ def CallPtr : Opcode {
   let Types = [];
 }
 
+def OffsetOf : Opcode {
+  let Types = [IntegerTypeClass];
+  let Args = [ArgOffsetOfExpr];
+  let HasGroup = 1;
+}
+
 //===----------------------------------------------------------------------===//
 // Frame management
 //===----------------------------------------------------------------------===//

diff  --git a/clang/test/AST/Interp/class-layout.cpp b/clang/test/AST/Interp/class-layout.cpp
deleted file mode 100644
index 41a964780b64245..000000000000000
--- a/clang/test/AST/Interp/class-layout.cpp
+++ /dev/null
@@ -1,698 +0,0 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -fexperimental-new-constant-interpreter -std=c++98 -Wno-inaccessible-base -Wno-c++11-extensions
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -fexperimental-new-constant-interpreter -std=c++11 -Wno-inaccessible-base
-// RUN: %clang_cc1 -triple x86_64-apple-darwin    %s -fsyntax-only -verify -fexperimental-new-constant-interpreter -std=c++11 -Wno-inaccessible-base -DCLANG_ABI_COMPAT=15
-// RUN: %clang_cc1 -triple x86_64-scei-ps4        %s -fsyntax-only -verify -fexperimental-new-constant-interpreter -std=c++11 -Wno-inaccessible-base -DCLANG_ABI_COMPAT=6
-// RUN: %clang_cc1 -triple x86_64-sie-ps5         %s -fsyntax-only -verify -fexperimental-new-constant-interpreter -std=c++11 -Wno-inaccessible-base -DCLANG_ABI_COMPAT=6
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -fexperimental-new-constant-interpreter -std=c++11 -Wno-inaccessible-base -fclang-abi-compat=6 -DCLANG_ABI_COMPAT=6
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -fexperimental-new-constant-interpreter -std=c++11 -Wno-inaccessible-base -fclang-abi-compat=14 -DCLANG_ABI_COMPAT=14
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -fexperimental-new-constant-interpreter -std=c++11 -Wno-inaccessible-base -fclang-abi-compat=15 -DCLANG_ABI_COMPAT=15
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -fexperimental-new-constant-interpreter -std=c++11 -Wno-inaccessible-base -fclang-abi-compat=16 -DCLANG_ABI_COMPAT=16
-// expected-no-diagnostics
-
-// FIXME: This is a copy of clang/test/SemaCXX/class-layout.cpp, but with the
-//   __builtin_offsetof calls commented out. Once that is supported in the
-//   new interpreter, we might as well remove this duplicated file and
-//   just use the one in SemaCXX/.
-
-#define SA(n, p) int a##n[(p) ? 1 : -1]
-
-struct A {
-  int a;
-  char b;
-};
-
-SA(0, sizeof(A) == 8);
-
-struct B : A {
-  char c;
-};
-
-SA(1, sizeof(B) == 12);
-
-struct C {
-// Make fields private so C won't be a POD type.
-private:
-  int a;
-  char b;
-};
-
-SA(2, sizeof(C) == 8);
-
-struct D : C {
-  char c;
-};
-
-SA(3, sizeof(D) == 8);
-
-struct __attribute__((packed)) E {
-  char b;
-  int a;
-};
-
-SA(4, sizeof(E) == 5);
-
-struct __attribute__((packed)) F : E {
-  char d;
-};
-
-SA(5, sizeof(F) == 6);
-
-struct G { G(); };
-struct H : G { };
-
-SA(6, sizeof(H) == 1);
-
-struct I {
-  char b;
-  int a;
-} __attribute__((packed));
-
-SA(6_1, sizeof(I) == 5);
-
-// PR5580
-namespace PR5580 {
-
-class A { bool iv0 : 1; };
-SA(7, sizeof(A) == 1);  
-
-class B : A { bool iv0 : 1; };
-SA(8, sizeof(B) == 2);
-
-struct C { bool iv0 : 1; };
-SA(9, sizeof(C) == 1);  
-
-struct D : C { bool iv0 : 1; };
-SA(10, sizeof(D) == 2);
-
-}
-
-namespace Test1 {
-
-// Test that we don't assert on this hierarchy.
-struct A { };
-struct B : A { virtual void b(); };
-class C : virtual A { int c; };
-struct D : virtual B { };
-struct E : C, virtual D { };
-class F : virtual E { };
-struct G : virtual E, F { };
-
-SA(0, sizeof(G) == 24);
-
-}
-
-namespace Test2 {
-
-// Test that this somewhat complex class structure is laid out correctly.
-struct A { };
-struct B : A { virtual void b(); };
-struct C : virtual B { };
-struct D : virtual A { };
-struct E : virtual B, D { };
-struct F : E, virtual C { };
-struct G : virtual F, A { };
-struct H { G g; };
-
-SA(0, sizeof(H) == 24);
-
-}
-
-namespace PR16537 {
-namespace test1 {
-  struct pod_in_11_only {
-  private:
-    long long x;
-  };
-   
-  struct tail_padded_pod_in_11_only {
-    pod_in_11_only pod11;
-    char tail_padding;
-  };
-    
-  struct might_use_tail_padding : public tail_padded_pod_in_11_only {
-    char may_go_into_tail_padding;
-  };
-
-  SA(0, sizeof(might_use_tail_padding) == 16);
-}
-
-namespace test2 {
-  struct pod_in_11_only {
-  private:
-    long long x;
-  };
-   
-  struct tail_padded_pod_in_11_only {
-    pod_in_11_only pod11 __attribute__((aligned(16)));
-  };
-    
-  struct might_use_tail_padding : public tail_padded_pod_in_11_only {
-    char may_go_into_tail_padding;
-  };
-
-  SA(0, sizeof(might_use_tail_padding) == 16);
-}
-
-namespace test3 {
-  struct pod_in_11_only {
-  private:
-    long long x;
-  };
-   
-  struct tail_padded_pod_in_11_only {
-    pod_in_11_only pod11;
-    char tail_padding;
-  };
-
-  struct second_base {
-      char foo;
-  };
-    
-  struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
-
-  };
-  SA(0, sizeof(might_use_tail_padding) == 16);
-}
-
-namespace test4 {
-  struct pod_in_11_only {
-  private:
-    long long x;
-  };
-   
-  struct tail_padded_pod_in_11_only {
-    pod_in_11_only pod11;
-    char tail_padding;
-  };
-
-  struct second_base {
-    char foo;
-  };
-    
-  struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
-    char may_go_into_tail_padding;
-  };
-  SA(0, sizeof(might_use_tail_padding) == 16);
-}
-
-namespace test5 {
-  struct pod_in_11_only {
-  private:
-    long long x;
-  };
-
-  struct pod_in_11_only2 {
-  private:
-    long long x;
-  };
-   
-  struct tail_padded_pod_in_11_only {
-    pod_in_11_only pod11;
-    char tail_padding;
-  };
-
-  struct second_base {
-    pod_in_11_only2 two;
-    char foo;
-  };
-    
-  struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
-    char may_go_into_tail_padding;
-  };
-  SA(0, sizeof(might_use_tail_padding) == 32);
-}
-
-namespace test6 {
-  struct pod_in_11_only {
-  private:
-    long long x;
-  };
-
-  struct pod_in_11_only2 {
-  private:
-    long long x;
-  };
-   
-  struct tail_padded_pod_in_11_only {
-    pod_in_11_only pod11;
-    char tail_padding;
-  };
-
-  struct second_base {
-    pod_in_11_only2 two;
-    char foo;
-  };
-    
-  struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
-    char may_go_into_tail_padding;
-  };
-  SA(0, sizeof(might_use_tail_padding) == 32);
-}
-
-namespace test7 {
-  struct pod_in_11_only {
-  private:
-    long long x;
-  };
-   
-  struct tail_padded_pod_in_11_only {
-    pod_in_11_only pod11;
-    pod_in_11_only pod12;
-    char tail_padding;
-  };
-    
-  struct might_use_tail_padding : public tail_padded_pod_in_11_only {
-    char may_go_into_tail_padding;
-  };
-
-  SA(0, sizeof(might_use_tail_padding) == 24);
-}
-
-namespace test8 {
-  struct pod_in_11_only {
-  private:
-    long long x;
-  };
-   
-  struct tail_padded_pod_in_11_only {
-    pod_in_11_only pod11;
-    char tail_padding;
-  };
-
-  struct another_layer {
-    tail_padded_pod_in_11_only pod;
-    char padding;
-  };
-    
-  struct might_use_tail_padding : public another_layer {
-    char may_go_into_tail_padding;
-  };
-
-  SA(0, sizeof(might_use_tail_padding) == 24);
-}
-
-namespace test9 {
-  struct pod_in_11_only {
-  private:
-    long long x;
-  };
-   
-  struct tail_padded_pod_in_11_only {
-    pod_in_11_only pod11;
-    char tail_padding;
-  };
-
-  struct another_layer : tail_padded_pod_in_11_only {
-  };
-    
-  struct might_use_tail_padding : public another_layer {
-    char may_go_into_tail_padding;
-  };
-
-  SA(0, sizeof(might_use_tail_padding) == 16);
-}
-
-namespace test10 {
-  struct pod_in_11_only {
-  private:
-    long long x;
-  };
-   
-  struct A {
-    pod_in_11_only a;
-    char apad;
-  };
-
-  struct B {
-    char b;
-  };
-
-  struct C {
-    pod_in_11_only c;
-    char cpad;
-  };
-
-  struct D {
-    char d;
-  };
-    
-  struct might_use_tail_padding : public A, public B, public C, public D {
-  };
-
-  SA(0, sizeof(might_use_tail_padding) == 32);
-}
-
-namespace test11 {
-  struct pod_in_11_only {
-  private:
-    long long x;
-  };
-   
-  struct A {
-    pod_in_11_only a;
-    char apad;
-  };
-
-  struct B {
-    char b_pre;
-    pod_in_11_only b;
-    char bpad;
-  };
-
-  struct C {
-    char c_pre;
-    pod_in_11_only c;
-    char cpad;
-  };
-
-  struct D {
-    char d_pre;
-    pod_in_11_only d;
-    char dpad;
-  };
-    
-  struct might_use_tail_padding : public A, public B, public C, public D {
-    char m;
-  };
-
-  SA(0, sizeof(might_use_tail_padding) == 88);
-}
-
-namespace test12 {
-  struct pod_in_11_only {
-  private:
-    long long x;
-  };
-   
-  struct A {
-    pod_in_11_only a __attribute__((aligned(128)));
-  };
-
-  struct B {
-    char bpad;
-  };
-
-  struct C {
-    char cpad;
-  };
-
-  struct D {
-    char dpad;
-  };
-    
-  struct might_use_tail_padding : public A, public B, public C, public D {
-    char m;
-  };
-  SA(0, sizeof(might_use_tail_padding) == 128);
-}
-
-namespace test13 {
-  struct pod_in_11_only {
-  private:
-    long long x;
-  };
-   
-  struct A {
-    pod_in_11_only a;
-    char apad;
-  };
-
-  struct B {
-  };
-
-  struct C {
-    char c_pre;
-    pod_in_11_only c;
-    char cpad;
-  };
-
-  struct D {
-  };
-    
-  struct might_use_tail_padding : public A, public B, public C, public D {
-    char m;
-  };
-  SA(0, sizeof(might_use_tail_padding) == 40);
-}
-
-namespace test14 {
-  struct pod_in_11_only {
-  private:
-    long long x;
-  };
-   
-  struct A {
-    pod_in_11_only a;
-    char apad;
-  };
-
-  struct might_use_tail_padding : public A {
-    struct {
-      int : 0;
-    } x;
-  };
-  SA(0, sizeof(might_use_tail_padding) == 16);
-}
-
-namespace test15 {
-  struct pod_in_11_only {
-  private:
-    long long x;
-  };
-   
-  struct A {
-    pod_in_11_only a;
-    char apad;
-  };
-
-  struct might_use_tail_padding : public A {
-    struct {
-      char a:1;
-      char b:2;
-      char c:2;
-      char d:2;
-      char e:1;
-    } x;
-  };
-  SA(0, sizeof(might_use_tail_padding) == 16);
-}
-
-namespace test16 {
-  struct pod_in_11_only {
-  private:
-    long long x;
-  };
-   
-  struct A  {
-    pod_in_11_only a;
-    char apad;
-  };
-
-  struct B {
-    char bpod;
-    pod_in_11_only b;
-    char bpad;
-  };
-
-  struct C : public A, public B {
-  };
-  
-  struct D : public C {
-  };
-
-  struct might_use_tail_padding : public D {
-    char m;
-  };
-  SA(0, sizeof(might_use_tail_padding) == 40);
-}
-
-namespace test17 {
-  struct pod_in_11_only {
-  private:
-    long long x;
-  };
-   
-  struct A {
-    pod_in_11_only a __attribute__((aligned(512)));
-  };
-
-  struct B {
-    char bpad;
-    pod_in_11_only foo;
-    char btail;
-  };
-
-  struct C {
-    char cpad;
-  };
-
-  struct D {
-    char dpad;
-  };
-    
-  struct might_use_tail_padding : public A, public B, public C, public D {
-    char a;
-  };
-  SA(0, sizeof(might_use_tail_padding) == 512);
-}
-
-namespace test18 {
-  struct pod_in_11_only {
-  private:
-    long long x;
-  };
-   
-  struct A  {
-    pod_in_11_only a;
-    char apad;
-  };
-
-  struct B {
-    char bpod;
-    pod_in_11_only b;
-    char bpad;
-  };
-
-  struct A1  {
-    pod_in_11_only a;
-    char apad;
-  };
-
-  struct B1 {
-    char bpod;
-    pod_in_11_only b;
-    char bpad;
-  };
-
-  struct C : public A, public B {
-  };
-
-  struct D : public A1, public B1 {
-  };
-
-  struct E : public D, public C {
-  };
-
-  struct F : public E {
-  };
-
-  struct might_use_tail_padding : public F {
-    char m;
-  };
-  SA(0, sizeof(might_use_tail_padding) == 80);
-}
-} // namespace PR16537
-
-namespace PR37275 {
-  struct X { char c; };
-
-  struct A { int n; };
-  _Static_assert(_Alignof(A) == _Alignof(int), "");
-  _Static_assert(_Alignof(A[]) == _Alignof(A), "");
-
-  _Static_assert(_Alignof(int[]) == _Alignof(int), "");
-  _Static_assert(_Alignof(char[]) == _Alignof(char), "");
-
-  // __attribute__((packed)) does not apply to base classes.
-  struct __attribute__((packed)) B : X, A {};
-#if defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 6
-  _Static_assert(_Alignof(B) == 1, "");
-  _Static_assert(_Alignof(B[]) == 1, "");
-  //_Static_assert(__builtin_offsetof(B, n) == 1, ""); FIXME
-#else
-  _Static_assert(_Alignof(B) == _Alignof(int), "");
-  _Static_assert(_Alignof(B[]) == _Alignof(int), "");
-  //_Static_assert(__builtin_offsetof(B, n) == 4, ""); FIXME
-#endif
-
-  // #pragma pack does, though.
-#pragma pack(push, 2)
-  struct C : X, A {};
-  _Static_assert(_Alignof(C) == 2, "");
-  _Static_assert(_Alignof(C[]) == 2, "");
-  //_Static_assert(__builtin_offsetof(C, n) == 2, ""); FIXME
-
-  struct __attribute__((packed)) D : X, A {};
-#if defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 6
-  _Static_assert(_Alignof(D) == 1, "");
-  //_Static_assert(__builtin_offsetof(D, n) == 1, ""); FIXME
-#else
-  _Static_assert(_Alignof(D) == 2, "");
-  //_Static_assert(__builtin_offsetof(D, n) == 2, ""); FIXME
-#endif
-#pragma pack(pop)
-}
-
-namespace non_pod {
-struct t1 {
-protected:
-  int a;
-};
-// GCC prints warning: ignoring packed attribute because of unpacked non-POD field 't1 t2::v1'`
-struct t2 {
-  char c1;
-  short s1;
-  char c2;
-  t1 v1;
-} __attribute__((packed));
-#if defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 15
-_Static_assert(_Alignof(t1) == 4, "");
-_Static_assert(_Alignof(t1[]) == 4, "");
-_Static_assert(_Alignof(t2) == 1, "");
-_Static_assert(_Alignof(t2[]) == 1, "");
-#else
-_Static_assert(_Alignof(t1) == 4, "");
-_Static_assert(_Alignof(t1[]) == 4, "");
-_Static_assert(_Alignof(t2) == 4, "");
-_Static_assert(_Alignof(t2[]) == 4, "");
-#endif
-_Static_assert(sizeof(t2) == 8, ""); // it's still packing the rest of the struct
-} // namespace non_pod
-
-namespace non_pod_packed {
-struct t1 {
-protected:
-  int a;
-} __attribute__((packed));
-struct t2 {
-  t1 v1;
-} __attribute__((packed));
-_Static_assert(_Alignof(t1) == 1, "");
-_Static_assert(_Alignof(t2) == 1, "");
-} // namespace non_pod_packed
-
-namespace non_pod_packed_packed {
-struct B {
-  int b;
-};
-struct  FromB : B {
-} __attribute__((packed));
-struct C {
-  char a[3];
-  FromB b;
-} __attribute__((packed));
-//_Static_assert(__builtin_offsetof(C, b) == 3, ""); FIXME
-}
-
-namespace cxx11_pod {
-struct t1 {
-  t1() = default;
-  t1(const t1&) = delete;
-  ~t1() = delete;
-  t1(t1&&) = default;
-  int a;
-  char c;
-};
-struct t2 {
-  t1 v1;
-} __attribute__((packed));
-_Static_assert(_Alignof(t2) == 1, "");
-struct t3 : t1 {
-  char c;
-};
-#if defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 15
-_Static_assert(sizeof(t3) == 8, "");
-#else
-_Static_assert(sizeof(t3) == 12, "");
-#endif
-}

diff  --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp
index e78ae42eb6d431f..69a3edc87b6ec65 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -928,6 +928,7 @@ namespace DiscardExprs {
     (short)5;
     (bool)1;
     __null;
+    __builtin_offsetof(A, a);
 
     return 0;
   }

diff  --git a/clang/test/SemaCXX/class-layout.cpp b/clang/test/SemaCXX/class-layout.cpp
index 3ccd0ad25d7e753..9782ff08100b2d6 100644
--- a/clang/test/SemaCXX/class-layout.cpp
+++ b/clang/test/SemaCXX/class-layout.cpp
@@ -14,6 +14,25 @@
 // RUN: %clang_cc1 -triple s390x-none-zos %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base
 // RUN: %clang_cc1 -triple s390x-none-zos %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -fclang-abi-compat=15 -DCLANG_ABI_COMPAT=15
 
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++98 -Wno-inaccessible-base -Wno-c++11-extensions
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple x86_64-apple-darwin    %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -DCLANG_ABI_COMPAT=15
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple x86_64-scei-ps4        %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -DCLANG_ABI_COMPAT=6
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple x86_64-sie-ps5         %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -DCLANG_ABI_COMPAT=6
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -fclang-abi-compat=6 -DCLANG_ABI_COMPAT=6
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -fclang-abi-compat=14 -DCLANG_ABI_COMPAT=14
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -fclang-abi-compat=15 -DCLANG_ABI_COMPAT=15
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -fclang-abi-compat=16 -DCLANG_ABI_COMPAT=16
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple powerpc-ibm-aix7.3.0.0 %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -DCLANG_ABI_COMPAT=15
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple powerpc-ibm-aix7.3.0.0 %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -fclang-abi-compat=15 -DCLANG_ABI_COMPAT=15
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple powerpc64-ibm-aix7.3.0.0 %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -DCLANG_ABI_COMPAT=15
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple powerpc64-ibm-aix7.3.0.0 %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -fclang-abi-compat=15 -DCLANG_ABI_COMPAT=15
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple s390x-none-zos %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -triple s390x-none-zos %s -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -fclang-abi-compat=15 -DCLANG_ABI_COMPAT=15
+
+
+
+
 // expected-no-diagnostics
 
 #if !defined(__MVS__) && !defined(_AIX)

diff  --git a/clang/test/SemaCXX/offsetof-0x.cpp b/clang/test/SemaCXX/offsetof-0x.cpp
index 610d919c1af1ce4..a3fe2fbbad72df4 100644
--- a/clang/test/SemaCXX/offsetof-0x.cpp
+++ b/clang/test/SemaCXX/offsetof-0x.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only -std=c++11 -verify %s -Winvalid-offsetof
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only -std=c++11 -verify %s -Winvalid-offsetof -fexperimental-new-constant-interpreter
 
 struct NonPOD {
   virtual void f();

diff  --git a/clang/test/SemaCXX/offsetof.cpp b/clang/test/SemaCXX/offsetof.cpp
index 39ea3804dce3113..c984657ebe1f0ed 100644
--- a/clang/test/SemaCXX/offsetof.cpp
+++ b/clang/test/SemaCXX/offsetof.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only -verify %s -Winvalid-offsetof -std=c++98
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only -verify %s -Winvalid-offsetof -std=c++98 -fexperimental-new-constant-interpreter
 
 struct NonPOD {
   virtual void f();


        


More information about the cfe-commits mailing list