[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