summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorPiotr Padlewski <piotr.padlewski@gmail.com>2017-06-01 18:39:34 +0000
committerPiotr Padlewski <piotr.padlewski@gmail.com>2017-06-01 18:39:34 +0000
commitc1d26062f7bfdc357bd05598a4b92cddc23a0fa5 (patch)
treede21403a0c8653191cbeb0eed8d4e7bbdc137e65 /clang/lib/CodeGen
parent33a1b73600d5305efd122e61926319a9db20414c (diff)
downloadbcm5719-llvm-c1d26062f7bfdc357bd05598a4b92cddc23a0fa5.tar.gz
bcm5719-llvm-c1d26062f7bfdc357bd05598a4b92cddc23a0fa5.zip
Emit invariant.group.barrier when using union field
Summary: We need to emit barrier if the union field is CXXRecordDecl because it might have vptrs. The testcode was wrongly devirtualized. It also proves that having different groups for different dynamic types is not sufficient. Reviewers: rjmccall, rsmith, mehdi_amini Subscribers: amharc, cfe-commits Differential Revision: https://reviews.llvm.org/D31830 llvm-svn: 304448
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp27
1 files changed, 27 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index b918a663ce5..6808c69cd8c 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3530,6 +3530,25 @@ static Address emitAddrOfFieldStorage(CodeGenFunction &CGF, Address base,
return CGF.Builder.CreateStructGEP(base, idx, offset, field->getName());
}
+static bool hasAnyVptr(const QualType Type, const ASTContext &Context) {
+ const auto *RD = Type.getTypePtr()->getAsCXXRecordDecl();
+ if (!RD)
+ return false;
+
+ if (RD->isDynamicClass())
+ return true;
+
+ for (const auto &Base : RD->bases())
+ if (hasAnyVptr(Base.getType(), Context))
+ return true;
+
+ for (const FieldDecl *Field : RD->fields())
+ if (hasAnyVptr(Field->getType(), Context))
+ return true;
+
+ return false;
+}
+
LValue CodeGenFunction::EmitLValueForField(LValue base,
const FieldDecl *field) {
LValueBaseInfo BaseInfo = base.getBaseInfo();
@@ -3572,6 +3591,14 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
assert(!type->isReferenceType() && "union has reference member");
// TODO: handle path-aware TBAA for union.
TBAAPath = false;
+
+ const auto FieldType = field->getType();
+ if (CGM.getCodeGenOpts().StrictVTablePointers &&
+ hasAnyVptr(FieldType, getContext()))
+ // Because unions can easily skip invariant.barriers, we need to add
+ // a barrier every time CXXRecord field with vptr is referenced.
+ addr = Address(Builder.CreateInvariantGroupBarrier(addr.getPointer()),
+ addr.getAlignment());
} else {
// For structs, we GEP to the field that the record layout suggests.
addr = emitAddrOfFieldStorage(*this, addr, field);
OpenPOWER on IntegriCloud