[clang] 5b3247b - [tbaa] Handle base classes in struct tbaa

2022-07-06 Thread Jeroen Dobbelaere via cfe-commits

Author: Bruno De Fraine
Date: 2022-07-06T14:37:59+02:00
New Revision: 5b3247bf9f715cc1b399af1e17540b3a3ce9cdec

URL: 
https://github.com/llvm/llvm-project/commit/5b3247bf9f715cc1b399af1e17540b3a3ce9cdec
DIFF: 
https://github.com/llvm/llvm-project/commit/5b3247bf9f715cc1b399af1e17540b3a3ce9cdec.diff

LOG: [tbaa] Handle base classes in struct tbaa

This is a fix for the miscompilation reported in 
https://github.com/llvm/llvm-project/issues/55384

Not adding a new test case since existing test cases already cover base classes 
(including new-struct-path tbaa).

Reviewed By: jeroen.dobbelaere

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

Added: 


Modified: 
clang/lib/CodeGen/CodeGenTBAA.cpp
clang/test/CodeGen/tbaa-class.cpp
clang/unittests/CodeGen/TBAAMetadataTest.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CodeGenTBAA.cpp 
b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 95763d8e18b70..0cb63fbbe9e5c 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -335,7 +335,42 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const 
Type *Ty) {
   if (auto *TTy = dyn_cast(Ty)) {
 const RecordDecl *RD = TTy->getDecl()->getDefinition();
 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
-SmallVector Fields;
+using TBAAStructField = llvm::MDBuilder::TBAAStructField;
+SmallVector Fields;
+if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) {
+  // Handle C++ base classes. Non-virtual bases can treated a a kind of
+  // field. Virtual bases are more complex and omitted, but avoid an
+  // incomplete view for NewStructPathTBAA.
+  if (CodeGenOpts.NewStructPathTBAA && CXXRD->getNumVBases() != 0)
+return BaseTypeMetadataCache[Ty] = nullptr;
+  for (const CXXBaseSpecifier &B : CXXRD->bases()) {
+if (B.isVirtual())
+  continue;
+QualType BaseQTy = B.getType();
+const CXXRecordDecl *BaseRD = BaseQTy->getAsCXXRecordDecl();
+if (BaseRD->isEmpty())
+  continue;
+llvm::MDNode *TypeNode = isValidBaseType(BaseQTy)
+ ? getBaseTypeInfo(BaseQTy)
+ : getTypeInfo(BaseQTy);
+if (!TypeNode)
+  return BaseTypeMetadataCache[Ty] = nullptr;
+uint64_t Offset = Layout.getBaseClassOffset(BaseRD).getQuantity();
+uint64_t Size =
+Context.getASTRecordLayout(BaseRD).getDataSize().getQuantity();
+Fields.push_back(
+llvm::MDBuilder::TBAAStructField(Offset, Size, TypeNode));
+  }
+  // The order in which base class subobjects are allocated is unspecified,
+  // so may 
diff er from declaration order. In particular, Itanium ABI will
+  // allocate a primary base first.
+  // Since we exclude empty subobjects, the objects are not overlapping and
+  // their offsets are unique.
+  llvm::sort(Fields,
+ [](const TBAAStructField &A, const TBAAStructField &B) {
+   return A.Offset < B.Offset;
+ });
+}
 for (FieldDecl *Field : RD->fields()) {
   if (Field->isZeroSize(Context) || Field->isUnnamedBitfield())
 continue;

diff  --git a/clang/test/CodeGen/tbaa-class.cpp 
b/clang/test/CodeGen/tbaa-class.cpp
index 7f413a6f323c2..8e485f7c1cb8f 100644
--- a/clang/test/CodeGen/tbaa-class.cpp
+++ b/clang/test/CodeGen/tbaa-class.cpp
@@ -51,6 +51,25 @@ class StructS2 : public StructS
uint32_t f32_2;
 };
 
+class StructT {
+public:
+  uint32_t f32_2;
+  void foo();
+};
+class StructM1 : public StructS, public StructT {
+public:
+  uint16_t f16_2;
+};
+class StructDyn {
+public:
+  uint32_t f32_2;
+  virtual void foo();
+};
+class StructM2 : public StructS, public StructDyn {
+public:
+  uint16_t f16_2;
+};
+
 uint32_t g(uint32_t *s, StructA *A, uint64_t count) {
 // CHECK-LABEL: define{{.*}} i32 @_Z1g
 // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]]
@@ -199,6 +218,30 @@ uint32_t g12(StructC *C, StructD *D, uint64_t count) {
   return b1->a.f32;
 }
 
+uint32_t g13(StructM1 *M, StructS *S) {
+  // CHECK-LABEL: define{{.*}} i32 @_Z3g13
+  // CHECK: store i16 1, i16* %{{.*}}, align 4, !tbaa [[TAG_i16]]
+  // CHECK: store i16 4, i16* %{{.*}}, align 4, !tbaa [[TAG_i16]]
+  // PATH-LABEL: define{{.*}} i32 @_Z3g13
+  // PATH: store i16 1, i16* %{{.*}}, align 4, !tbaa [[TAG_S_f16]]
+  // PATH: store i16 4, i16* %{{.*}}, align 4, !tbaa [[TAG_M1_f16_2:!.*]]
+  S->f16 = 1;
+  M->f16_2 = 4;
+  return S->f16;
+}
+
+uint32_t g14(StructM2 *M, StructS *S) {
+  // CHECK-LABEL: define{{.*}} i32 @_Z3g14
+  // CHECK: store i16 1, i16* %{{.*}}, align 4, !tbaa [[TAG_i16]]
+  // CHECK: store i16 4, i16* %{{.*}}, align 4, !tbaa [[TAG_i16]]
+  // PATH-LABEL: define{{.*}} i32 @_Z3g14
+  // PATH: store i16 1, i16* %{{.*}}, align 4, !tbaa [[TAG_S_f16]]
+  // PATH: store i16 4, i16* %{{.*}},

[clang] 2b9a834 - [InlineFunction] Use llvm.experimental.noalias.scope.decl for noalias arguments.

2021-01-23 Thread Jeroen Dobbelaere via cfe-commits

Author: Jeroen Dobbelaere
Date: 2021-01-23T12:10:57+01:00
New Revision: 2b9a834c43cb1f93d33958c14b695896bb4e9c1e

URL: 
https://github.com/llvm/llvm-project/commit/2b9a834c43cb1f93d33958c14b695896bb4e9c1e
DIFF: 
https://github.com/llvm/llvm-project/commit/2b9a834c43cb1f93d33958c14b695896bb4e9c1e.diff

LOG: [InlineFunction] Use llvm.experimental.noalias.scope.decl for noalias 
arguments.

Insert a llvm.experimental.noalias.scope.decl intrinsic that identifies where a 
noalias argument was inlined.

This patch includes some refactorings from D90104.

Reviewed By: nikic

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

Added: 
llvm/test/Transforms/Inline/noalias-calls2.ll

Modified: 
clang/test/CodeGen/aarch64-ls64.c
llvm/lib/Transforms/Utils/InlineFunction.cpp
llvm/test/Transforms/Coroutines/ArgAddr.ll
llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll
llvm/test/Transforms/Coroutines/coro-retcon-value.ll
llvm/test/Transforms/Coroutines/coro-retcon.ll
llvm/test/Transforms/Coroutines/ex2.ll
llvm/test/Transforms/Coroutines/ex3.ll
llvm/test/Transforms/Coroutines/ex4.ll
llvm/test/Transforms/Inline/launder.invariant.group.ll
llvm/test/Transforms/Inline/noalias-calls-always.ll
llvm/test/Transforms/Inline/noalias-calls.ll
llvm/test/Transforms/Inline/noalias-cs.ll
llvm/test/Transforms/Inline/noalias.ll
llvm/test/Transforms/Inline/noalias2.ll
llvm/test/Transforms/PhaseOrdering/inlining-alignment-assumptions.ll
llvm/test/Transforms/PhaseOrdering/instcombine-sroa-inttoptr.ll
llvm/test/Transforms/PhaseOrdering/pr39282.ll

Removed: 




diff  --git a/clang/test/CodeGen/aarch64-ls64.c 
b/clang/test/CodeGen/aarch64-ls64.c
index 77e4b41fbd58..17fce0094ac9 100644
--- a/clang/test/CodeGen/aarch64-ls64.c
+++ b/clang/test/CodeGen/aarch64-ls64.c
@@ -21,6 +21,7 @@ uint64_t status;
 // CHECK-NEXT:[[__ADDR_ADDR_I:%.*]] = alloca i8*, align 8
 // CHECK-NEXT:[[REF_TMP:%.*]] = alloca [[STRUCT_DATA512_T:%.*]], align 8
 // CHECK-NEXT:[[TMP0:%.*]] = load i8*, i8** @addr, align 8
+// CHECK-NEXT:call void @llvm.experimental.noalias.scope.decl(metadata !6)
 // CHECK-NEXT:store i8* [[TMP0]], i8** [[__ADDR_ADDR_I]], align 8, 
!noalias !6
 // CHECK-NEXT:[[TMP1:%.*]] = load i8*, i8** [[__ADDR_ADDR_I]], align 8, 
!noalias !6
 // CHECK-NEXT:[[VAL_I:%.*]] = getelementptr inbounds [[STRUCT_DATA512_T]], 
%struct.data512_t* [[REF_TMP]], i32 0, i32 0

diff  --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp 
b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index 65bf6a3b32dc..abdd2b2361b7 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -79,6 +79,12 @@ EnableNoAliasConversion("enable-noalias-to-md-conversion", 
cl::init(true),
   cl::Hidden,
   cl::desc("Convert noalias attributes to metadata during inlining."));
 
+static cl::opt
+UseNoAliasIntrinsic("use-noalias-intrinsic-during-inlining", cl::Hidden,
+cl::ZeroOrMore, cl::init(true),
+cl::desc("Use the llvm.experimental.noalias.scope.decl 
"
+ "intrinsic during inlining."));
+
 // Disabled by default, because the added alignment assumptions may increase
 // compile-time and block optimizations. This option is not suitable for use
 // with frontends that emit comprehensive parameter alignment annotations.
@@ -821,91 +827,119 @@ static void PropagateCallSiteMetadata(CallBase &CB, 
ValueToValueMapTy &VMap) {
   }
 }
 
-/// When inlining a function that contains noalias scope metadata,
-/// this metadata needs to be cloned so that the inlined blocks
-/// have 
diff erent "unique scopes" at every call site. Were this not done, then
-/// aliasing scopes from a function inlined into a caller multiple times could
-/// not be 
diff erentiated (and this would lead to miscompiles because the
-/// non-aliasing property communicated by the metadata could have
-/// call-site-specific control dependencies).
-static void CloneAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap) {
-  const Function *CalledFunc = CB.getCalledFunction();
+/// Utility for cloning !noalias and !alias.scope metadata. When a code region
+/// using scoped alias metadata is inlined, the aliasing relationships may not
+/// hold between the two version. It is necessary to create a deep clone of the
+/// metadata, putting the two versions in separate scope domains.
+class ScopedAliasMetadataDeepCloner {
+  using MetadataMap = DenseMap;
   SetVector MD;
-
-  // Note: We could only clone the metadata if it is already used in the
-  // caller. I'm omitting that check here because it might confuse
-  // inter-procedural alias analysis passes. We can revisit this if it becomes
-  // an efficiency or overhead problem.
-
-  for (const BasicBlock &I : *CalledFunc)
-for (const Instruction &J : I) {

[clang] 46757cc - [clang] functions with the 'const' or 'pure' attribute must always return.

2021-02-18 Thread Jeroen Dobbelaere via cfe-commits

Author: Jeroen Dobbelaere
Date: 2021-02-18T17:29:46+01:00
New Revision: 46757ccb49ab88da54ca8ddd43665d5255ee80f7

URL: 
https://github.com/llvm/llvm-project/commit/46757ccb49ab88da54ca8ddd43665d5255ee80f7
DIFF: 
https://github.com/llvm/llvm-project/commit/46757ccb49ab88da54ca8ddd43665d5255ee80f7.diff

LOG: [clang] functions with the 'const' or 'pure' attribute must always return.

As described in
* 
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute
* 
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-const-function-attribute

An `__attribute__((pure))` function must always return, as well as an 
`__attribute__((const))` function.

Reviewed By: jdoerfert

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

Added: 


Modified: 
clang/lib/CodeGen/CGCall.cpp
clang/test/CodeGen/complex-builtins.c
clang/test/CodeGen/complex-libcalls.c
clang/test/CodeGen/function-attributes.c
clang/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp
clang/test/Sema/libbuiltins-ctype-powerpc64.c
clang/test/Sema/libbuiltins-ctype-x86_64.c

Removed: 




diff  --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 405b4d2e1980..992e87319943 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1994,9 +1994,14 @@ void CodeGenModule::ConstructAttributeList(
 if (TargetDecl->hasAttr()) {
   FuncAttrs.addAttribute(llvm::Attribute::ReadNone);
   FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
+  // gcc specifies that 'const' functions have greater restrictions than
+  // 'pure' functions, so they also cannot have infinite loops.
+  FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
 } else if (TargetDecl->hasAttr()) {
   FuncAttrs.addAttribute(llvm::Attribute::ReadOnly);
   FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
+  // gcc specifies that 'pure' functions cannot have infinite loops.
+  FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
 } else if (TargetDecl->hasAttr()) {
   FuncAttrs.addAttribute(llvm::Attribute::ArgMemOnly);
   FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);

diff  --git a/clang/test/CodeGen/complex-builtins.c 
b/clang/test/CodeGen/complex-builtins.c
index 96c0e7117016..6fea8a9f028c 100644
--- a/clang/test/CodeGen/complex-builtins.c
+++ b/clang/test/CodeGen/complex-builtins.c
@@ -133,7 +133,7 @@ void foo(float f) {
 // NO__ERRNO: declare { x86_fp80, x86_fp80 } @cprojl({ x86_fp80, x86_fp80 }* 
byval({ x86_fp80, x86_fp80 }) align 16) [[NOT_READNONE]]
 // HAS_ERRNO: declare { double, double } @cproj(double, double) 
[[READNONE:#[0-9]+]]
 // HAS_ERRNO: declare <2 x float> @cprojf(<2 x float>) [[READNONE]]
-// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cprojl({ x86_fp80, x86_fp80 }* 
byval({ x86_fp80, x86_fp80 }) align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cprojl({ x86_fp80, x86_fp80 }* 
byval({ x86_fp80, x86_fp80 }) align 16) [[WILLRETURN_NOT_READNONE:#[0-9]+]]
 
   __builtin_cpow(f,f);   __builtin_cpowf(f,f);  __builtin_cpowl(f,f);
 
@@ -202,3 +202,4 @@ void foo(float f) {
 
 // HAS_ERRNO: attributes [[NOT_READNONE]] = { nounwind {{.*}} }
 // HAS_ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} }
+// HAS_ERRNO: attributes [[WILLRETURN_NOT_READNONE]] = { nounwind willreturn 
{{.*}} }

diff  --git a/clang/test/CodeGen/complex-libcalls.c 
b/clang/test/CodeGen/complex-libcalls.c
index 9bd419a83821..44d6849c0a71 100644
--- a/clang/test/CodeGen/complex-libcalls.c
+++ b/clang/test/CodeGen/complex-libcalls.c
@@ -133,7 +133,7 @@ void foo(float f) {
 // NO__ERRNO: declare { x86_fp80, x86_fp80 } @cprojl({ x86_fp80, x86_fp80 }* 
byval({ x86_fp80, x86_fp80 }) align 16) [[NOT_READNONE]]
 // HAS_ERRNO: declare { double, double } @cproj(double, double) 
[[READNONE:#[0-9]+]]
 // HAS_ERRNO: declare <2 x float> @cprojf(<2 x float>) [[READNONE]]
-// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cprojl({ x86_fp80, x86_fp80 }* 
byval({ x86_fp80, x86_fp80 }) align 16) [[NOT_READNONE]]
+// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cprojl({ x86_fp80, x86_fp80 }* 
byval({ x86_fp80, x86_fp80 }) align 16) [[WILLRETURN_NOT_READNONE:#[0-9]+]]
 
   cpow(f,f);   cpowf(f,f);  cpowl(f,f);
 
@@ -202,3 +202,4 @@ void foo(float f) {
 
 // HAS_ERRNO: attributes [[NOT_READNONE]] = { nounwind {{.*}} }
 // HAS_ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} }
+// HAS_ERRNO: attributes [[WILLRETURN_NOT_READNONE]] = { nounwind willreturn 
{{.*}} }

diff  --git a/clang/test/CodeGen/function-attributes.c 
b/clang/test/CodeGen/function-attributes.c
index ffb86a6cd272..f14f24801006 100644
--- a/clang/test/CodeGen/function-attributes.c
+++ b/clang/test/CodeGen/function-attributes.c
@@ -115,5 +115,5 @@ void f20(void) {
 // CHECK: attributes [[SR]] = { nounwind optsize{{.*}} "stackrealign"{{.*}} }
 // CHECK: 

[clang] 4d8871a - PR50767: clear non-distinct debuginfo for function with nodebug definition after undecorated declaration

2021-06-29 Thread Jeroen Dobbelaere via cfe-commits

Author: Bruno De Fraine
Date: 2021-06-29T10:26:45+02:00
New Revision: 4d8871a898b30f11c905b27954c18d826c0953c9

URL: 
https://github.com/llvm/llvm-project/commit/4d8871a898b30f11c905b27954c18d826c0953c9
DIFF: 
https://github.com/llvm/llvm-project/commit/4d8871a898b30f11c905b27954c18d826c0953c9.diff

LOG: PR50767: clear non-distinct debuginfo for function with nodebug definition 
after undecorated declaration

Fix suggested by Yuanfang Chen:

Non-distinct debuginfo is attached to the function due to the undecorated 
declaration. Later, when seeing the function definition and `nodebug` 
attribute, the non-distinct debuginfo should be cleared.

Reviewed By: dblaikie

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

Added: 
clang/test/CodeGen/attr-nodebug2.c

Modified: 
clang/lib/CodeGen/CodeGenFunction.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CodeGenFunction.cpp 
b/clang/lib/CodeGen/CodeGenFunction.cpp
index 0ca94657e815..578b8a811817 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1304,8 +1304,14 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, 
llvm::Function *Fn,
   QualType ResTy = BuildFunctionArgList(GD, Args);
 
   // Check if we should generate debug info for this function.
-  if (FD->hasAttr())
-DebugInfo = nullptr; // disable debug info indefinitely for this function
+  if (FD->hasAttr()) {
+// Clear non-distinct debug info that was possibly attached to the function
+// due to an earlier declaration without the nodebug attribute
+if (Fn)
+  Fn->setSubprogram(nullptr);
+// Disable debug info indefinitely for this function
+DebugInfo = nullptr;
+  }
 
   // The function might not have a body if we're generating thunks for a
   // function declaration.

diff  --git a/clang/test/CodeGen/attr-nodebug2.c 
b/clang/test/CodeGen/attr-nodebug2.c
new file mode 100644
index ..fd6eca1f7432
--- /dev/null
+++ b/clang/test/CodeGen/attr-nodebug2.c
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -x c -debug-info-kind=limited -debugger-tuning=gdb 
-dwarf-version=4 -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -x c++ -debug-info-kind=limited -debugger-tuning=gdb 
-dwarf-version=4 -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void t1();
+
+void use() { t1(); }
+
+__attribute__((nodebug)) void t1() {
+  int a = 10;
+  a++;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+// CHECK-LABEL: define{{.*}} void @use()
+// CHECK-SAME:  !dbg
+// CHECK-SAME:  {
+// CHECK:   !dbg
+// CHECK:   }
+
+// PR50767 Function __attribute__((nodebug)) inconsistency causes crash
+// illegal (non-distinct) !dbg metadata was being added to _Z2t1v definition
+
+// CHECK-LABEL: define{{.*}} void @t1()
+// CHECK-NOT:   !dbg
+// CHECK-SAME:  {
+// CHECK-NOT:   !dbg
+// CHECK:   }



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 0c047a8 - [Sema] check PseudoObject when rebuilding CXXOperatorCallExpr in template instantiation

2021-12-01 Thread Jeroen Dobbelaere via cfe-commits

Author: Jeroen Dobbelaere
Date: 2021-12-01T11:02:28+01:00
New Revision: 0c047a8e13320fb8e9dabbf7a3c6a00fe81198c7

URL: 
https://github.com/llvm/llvm-project/commit/0c047a8e13320fb8e9dabbf7a3c6a00fe81198c7
DIFF: 
https://github.com/llvm/llvm-project/commit/0c047a8e13320fb8e9dabbf7a3c6a00fe81198c7.diff

LOG: [Sema] check PseudoObject when rebuilding CXXOperatorCallExpr in template 
instantiation

The invocation of a unary or binary operator for type-dependent expressions is 
represented as a CXXOperatorCallExpr. Upon template instantiation, 
TreeTransform::RebuildCXXOperatorCallExpr checks for the case of an overloaded 
operator, but not for a (non-ObjC) PseudoObject, and will directly create a 
UnaryOperator or BinaryOperator.

Generalizing commit 0f99537ecac40 from @akyrtzi to handle non-ObjC pseudo 
objects (and also handle the case of unary pseudo object inc/dec).

This fixes https://bugs.llvm.org/show_bug.cgi?id=51855

Reviewed By: rnk

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

Added: 
clang/test/SemaCXX/PR51855.cpp

Modified: 
clang/lib/Sema/TreeTransform.h
clang/test/SemaObjCXX/instantiate-property-access.mm

Removed: 




diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 7f3326c13263f..152feac4041c4 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -14630,18 +14630,28 @@ 
TreeTransform::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
   Expr *Callee = OrigCallee->IgnoreParenCasts();
   bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
 
-  if (First->getObjectKind() == OK_ObjCProperty) {
-BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
-if (BinaryOperator::isAssignmentOp(Opc))
-  return SemaRef.checkPseudoObjectAssignment(/*Scope=*/nullptr, OpLoc, Opc,
- First, Second);
+  if (const BuiltinType *pty = First->getType()->getAsPlaceholderType()) {
+if (Second && !isPostIncDec) {
+  BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
+  if (pty->getKind() == BuiltinType::PseudoObject &&
+  BinaryOperator::isAssignmentOp(Opc))
+return SemaRef.checkPseudoObjectAssignment(/*Scope=*/nullptr, OpLoc,
+   Opc, First, Second);
+} else {
+  UnaryOperatorKind Opc =
+  UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
+  if (pty->getKind() == BuiltinType::PseudoObject &&
+  UnaryOperator::isIncrementDecrementOp(Opc))
+return SemaRef.checkPseudoObjectIncDec(/*Scope=*/nullptr, OpLoc, Opc,
+   First);
+}
 ExprResult Result = SemaRef.CheckPlaceholderExpr(First);
 if (Result.isInvalid())
   return ExprError();
 First = Result.get();
   }
 
-  if (Second && Second->getObjectKind() == OK_ObjCProperty) {
+  if (Second && Second->getType()->isPlaceholderType()) {
 ExprResult Result = SemaRef.CheckPlaceholderExpr(Second);
 if (Result.isInvalid())
   return ExprError();

diff  --git a/clang/test/SemaCXX/PR51855.cpp b/clang/test/SemaCXX/PR51855.cpp
new file mode 100644
index 0..6ace3bf085aa5
--- /dev/null
+++ b/clang/test/SemaCXX/PR51855.cpp
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -S -triple %itanium_abi_triple -fms-extensions -emit-llvm 
%s -o - | FileCheck %s
+
+struct F {};
+
+F operator*=(F &lhs, int rhs);
+
+F operator++(F &lhs);
+
+struct S {
+  short _m;
+  S(short _m) : _m(_m) {}
+
+  void putM(short rhs) { _m = rhs; }
+  short getM() { return _m; }
+
+  __declspec(property(get = getM, put = putM)) short theData;
+};
+
+int test1a(int i) {
+  S tmp(i);
+  tmp.theData *= 2;
+  return tmp.theData;
+}
+
+// CHECK-LABEL: define {{.*}} @_Z6test1ai(
+// CHECK: call {{.*}} @_ZN1SC1Es(
+// CHECK: call {{.*}} @_ZN1S4getMEv(
+// CHECK: call {{.*}} @_ZN1S4putMEs(
+// CHECK: call {{.*}} @_ZN1S4getMEv(
+
+template 
+int test1b(int i) {
+  T tmp(i);
+  tmp.theData *= 2;
+  return tmp.theData;
+}
+
+template int test1b(int);
+
+// CHECK-LABEL: define {{.*}} @_Z6test1bI1SEii(
+// CHECK: call {{.*}} @_ZN1SC1Es(
+// CHECK: call {{.*}} @_ZN1S4getMEv(
+// CHECK: call {{.*}} @_ZN1S4putMEs(
+// CHECK: call {{.*}} @_ZN1S4getMEv(
+
+int test2a(int i) {
+  S tmp(i);
+  ++tmp.theData;
+  return tmp.theData;
+}
+
+// CHECK-LABEL: define {{.*}} i32 @_Z6test2ai(
+// CHECK: call {{.*}} @_ZN1SC1Es(
+// CHECK: call {{.*}} @_ZN1S4getMEv(
+// CHECK: call {{.*}} @_ZN1S4putMEs(
+// CHECK: call {{.*}} @_ZN1S4getMEv(
+
+template 
+int test2b(int i) {
+  T tmp(i);
+  ++tmp.theData;
+  return tmp.theData;
+}
+
+template int test2b(int);
+
+// CHECK-LABEL: define {{.*}} i32 @_Z6test2bI1SEii(
+// CHECK: call void @_ZN1SC1Es(
+// CHECK: call {{.*}} @_ZN1S4getMEv(
+// CHECK: call {{.*}} @_ZN1S4putMEs(
+// CHECK: call {{.*}} @_ZN1S4getMEv(

diff  --git a/clang/test/Sema

[clang] a4fbae2 - Revert "[Sema] check PseudoObject when rebuilding CXXOperatorCallExpr in template instantiation"

2021-12-01 Thread Jeroen Dobbelaere via cfe-commits

Author: Jeroen Dobbelaere
Date: 2021-12-01T11:18:30+01:00
New Revision: a4fbae268f67a6737b86c47f555f95a4a44462d2

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

LOG: Revert "[Sema] check PseudoObject when rebuilding CXXOperatorCallExpr in 
template instantiation"

This reverts commit 0c047a8e13320fb8e9dabbf7a3c6a00fe81198c7.

A number of buildbots started failing. Reverting for now.

Added: 


Modified: 
clang/lib/Sema/TreeTransform.h
clang/test/SemaObjCXX/instantiate-property-access.mm

Removed: 
clang/test/SemaCXX/PR51855.cpp



diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 152feac4041c4..7f3326c13263f 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -14630,28 +14630,18 @@ 
TreeTransform::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
   Expr *Callee = OrigCallee->IgnoreParenCasts();
   bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
 
-  if (const BuiltinType *pty = First->getType()->getAsPlaceholderType()) {
-if (Second && !isPostIncDec) {
-  BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
-  if (pty->getKind() == BuiltinType::PseudoObject &&
-  BinaryOperator::isAssignmentOp(Opc))
-return SemaRef.checkPseudoObjectAssignment(/*Scope=*/nullptr, OpLoc,
-   Opc, First, Second);
-} else {
-  UnaryOperatorKind Opc =
-  UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
-  if (pty->getKind() == BuiltinType::PseudoObject &&
-  UnaryOperator::isIncrementDecrementOp(Opc))
-return SemaRef.checkPseudoObjectIncDec(/*Scope=*/nullptr, OpLoc, Opc,
-   First);
-}
+  if (First->getObjectKind() == OK_ObjCProperty) {
+BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
+if (BinaryOperator::isAssignmentOp(Opc))
+  return SemaRef.checkPseudoObjectAssignment(/*Scope=*/nullptr, OpLoc, Opc,
+ First, Second);
 ExprResult Result = SemaRef.CheckPlaceholderExpr(First);
 if (Result.isInvalid())
   return ExprError();
 First = Result.get();
   }
 
-  if (Second && Second->getType()->isPlaceholderType()) {
+  if (Second && Second->getObjectKind() == OK_ObjCProperty) {
 ExprResult Result = SemaRef.CheckPlaceholderExpr(Second);
 if (Result.isInvalid())
   return ExprError();

diff  --git a/clang/test/SemaCXX/PR51855.cpp b/clang/test/SemaCXX/PR51855.cpp
deleted file mode 100644
index 6ace3bf085aa5..0
--- a/clang/test/SemaCXX/PR51855.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-// RUN: %clang_cc1 -S -triple %itanium_abi_triple -fms-extensions -emit-llvm 
%s -o - | FileCheck %s
-
-struct F {};
-
-F operator*=(F &lhs, int rhs);
-
-F operator++(F &lhs);
-
-struct S {
-  short _m;
-  S(short _m) : _m(_m) {}
-
-  void putM(short rhs) { _m = rhs; }
-  short getM() { return _m; }
-
-  __declspec(property(get = getM, put = putM)) short theData;
-};
-
-int test1a(int i) {
-  S tmp(i);
-  tmp.theData *= 2;
-  return tmp.theData;
-}
-
-// CHECK-LABEL: define {{.*}} @_Z6test1ai(
-// CHECK: call {{.*}} @_ZN1SC1Es(
-// CHECK: call {{.*}} @_ZN1S4getMEv(
-// CHECK: call {{.*}} @_ZN1S4putMEs(
-// CHECK: call {{.*}} @_ZN1S4getMEv(
-
-template 
-int test1b(int i) {
-  T tmp(i);
-  tmp.theData *= 2;
-  return tmp.theData;
-}
-
-template int test1b(int);
-
-// CHECK-LABEL: define {{.*}} @_Z6test1bI1SEii(
-// CHECK: call {{.*}} @_ZN1SC1Es(
-// CHECK: call {{.*}} @_ZN1S4getMEv(
-// CHECK: call {{.*}} @_ZN1S4putMEs(
-// CHECK: call {{.*}} @_ZN1S4getMEv(
-
-int test2a(int i) {
-  S tmp(i);
-  ++tmp.theData;
-  return tmp.theData;
-}
-
-// CHECK-LABEL: define {{.*}} i32 @_Z6test2ai(
-// CHECK: call {{.*}} @_ZN1SC1Es(
-// CHECK: call {{.*}} @_ZN1S4getMEv(
-// CHECK: call {{.*}} @_ZN1S4putMEs(
-// CHECK: call {{.*}} @_ZN1S4getMEv(
-
-template 
-int test2b(int i) {
-  T tmp(i);
-  ++tmp.theData;
-  return tmp.theData;
-}
-
-template int test2b(int);
-
-// CHECK-LABEL: define {{.*}} i32 @_Z6test2bI1SEii(
-// CHECK: call void @_ZN1SC1Es(
-// CHECK: call {{.*}} @_ZN1S4getMEv(
-// CHECK: call {{.*}} @_ZN1S4putMEs(
-// CHECK: call {{.*}} @_ZN1S4getMEv(

diff  --git a/clang/test/SemaObjCXX/instantiate-property-access.mm 
b/clang/test/SemaObjCXX/instantiate-property-access.mm
index e792825facf46..8d5c201a80a19 100644
--- a/clang/test/SemaObjCXX/instantiate-property-access.mm
+++ b/clang/test/SemaObjCXX/instantiate-property-access.mm
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -fsyntax-only -DDEPENDENT -verify %s
 // expected-no-diagnostics
 
 class C {};
@@ -10,10 +9,6 @@
 
 C operator += (C c1, C c2);
 
-C operator+

[clang] cdc59e2 - [tbaa] Handle base classes in struct tbaa

2022-06-23 Thread Jeroen Dobbelaere via cfe-commits

Author: Bruno De Fraine
Date: 2022-06-23T13:39:49+02:00
New Revision: cdc59e2202c11a6a5dfd2ec83531523c58eaae45

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

LOG: [tbaa] Handle base classes in struct tbaa

This is a fix for the miscompilation reported in 
https://github.com/llvm/llvm-project/issues/55384

Not adding a new test case since existing test cases already cover base classes 
(including new-struct-path tbaa).

Reviewed By: jeroen.dobbelaere

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

Added: 


Modified: 
clang/lib/CodeGen/CodeGenTBAA.cpp
clang/test/CodeGen/tbaa-class.cpp
clang/unittests/CodeGen/TBAAMetadataTest.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CodeGenTBAA.cpp 
b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 95763d8e18b70..2904bd5a244fe 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -336,6 +336,30 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const 
Type *Ty) {
 const RecordDecl *RD = TTy->getDecl()->getDefinition();
 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
 SmallVector Fields;
+if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) {
+  // Handle C++ base classes. Non-virtual bases can treated a a kind of
+  // field. Virtual bases are more complex and omitted, but avoid an
+  // incomplete view for NewStructPathTBAA.
+  if (CodeGenOpts.NewStructPathTBAA && CXXRD->getNumVBases() != 0)
+return BaseTypeMetadataCache[Ty] = nullptr;
+  for (const CXXBaseSpecifier &B : CXXRD->bases()) {
+if (B.isVirtual())
+  continue;
+QualType BaseQTy = B.getType();
+const CXXRecordDecl *BaseRD = BaseQTy->getAsCXXRecordDecl();
+if (BaseRD->isEmpty())
+  continue;
+llvm::MDNode *TypeNode = isValidBaseType(BaseQTy)
+ ? getBaseTypeInfo(BaseQTy)
+ : getTypeInfo(BaseQTy);
+if (!TypeNode)
+  return BaseTypeMetadataCache[Ty] = nullptr;
+uint64_t Offset = Layout.getBaseClassOffset(BaseRD).getQuantity();
+uint64_t Size = Context.getTypeSizeInChars(BaseQTy).getQuantity();
+Fields.push_back(
+llvm::MDBuilder::TBAAStructField(Offset, Size, TypeNode));
+  }
+}
 for (FieldDecl *Field : RD->fields()) {
   if (Field->isZeroSize(Context) || Field->isUnnamedBitfield())
 continue;

diff  --git a/clang/test/CodeGen/tbaa-class.cpp 
b/clang/test/CodeGen/tbaa-class.cpp
index 7f413a6f323c2..38558b0415a7a 100644
--- a/clang/test/CodeGen/tbaa-class.cpp
+++ b/clang/test/CodeGen/tbaa-class.cpp
@@ -222,7 +222,7 @@ uint32_t g12(StructC *C, StructD *D, uint64_t count) {
 // OLD-PATH: [[TYPE_S]] = !{!"_ZTS7StructS", [[TYPE_SHORT]], i64 0, 
[[TYPE_INT]], i64 4}
 // OLD-PATH: [[TAG_S_f16]] = !{[[TYPE_S]], [[TYPE_SHORT]], i64 0}
 // OLD-PATH: [[TAG_S2_f32_2]] = !{[[TYPE_S2:!.*]], [[TYPE_INT]], i64 12}
-// OLD-PATH: [[TYPE_S2]] = !{!"_ZTS8StructS2", [[TYPE_SHORT]], i64 8, 
[[TYPE_INT]], i64 12}
+// OLD-PATH: [[TYPE_S2]] = !{!"_ZTS8StructS2", [[TYPE_S]], i64 0, 
[[TYPE_SHORT]], i64 8, [[TYPE_INT]], i64 12}
 // OLD-PATH: [[TAG_C_b_a_f32]] = !{[[TYPE_C:!.*]], [[TYPE_INT]], i64 12}
 // OLD-PATH: [[TYPE_C]] = !{!"_ZTS7StructC", [[TYPE_SHORT]], i64 0, 
[[TYPE_B]], i64 4, [[TYPE_INT]], i64 28}
 // OLD-PATH: [[TAG_D_b_a_f32]] = !{[[TYPE_D:!.*]], [[TYPE_INT]], i64 12}
@@ -244,7 +244,7 @@ uint32_t g12(StructC *C, StructD *D, uint64_t count) {
 // NEW-PATH: [[TYPE_S]] = !{[[TYPE_CHAR]], i64 8, !"_ZTS7StructS", 
[[TYPE_SHORT]], i64 0, i64 2, [[TYPE_INT]], i64 4, i64 4}
 // NEW-PATH: [[TAG_S_f16]] = !{[[TYPE_S]], [[TYPE_SHORT]], i64 0, i64 2}
 // NEW-PATH: [[TAG_S2_f32_2]] = !{[[TYPE_S2:!.*]], [[TYPE_INT]], i64 12, i64 4}
-// NEW-PATH: [[TYPE_S2]] = !{[[TYPE_CHAR]], i64 16, !"_ZTS8StructS2", 
[[TYPE_SHORT]], i64 8, i64 2, [[TYPE_INT]], i64 12, i64 4}
+// NEW-PATH: [[TYPE_S2]] = !{[[TYPE_CHAR]], i64 16, !"_ZTS8StructS2", 
[[TYPE_S]], i64 0, i64 8, [[TYPE_SHORT]], i64 8, i64 2, [[TYPE_INT]], i64 12, 
i64 4}
 // NEW-PATH: [[TAG_C_b_a_f32]] = !{[[TYPE_C:!.*]], [[TYPE_INT]], i64 12, i64 4}
 // NEW-PATH: [[TYPE_C]] = !{[[TYPE_CHAR]], i64 32, !"_ZTS7StructC", 
[[TYPE_SHORT]], i64 0, i64 2, [[TYPE_B]], i64 4, i64 24, [[TYPE_INT]], i64 28, 
i64 4}
 // NEW-PATH: [[TAG_D_b_a_f32]] = !{[[TYPE_D:!.*]], [[TYPE_INT]], i64 12, i64 4}

diff  --git a/clang/unittests/CodeGen/TBAAMetadataTest.cpp 
b/clang/unittests/CodeGen/TBAAMetadataTest.cpp
index 149a8e074b692..2919a35c8cedf 100644
--- a/clang/unittests/CodeGen/TBAAMetadataTest.cpp
+++ b/clang/unittests/CodeGen/TBAAMetadataTest.cpp
@@ -968,13 +968,10 @@ TEST(TBAAMetadataTest, BaseClass) {
   MConstInt(0)),
 MConstInt(0));
 
-  auto ClassDerived = MMTup

[clang] 8999b74 - Revert "[tbaa] Handle base classes in struct tbaa"

2022-06-23 Thread Jeroen Dobbelaere via cfe-commits

Author: Jeroen Dobbelaere
Date: 2022-06-23T14:18:49+02:00
New Revision: 8999b745bc4ecae5ac74f5c4d06f40e317ddb12c

URL: 
https://github.com/llvm/llvm-project/commit/8999b745bc4ecae5ac74f5c4d06f40e317ddb12c
DIFF: 
https://github.com/llvm/llvm-project/commit/8999b745bc4ecae5ac74f5c4d06f40e317ddb12c.diff

LOG: Revert "[tbaa] Handle base classes in struct tbaa"

This reverts commit cdc59e2202c11a6a5dfd2ec83531523c58eaae45.

The Verifier finds a problem in a stage2 build. Reverting so Bruno can 
investigate.

Added: 


Modified: 
clang/lib/CodeGen/CodeGenTBAA.cpp
clang/test/CodeGen/tbaa-class.cpp
clang/unittests/CodeGen/TBAAMetadataTest.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CodeGenTBAA.cpp 
b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 2904bd5a244f..95763d8e18b7 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -336,30 +336,6 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const 
Type *Ty) {
 const RecordDecl *RD = TTy->getDecl()->getDefinition();
 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
 SmallVector Fields;
-if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) {
-  // Handle C++ base classes. Non-virtual bases can treated a a kind of
-  // field. Virtual bases are more complex and omitted, but avoid an
-  // incomplete view for NewStructPathTBAA.
-  if (CodeGenOpts.NewStructPathTBAA && CXXRD->getNumVBases() != 0)
-return BaseTypeMetadataCache[Ty] = nullptr;
-  for (const CXXBaseSpecifier &B : CXXRD->bases()) {
-if (B.isVirtual())
-  continue;
-QualType BaseQTy = B.getType();
-const CXXRecordDecl *BaseRD = BaseQTy->getAsCXXRecordDecl();
-if (BaseRD->isEmpty())
-  continue;
-llvm::MDNode *TypeNode = isValidBaseType(BaseQTy)
- ? getBaseTypeInfo(BaseQTy)
- : getTypeInfo(BaseQTy);
-if (!TypeNode)
-  return BaseTypeMetadataCache[Ty] = nullptr;
-uint64_t Offset = Layout.getBaseClassOffset(BaseRD).getQuantity();
-uint64_t Size = Context.getTypeSizeInChars(BaseQTy).getQuantity();
-Fields.push_back(
-llvm::MDBuilder::TBAAStructField(Offset, Size, TypeNode));
-  }
-}
 for (FieldDecl *Field : RD->fields()) {
   if (Field->isZeroSize(Context) || Field->isUnnamedBitfield())
 continue;

diff  --git a/clang/test/CodeGen/tbaa-class.cpp 
b/clang/test/CodeGen/tbaa-class.cpp
index 38558b0415a7..7f413a6f323c 100644
--- a/clang/test/CodeGen/tbaa-class.cpp
+++ b/clang/test/CodeGen/tbaa-class.cpp
@@ -222,7 +222,7 @@ uint32_t g12(StructC *C, StructD *D, uint64_t count) {
 // OLD-PATH: [[TYPE_S]] = !{!"_ZTS7StructS", [[TYPE_SHORT]], i64 0, 
[[TYPE_INT]], i64 4}
 // OLD-PATH: [[TAG_S_f16]] = !{[[TYPE_S]], [[TYPE_SHORT]], i64 0}
 // OLD-PATH: [[TAG_S2_f32_2]] = !{[[TYPE_S2:!.*]], [[TYPE_INT]], i64 12}
-// OLD-PATH: [[TYPE_S2]] = !{!"_ZTS8StructS2", [[TYPE_S]], i64 0, 
[[TYPE_SHORT]], i64 8, [[TYPE_INT]], i64 12}
+// OLD-PATH: [[TYPE_S2]] = !{!"_ZTS8StructS2", [[TYPE_SHORT]], i64 8, 
[[TYPE_INT]], i64 12}
 // OLD-PATH: [[TAG_C_b_a_f32]] = !{[[TYPE_C:!.*]], [[TYPE_INT]], i64 12}
 // OLD-PATH: [[TYPE_C]] = !{!"_ZTS7StructC", [[TYPE_SHORT]], i64 0, 
[[TYPE_B]], i64 4, [[TYPE_INT]], i64 28}
 // OLD-PATH: [[TAG_D_b_a_f32]] = !{[[TYPE_D:!.*]], [[TYPE_INT]], i64 12}
@@ -244,7 +244,7 @@ uint32_t g12(StructC *C, StructD *D, uint64_t count) {
 // NEW-PATH: [[TYPE_S]] = !{[[TYPE_CHAR]], i64 8, !"_ZTS7StructS", 
[[TYPE_SHORT]], i64 0, i64 2, [[TYPE_INT]], i64 4, i64 4}
 // NEW-PATH: [[TAG_S_f16]] = !{[[TYPE_S]], [[TYPE_SHORT]], i64 0, i64 2}
 // NEW-PATH: [[TAG_S2_f32_2]] = !{[[TYPE_S2:!.*]], [[TYPE_INT]], i64 12, i64 4}
-// NEW-PATH: [[TYPE_S2]] = !{[[TYPE_CHAR]], i64 16, !"_ZTS8StructS2", 
[[TYPE_S]], i64 0, i64 8, [[TYPE_SHORT]], i64 8, i64 2, [[TYPE_INT]], i64 12, 
i64 4}
+// NEW-PATH: [[TYPE_S2]] = !{[[TYPE_CHAR]], i64 16, !"_ZTS8StructS2", 
[[TYPE_SHORT]], i64 8, i64 2, [[TYPE_INT]], i64 12, i64 4}
 // NEW-PATH: [[TAG_C_b_a_f32]] = !{[[TYPE_C:!.*]], [[TYPE_INT]], i64 12, i64 4}
 // NEW-PATH: [[TYPE_C]] = !{[[TYPE_CHAR]], i64 32, !"_ZTS7StructC", 
[[TYPE_SHORT]], i64 0, i64 2, [[TYPE_B]], i64 4, i64 24, [[TYPE_INT]], i64 28, 
i64 4}
 // NEW-PATH: [[TAG_D_b_a_f32]] = !{[[TYPE_D:!.*]], [[TYPE_INT]], i64 12, i64 4}

diff  --git a/clang/unittests/CodeGen/TBAAMetadataTest.cpp 
b/clang/unittests/CodeGen/TBAAMetadataTest.cpp
index 2919a35c8ced..149a8e074b69 100644
--- a/clang/unittests/CodeGen/TBAAMetadataTest.cpp
+++ b/clang/unittests/CodeGen/TBAAMetadataTest.cpp
@@ -968,10 +968,13 @@ TEST(TBAAMetadataTest, BaseClass) {
   MConstInt(0)),
 MConstInt(0));
 
-  auto ClassDerived =
-  MMTuple(MMString("_ZTS7Derived"), ClassBase, MConstInt(0),
-  MMTuple(MMString("short"), OmnipotentCharCXX, MConstInt(0)),
-