Index: lib/CodeGen/CGAtomic.cpp =================================================================== --- lib/CodeGen/CGAtomic.cpp +++ lib/CodeGen/CGAtomic.cpp @@ -98,7 +98,6 @@ LVal = LValue::MakeBitfield(Address(Addr, lvalue.getAlignment()), BFI, lvalue.getType(), lvalue.getBaseInfo()); - LVal.setTBAAInfo(lvalue.getTBAAInfo()); AtomicTy = C.getIntTypeForBitwidth(AtomicSizeInBits, OrigBFI.IsSigned); if (AtomicTy.isNull()) { llvm::APInt Size( @@ -205,7 +204,7 @@ addr = CGF.Builder.CreateStructGEP(addr, 0, CharUnits()); return LValue::MakeAddr(addr, getValueType(), CGF.getContext(), - LVal.getBaseInfo(), LVal.getTBAAInfo()); + LVal.getBaseInfo()); } /// \brief Emits atomic load. @@ -1691,8 +1690,6 @@ DesiredAddr, AtomicLVal.getExtVectorElts(), AtomicLVal.getType(), AtomicLVal.getBaseInfo()); } - UpdateLVal.setTBAAInfo(AtomicLVal.getTBAAInfo()); - DesiredLVal.setTBAAInfo(AtomicLVal.getTBAAInfo()); UpRVal = CGF.EmitLoadOfLValue(UpdateLVal, SourceLocation()); } // Store new value in the corresponding memory area @@ -1788,7 +1785,6 @@ DesiredAddr, AtomicLVal.getExtVectorElts(), AtomicLVal.getType(), AtomicLVal.getBaseInfo()); } - DesiredLVal.setTBAAInfo(AtomicLVal.getTBAAInfo()); // Store new value in the corresponding memory area assert(UpdateRVal.isScalar()); CGF.EmitStoreThroughLValue(UpdateRVal, DesiredLVal); Index: lib/CodeGen/CGBlocks.cpp =================================================================== --- lib/CodeGen/CGBlocks.cpp +++ lib/CodeGen/CGBlocks.cpp @@ -986,9 +986,8 @@ // FIXME: Pass a specific location for the expr init so that the store is // attributed to a reasonable location - otherwise it may be attributed to // locations of subexpressions in the initialization. - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); EmitExprAsInit(&l2r, &BlockFieldPseudoVar, - MakeAddrLValue(blockField, type, BaseInfo), + MakeAddrLValue(blockField, type, AlignmentSource::Decl), /*captured by init*/ false); } Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -412,14 +412,12 @@ // dynamic initialization or a cleanup and we can just return the address // of the temporary. if (Var->hasInitializer()) - return MakeAddrLValue(Object, M->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + return MakeAddrLValue(Object, M->getType(), AlignmentSource::Decl); Var->setInitializer(CGM.EmitNullConstant(E->getType())); } LValue RefTempDst = MakeAddrLValue(Object, M->getType(), - LValueBaseInfo(AlignmentSource::Decl, - false)); + AlignmentSource::Decl); switch (getEvaluationKind(E->getType())) { default: llvm_unreachable("expected scalar or aggregate expression"); @@ -506,8 +504,7 @@ break; case SubobjectAdjustment::FieldAdjustment: { - LValue LV = MakeAddrLValue(Object, E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + LValue LV = MakeAddrLValue(Object, E->getType(), AlignmentSource::Decl); LV = EmitLValueForField(LV, Adjustment.Field); assert(LV.isSimple() && "materialized temporary field is not a simple lvalue"); @@ -524,8 +521,7 @@ } } - return MakeAddrLValue(Object, M->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + return MakeAddrLValue(Object, M->getType(), AlignmentSource::Decl); } RValue @@ -952,7 +948,7 @@ CharUnits Align = getNaturalPointeeTypeAlignment(E->getType(), &ExpInfo); if (BaseInfo) - BaseInfo->mergeForCast(ExpInfo); + BaseInfo->mergeForCast(ExpInfo, CGM); Addr = Address(Addr.getPointer(), Align); } @@ -1174,7 +1170,7 @@ llvm::Value *V = LV.getPointer(); Scope.ForceCleanup({&V}); return LValue::MakeAddr(Address(V, LV.getAlignment()), LV.getType(), - getContext(), LV.getBaseInfo(), LV.getTBAAInfo()); + getContext(), LV.getBaseInfo()); } // FIXME: Is it possible to create an ExprWithCleanups that produces a // bitfield lvalue or some other non-simple lvalue? @@ -1374,7 +1370,7 @@ SourceLocation Loc) { return EmitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(), lvalue.getType(), Loc, lvalue.getBaseInfo(), - lvalue.getTBAAInfo(), lvalue.isNontemporal()); + lvalue.isNontemporal()); } static bool hasBooleanRepresentation(QualType Ty) { @@ -1484,7 +1480,6 @@ QualType Ty, SourceLocation Loc, LValueBaseInfo BaseInfo, - TBAAAccessInfo TBAAInfo, bool isNontemporal) { if (!CGM.getCodeGenOpts().PreserveVec3Type) { // For better performance, handle vector loads differently. @@ -1512,8 +1507,7 @@ } // Atomic operations have to be done on integral types. - LValue AtomicLValue = - LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo, TBAAInfo); + LValue AtomicLValue = LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo); if (Ty->isAtomicType() || LValueIsSuitableForInlineAtomic(AtomicLValue)) { return EmitAtomicLoad(AtomicLValue, Loc).getScalarVal(); } @@ -1525,9 +1519,7 @@ Load->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); } - if (BaseInfo.getMayAlias()) - TBAAInfo = CGM.getTBAAMayAliasAccessInfo(); - CGM.DecorateInstructionWithTBAA(Load, TBAAInfo); + CGM.DecorateInstructionWithTBAA(Load, BaseInfo.getTBAAInfo()); if (EmitScalarRangeCheck(Load, Ty, Loc)) { // In order to prevent the optimizer from throwing away the check, don't @@ -1567,7 +1559,6 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, LValueBaseInfo BaseInfo, - TBAAAccessInfo TBAAInfo, bool isInit, bool isNontemporal) { if (!CGM.getCodeGenOpts().PreserveVec3Type) { // Handle vectors differently to get better performance. @@ -1593,8 +1584,7 @@ Value = EmitToMemory(Value, Ty); - LValue AtomicLValue = - LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo, TBAAInfo); + LValue AtomicLValue = LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo); if (Ty->isAtomicType() || (!isInit && LValueIsSuitableForInlineAtomic(AtomicLValue))) { EmitAtomicStore(RValue::get(Value), AtomicLValue, isInit); @@ -1609,16 +1599,14 @@ Store->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); } - if (BaseInfo.getMayAlias()) - TBAAInfo = CGM.getTBAAMayAliasAccessInfo(); - CGM.DecorateInstructionWithTBAA(Store, TBAAInfo); + CGM.DecorateInstructionWithTBAA(Store, BaseInfo.getTBAAInfo()); } void CodeGenFunction::EmitStoreOfScalar(llvm::Value *value, LValue lvalue, bool isInit) { EmitStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(), lvalue.getType(), lvalue.getBaseInfo(), - lvalue.getTBAAInfo(), isInit, lvalue.isNontemporal()); + isInit, lvalue.isNontemporal()); } /// EmitLoadOfLValue - Given an expression that represents a value lvalue, this @@ -2148,8 +2136,7 @@ llvm::Type *RealVarTy, SourceLocation Loc) { Addr = CGF.CGM.getOpenMPRuntime().getAddrOfThreadPrivate(CGF, VD, Addr, Loc); Addr = CGF.Builder.CreateElementBitCast(Addr, RealVarTy); - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); - return CGF.MakeAddrLValue(Addr, T, BaseInfo); + return CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl); } Address CodeGenFunction::EmitLoadOfReference(Address Addr, @@ -2206,8 +2193,7 @@ if (auto RefTy = VD->getType()->getAs()) { LV = CGF.EmitLoadOfReferenceLValue(Addr, RefTy); } else { - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); - LV = CGF.MakeAddrLValue(Addr, T, BaseInfo); + LV = CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl); } setObjCGCLValueClass(CGF.getContext(), E, LV); return LV; @@ -2241,8 +2227,7 @@ const Expr *E, const FunctionDecl *FD) { llvm::Value *V = EmitFunctionDeclPointer(CGF.CGM, FD); CharUnits Alignment = CGF.getContext().getDeclAlign(FD); - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); - return CGF.MakeAddrLValue(V, E->getType(), Alignment, BaseInfo); + return CGF.MakeAddrLValue(V, E->getType(), Alignment, AlignmentSource::Decl); } static LValue EmitCapturedFieldLValue(CodeGenFunction &CGF, const FieldDecl *FD, @@ -2309,8 +2294,7 @@ // Should we be using the alignment of the constant pointer we emitted? CharUnits Alignment = getNaturalTypeAlignment(E->getType(), nullptr, /*pointee*/ true); - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); - return MakeAddrLValue(Address(Val, Alignment), T, BaseInfo); + return MakeAddrLValue(Address(Val, Alignment), T, AlignmentSource::Decl); } // Check for captured variables. @@ -2328,16 +2312,15 @@ LValue CapLVal = EmitCapturedFieldLValue(*this, CapturedStmtInfo->lookup(VD), CapturedStmtInfo->getContextValue()); - bool MayAlias = CapLVal.getBaseInfo().getMayAlias(); - return MakeAddrLValue( - Address(CapLVal.getPointer(), getContext().getDeclAlign(VD)), - CapLVal.getType(), LValueBaseInfo(AlignmentSource::Decl, MayAlias)); + LValueBaseInfo BaseInfo(AlignmentSource::Decl, CapLVal.getTBAAInfo()); + return MakeAddrLValue(Address(CapLVal.getPointer(), + getContext().getDeclAlign(VD)), + CapLVal.getType(), BaseInfo); } assert(isa(CurCodeDecl)); Address addr = GetAddrOfBlockDecl(VD, VD->hasAttr()); - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); - return MakeAddrLValue(addr, T, BaseInfo); + return MakeAddrLValue(addr, T, AlignmentSource::Decl); } } @@ -2351,8 +2334,7 @@ if (ND->hasAttr()) { const auto *VD = cast(ND); ConstantAddress Aliasee = CGM.GetWeakRefReference(VD); - return MakeAddrLValue(Aliasee, T, - LValueBaseInfo(AlignmentSource::Decl, false)); + return MakeAddrLValue(Aliasee, T, AlignmentSource::Decl); } if (const auto *VD = dyn_cast(ND)) { @@ -2398,8 +2380,7 @@ if (auto RefTy = VD->getType()->getAs()) { LV = EmitLoadOfReferenceLValue(addr, RefTy); } else { - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); - LV = MakeAddrLValue(addr, T, BaseInfo); + LV = MakeAddrLValue(addr, T, AlignmentSource::Decl); } bool isLocalStorage = VD->hasLocalStorage(); @@ -2498,14 +2479,12 @@ LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) { return MakeAddrLValue(CGM.GetAddrOfConstantStringFromLiteral(E), - E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + E->getType(), AlignmentSource::Decl); } LValue CodeGenFunction::EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E) { return MakeAddrLValue(CGM.GetAddrOfConstantStringFromObjCEncode(E), - E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + E->getType(), AlignmentSource::Decl); } LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) { @@ -2517,7 +2496,6 @@ StringRef NameItems[] = { PredefinedExpr::getIdentTypeName(E->getIdentType()), FnName}; std::string GVName = llvm::join(NameItems, NameItems + 2, "."); - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); if (auto *BD = dyn_cast(CurCodeDecl)) { std::string Name = SL->getString(); if (!Name.empty()) { @@ -2526,14 +2504,14 @@ if (Discriminator) Name += "_" + Twine(Discriminator + 1).str(); auto C = CGM.GetAddrOfConstantCString(Name, GVName.c_str()); - return MakeAddrLValue(C, E->getType(), BaseInfo); + return MakeAddrLValue(C, E->getType(), AlignmentSource::Decl); } else { auto C = CGM.GetAddrOfConstantCString(FnName, GVName.c_str()); - return MakeAddrLValue(C, E->getType(), BaseInfo); + return MakeAddrLValue(C, E->getType(), AlignmentSource::Decl); } } auto C = CGM.GetAddrOfConstantStringFromLiteral(SL, GVName); - return MakeAddrLValue(C, E->getType(), BaseInfo); + return MakeAddrLValue(C, E->getType(), AlignmentSource::Decl); } /// Emit a type description suitable for use by a runtime sanitizer library. The @@ -3211,7 +3189,12 @@ QualType EltType = LV.getType()->castAs()->getElementType(); Addr = emitArraySubscriptGEP(*this, Addr, Idx, EltType, /*inbounds*/ true, SignedIndices, E->getExprLoc()); - return MakeAddrLValue(Addr, EltType, LV.getBaseInfo()); + + TBAAAccessInfo TBAAInfo = LV.getTBAAInfo(); + if (!CGM.isTBAAMayAliasAccessInfo(TBAAInfo)) + TBAAInfo = CGM.getTBAAAccessInfo(EltType); + LValueBaseInfo BaseInfo(LV.getBaseInfo().getAlignmentSource(), TBAAInfo); + return MakeAddrLValue(Addr, EltType, BaseInfo); } LValueBaseInfo BaseInfo; @@ -3302,9 +3285,11 @@ SignedIndices, E->getExprLoc()); } - LValue LV = MakeAddrLValue(Addr, E->getType(), BaseInfo); - - // TODO: Preserve/extend path TBAA metadata? + TBAAAccessInfo TBAAInfo = BaseInfo.getTBAAInfo(); + if (!CGM.isTBAAMayAliasAccessInfo(TBAAInfo)) + TBAAInfo = CGM.getTBAAAccessInfo(E->getType()); + LValueBaseInfo EltBaseInfo(BaseInfo.getAlignmentSource(), TBAAInfo); + LValue LV = MakeAddrLValue(Addr, E->getType(), EltBaseInfo); if (getLangOpts().ObjC1 && getLangOpts().getGC() != LangOptions::NonGC) { @@ -3344,7 +3329,7 @@ } LValueBaseInfo TypeInfo; CharUnits Align = CGF.getNaturalTypeAlignment(ElTy, &TypeInfo); - BaseInfo.mergeForCast(TypeInfo); + BaseInfo.mergeForCast(TypeInfo, CGF.CGM); return Address(CGF.Builder.CreateLoad(BaseLVal.getAddress()), Align); } return CGF.EmitPointerWithAlignment(Base, &BaseInfo); @@ -3534,7 +3519,7 @@ Address VecMem = CreateMemTemp(E->getBase()->getType()); Builder.CreateStore(Vec, VecMem); Base = MakeAddrLValue(VecMem, E->getBase()->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + AlignmentSource::Decl); } QualType type = @@ -3660,15 +3645,6 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, const FieldDecl *field) { LValueBaseInfo BaseInfo = base.getBaseInfo(); - AlignmentSource fieldAlignSource = - getFieldAlignmentSource(BaseInfo.getAlignmentSource()); - LValueBaseInfo FieldBaseInfo(fieldAlignSource, BaseInfo.getMayAlias()); - - QualType type = field->getType(); - const RecordDecl *rec = field->getParent(); - if (rec->isUnion() || rec->hasAttr() || type->isVectorType()) - FieldBaseInfo.setMayAlias(true); - bool mayAlias = FieldBaseInfo.getMayAlias(); if (field->isBitField()) { const CGRecordLayout &RL = @@ -3688,18 +3664,53 @@ QualType fieldType = field->getType().withCVRQualifiers(base.getVRQualifiers()); + // TODO: Support TBAA for bit fields. + LValueBaseInfo FieldBaseInfo(BaseInfo.getAlignmentSource(), + CGM.getTBAAMayAliasAccessInfo()); return LValue::MakeBitfield(Addr, Info, fieldType, FieldBaseInfo); } + // Fields of may-alias structures are may-alias themselves. + // FIXME: this should get propagated down through anonymous structs + // and unions. + QualType type = field->getType(); + const RecordDecl *rec = field->getParent(); + LValueBaseInfo FieldBaseInfo(BaseInfo.getAlignmentSource()); + if (CGM.isTBAAMayAliasAccessInfo(BaseInfo.getTBAAInfo()) || + rec->hasAttr() || type->isVectorType()) { + FieldBaseInfo.setTBAAInfo(CGM.getTBAAMayAliasAccessInfo()); + } else if(rec->isUnion()) { + // TODO: Support TBAA for unions. + FieldBaseInfo.setTBAAInfo(CGM.getTBAAMayAliasAccessInfo()); + } else { + TBAAAccessInfo TBAAInfo = base.getTBAAInfo(); + // If no base type been assigned for the base access, then try to generate + // one for this base lvalue. + if (!TBAAInfo.BaseType) { + TBAAInfo.BaseType = CGM.getTBAABaseTypeInfo(base.getType()); + assert(!TBAAInfo.Offset && + "Nonzero offset for an access with no base type!"); + } + + // Adjust offset to be relative to the base type. + const ASTRecordLayout &Layout = + getContext().getASTRecordLayout(field->getParent()); + unsigned CharWidth = getContext().getCharWidth(); + if (TBAAInfo.BaseType) + TBAAInfo.Offset += + Layout.getFieldOffset(field->getFieldIndex()) / CharWidth; + + // Update the final access type. + TBAAInfo.AccessType = CGM.getTBAATypeInfo(type); + + FieldBaseInfo.setTBAAInfo(TBAAInfo); + } + Address addr = base.getAddress(); unsigned cvr = base.getVRQualifiers(); - bool TBAAPath = CGM.getCodeGenOpts().StructPathTBAA; if (rec->isUnion()) { // For unions, there is no pointer adjustment. 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())) @@ -3716,18 +3727,11 @@ llvm::LoadInst *load = Builder.CreateLoad(addr, "ref"); if (cvr & Qualifiers::Volatile) load->setVolatile(true); - // Loading the reference will disable path-aware TBAA. - TBAAPath = false; - TBAAAccessInfo TBAAInfo = mayAlias ? CGM.getTBAAMayAliasAccessInfo() : - CGM.getTBAAAccessInfo(type); - CGM.DecorateInstructionWithTBAA(load, TBAAInfo); + CGM.DecorateInstructionWithTBAA(load, FieldBaseInfo.getTBAAInfo()); - mayAlias = false; type = refType->getPointeeType(); - CharUnits alignment = getNaturalTypeAlignment(type, &FieldBaseInfo, /*pointee*/ true); - FieldBaseInfo.setMayAlias(false); addr = Address(load, alignment); // Qualifiers on the struct don't apply to the referencee, and @@ -3751,35 +3755,6 @@ LValue LV = MakeAddrLValue(addr, type, FieldBaseInfo); LV.getQuals().addCVRQualifiers(cvr); - // Fields of may_alias structs act like 'char' for TBAA purposes. - // FIXME: this should get propagated down through anonymous structs - // and unions. - if (mayAlias) { - LV.setTBAAInfo(CGM.getTBAAMayAliasAccessInfo()); - } else if (TBAAPath) { - // If no base type been assigned for the base access, then try to generate - // one for this base lvalue. - TBAAAccessInfo TBAAInfo = base.getTBAAInfo(); - if (!TBAAInfo.BaseType) { - TBAAInfo.BaseType = CGM.getTBAABaseTypeInfo(base.getType()); - assert(!TBAAInfo.Offset && - "Nonzero offset for an access with no base type!"); - } - - // Adjust offset to be relative to the base type. - const ASTRecordLayout &Layout = - getContext().getASTRecordLayout(field->getParent()); - unsigned CharWidth = getContext().getCharWidth(); - if (TBAAInfo.BaseType) - TBAAInfo.Offset += - Layout.getFieldOffset(field->getFieldIndex()) / CharWidth; - - // Update the final access type. - TBAAInfo.AccessType = LV.getTBAAInfo().AccessType; - - LV.setTBAAInfo(TBAAInfo); - } - // __weak attribute on a field is ignored. if (LV.getQuals().getObjCGCAttr() == Qualifiers::Weak) LV.getQuals().removeObjCGCAttr(); @@ -3801,19 +3776,23 @@ llvm::Type *llvmType = ConvertTypeForMem(FieldType); V = Builder.CreateElementBitCast(V, llvmType, Field->getName()); - // TODO: access-path TBAA? + // TODO: Generate TBAA information that describes this access as a structure + // member access and not just an access to an object of the field's type. This + // is similar to what we do in EmitLValueForField(). LValueBaseInfo BaseInfo = Base.getBaseInfo(); + TBAAAccessInfo TBAAInfo = BaseInfo.getTBAAInfo(); + if (!CGM.isTBAAMayAliasAccessInfo(TBAAInfo)) + TBAAInfo = CGM.getTBAAAccessInfo(FieldType); LValueBaseInfo FieldBaseInfo( getFieldAlignmentSource(BaseInfo.getAlignmentSource()), - BaseInfo.getMayAlias()); + TBAAInfo); return MakeAddrLValue(V, FieldType, FieldBaseInfo); } LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){ - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); if (E->isFileScope()) { ConstantAddress GlobalPtr = CGM.GetAddrOfConstantCompoundLiteral(E); - return MakeAddrLValue(GlobalPtr, E->getType(), BaseInfo); + return MakeAddrLValue(GlobalPtr, E->getType(), AlignmentSource::Decl); } if (E->getType()->isVariablyModifiedType()) // make sure to emit the VLA size. @@ -3821,7 +3800,7 @@ Address DeclPtr = CreateMemTemp(E->getType(), ".compoundliteral"); const Expr *InitExpr = E->getInitializer(); - LValue Result = MakeAddrLValue(DeclPtr, E->getType(), BaseInfo); + LValue Result = MakeAddrLValue(DeclPtr, E->getType(), AlignmentSource::Decl); EmitAnyExprToMem(InitExpr, DeclPtr, E->getType().getQualifiers(), /*Init*/ true); @@ -3920,10 +3899,11 @@ AlignmentSource alignSource = std::max(lhs->getBaseInfo().getAlignmentSource(), rhs->getBaseInfo().getAlignmentSource()); - bool MayAlias = lhs->getBaseInfo().getMayAlias() || - rhs->getBaseInfo().getMayAlias(); + TBAAAccessInfo TBAAInfo = CGM.mergeTBAAInfoForConditionalOperator( + lhs->getBaseInfo().getTBAAInfo(), + rhs->getBaseInfo().getTBAAInfo()); return MakeAddrLValue(result, expr->getType(), - LValueBaseInfo(alignSource, MayAlias)); + LValueBaseInfo(alignSource, TBAAInfo)); } else { assert((lhs || rhs) && "both operands of glvalue conditional are throw-expressions?"); @@ -4021,7 +4001,11 @@ This, DerivedClassDecl, E->path_begin(), E->path_end(), /*NullCheckValue=*/false, E->getExprLoc()); - return MakeAddrLValue(Base, E->getType(), LV.getBaseInfo()); + // TODO: Support accesses to members of base classes in TBAA. For now, we + // conservatively pretend that the complete object is of the base class + // type. + return MakeAddrLValue(Base, E->getType(), + LV.getBaseInfo().getAlignmentSource()); } case CK_ToUnion: return EmitAggExprToLValue(E); @@ -4259,7 +4243,7 @@ if (!RV.isScalar()) return MakeAddrLValue(RV.getAggregateAddress(), E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + AlignmentSource::Decl); assert(E->getCallReturnType(getContext())->isReferenceType() && "Can't have a scalar return unless the return type is a " @@ -4278,8 +4262,7 @@ && "binding l-value to type which needs a temporary"); AggValueSlot Slot = CreateAggTemp(E->getType()); EmitCXXConstructExpr(E, Slot); - return MakeAddrLValue(Slot.getAddress(), E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + return MakeAddrLValue(Slot.getAddress(), E->getType(), AlignmentSource::Decl); } LValue @@ -4294,7 +4277,7 @@ LValue CodeGenFunction::EmitCXXUuidofLValue(const CXXUuidofExpr *E) { return MakeAddrLValue(EmitCXXUuidofExpr(E), E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + AlignmentSource::Decl); } LValue @@ -4303,16 +4286,14 @@ Slot.setExternallyDestructed(); EmitAggExpr(E->getSubExpr(), Slot); EmitCXXTemporary(E->getTemporary(), E->getType(), Slot.getAddress()); - return MakeAddrLValue(Slot.getAddress(), E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + return MakeAddrLValue(Slot.getAddress(), E->getType(), AlignmentSource::Decl); } LValue CodeGenFunction::EmitLambdaLValue(const LambdaExpr *E) { AggValueSlot Slot = CreateAggTemp(E->getType(), "temp.lvalue"); EmitLambdaExpr(E, Slot); - return MakeAddrLValue(Slot.getAddress(), E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + return MakeAddrLValue(Slot.getAddress(), E->getType(), AlignmentSource::Decl); } LValue CodeGenFunction::EmitObjCMessageExprLValue(const ObjCMessageExpr *E) { @@ -4320,7 +4301,7 @@ if (!RV.isScalar()) return MakeAddrLValue(RV.getAggregateAddress(), E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + AlignmentSource::Decl); assert(E->getMethodDecl()->getReturnType()->isReferenceType() && "Can't have a scalar return unless the return type is a " @@ -4332,8 +4313,7 @@ LValue CodeGenFunction::EmitObjCSelectorLValue(const ObjCSelectorExpr *E) { Address V = CGM.getObjCRuntime().GetAddrOfSelector(*this, E->getSelector()); - return MakeAddrLValue(V, E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + return MakeAddrLValue(V, E->getType(), AlignmentSource::Decl); } llvm::Value *CodeGenFunction::EmitIvarOffset(const ObjCInterfaceDecl *Interface, @@ -4377,7 +4357,7 @@ // Can only get l-value for message expression returning aggregate type RValue RV = EmitAnyExprToTemp(E); return MakeAddrLValue(RV.getAggregateAddress(), E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + AlignmentSource::Decl); } RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee, @@ -4580,8 +4560,7 @@ RValue CodeGenFunction::convertTempToRValue(Address addr, QualType type, SourceLocation loc) { - LValue lvalue = MakeAddrLValue(addr, type, - LValueBaseInfo(AlignmentSource::Decl, false)); + LValue lvalue = MakeAddrLValue(addr, type, AlignmentSource::Decl); switch (getEvaluationKind(type)) { case TEK_Complex: return RValue::getComplex(EmitLoadOfComplex(lvalue, loc)); @@ -4636,9 +4615,8 @@ if (ov == resultExpr && ov->isRValue() && !forLValue && CodeGenFunction::hasAggregateEvaluationKind(ov->getType())) { CGF.EmitAggExpr(ov->getSourceExpr(), slot); - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); LValue LV = CGF.MakeAddrLValue(slot.getAddress(), ov->getType(), - BaseInfo); + AlignmentSource::Decl); opaqueData = OVMA::bind(CGF, ov, LV); result.RV = slot.asRValue(); @@ -4686,3 +4664,10 @@ LValue CodeGenFunction::EmitPseudoObjectLValue(const PseudoObjectExpr *E) { return emitPseudoObjectExpr(*this, E, true, AggValueSlot::ignored()).LV; } + +void LValueBaseInfo::mergeForCast(const LValueBaseInfo &TargetTypeInfo, + CodeGenModule &CGM) { + setAlignmentSource(TargetTypeInfo.getAlignmentSource()); + setTBAAInfo(CGM.mergeTBAAInfoForCast(getTBAAInfo(), + TargetTypeInfo.getTBAAInfo())); +} Index: lib/CodeGen/CGObjC.cpp =================================================================== --- lib/CodeGen/CGObjC.cpp +++ lib/CodeGen/CGObjC.cpp @@ -162,7 +162,7 @@ const Expr *Rhs = ALE->getElement(i); LValue LV = MakeAddrLValue( Builder.CreateConstArrayGEP(Objects, i, getPointerSize()), - ElementType, LValueBaseInfo(AlignmentSource::Decl, false)); + ElementType, AlignmentSource::Decl); llvm::Value *value = EmitScalarExpr(Rhs); EmitStoreThroughLValue(RValue::get(value), LV, true); @@ -174,7 +174,7 @@ const Expr *Key = DLE->getKeyValueElement(i).Key; LValue KeyLV = MakeAddrLValue( Builder.CreateConstArrayGEP(Keys, i, getPointerSize()), - ElementType, LValueBaseInfo(AlignmentSource::Decl, false)); + ElementType, AlignmentSource::Decl); llvm::Value *keyValue = EmitScalarExpr(Key); EmitStoreThroughLValue(RValue::get(keyValue), KeyLV, /*isInit=*/true); @@ -182,7 +182,7 @@ const Expr *Value = DLE->getKeyValueElement(i).Value; LValue ValueLV = MakeAddrLValue( Builder.CreateConstArrayGEP(Objects, i, getPointerSize()), - ElementType, LValueBaseInfo(AlignmentSource::Decl, false)); + ElementType, AlignmentSource::Decl); llvm::Value *valueValue = EmitScalarExpr(Value); EmitStoreThroughLValue(RValue::get(valueValue), ValueLV, /*isInit=*/true); if (TrackNeededObjects) { Index: lib/CodeGen/CGObjCRuntime.cpp =================================================================== --- lib/CodeGen/CGObjCRuntime.cpp +++ lib/CodeGen/CGObjCRuntime.cpp @@ -109,8 +109,9 @@ Addr = CGF.Builder.CreateElementBitCast(Addr, llvm::Type::getIntNTy(CGF.getLLVMContext(), Info->StorageSize)); - return LValue::MakeBitfield(Addr, *Info, IvarTy, - LValueBaseInfo(AlignmentSource::Decl, false)); + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGM.getTBAAMayAliasAccessInfo()); + return LValue::MakeBitfield(Addr, *Info, IvarTy, BaseInfo); } namespace { Index: lib/CodeGen/CGOpenMPRuntime.cpp =================================================================== --- lib/CodeGen/CGOpenMPRuntime.cpp +++ lib/CodeGen/CGOpenMPRuntime.cpp @@ -1131,7 +1131,7 @@ CodeGenFunction &CGF) { return CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(getThreadIDVariable()), getThreadIDVariable()->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + AlignmentSource::Decl); } CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM) @@ -4072,7 +4072,7 @@ Address(SharedRefLValue.getPointer(), C.getDeclAlign(OriginalVD)), SharedRefLValue.getType(), LValueBaseInfo(AlignmentSource::Decl, - SharedRefLValue.getBaseInfo().getMayAlias())); + SharedRefLValue.getTBAAInfo())); QualType Type = OriginalVD->getType(); if (Type->isArrayType()) { // Initialize firstprivate array. Index: lib/CodeGen/CGStmtOpenMP.cpp =================================================================== --- lib/CodeGen/CGStmtOpenMP.cpp +++ lib/CodeGen/CGStmtOpenMP.cpp @@ -392,15 +392,14 @@ continue; } - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); - LValue ArgLVal = - CGF.MakeAddrLValue(LocalAddr, Args[Cnt]->getType(), BaseInfo); + LValue ArgLVal = CGF.MakeAddrLValue(LocalAddr, Args[Cnt]->getType(), + AlignmentSource::Decl); if (FD->hasCapturedVLAType()) { if (FO.UIntPtrCastRequired) { ArgLVal = CGF.MakeAddrLValue(castValueFromUintptr(CGF, FD->getType(), Args[Cnt]->getName(), ArgLVal), - FD->getType(), BaseInfo); + FD->getType(), AlignmentSource::Decl); } auto *ExprArg = CGF.EmitLoadOfLValue(ArgLVal, SourceLocation()).getScalarVal(); @@ -497,14 +496,13 @@ llvm::Function *WrapperF = emitOutlinedFunctionPrologue(WrapperCGF, Args, LocalAddrs, VLASizes, WrapperCGF.CXXThisValue, WrapperFO); - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); llvm::SmallVector CallArgs; for (const auto *Arg : Args) { llvm::Value *CallArg; auto I = LocalAddrs.find(Arg); if (I != LocalAddrs.end()) { - LValue LV = - WrapperCGF.MakeAddrLValue(I->second.second, Arg->getType(), BaseInfo); + LValue LV = WrapperCGF.MakeAddrLValue(I->second.second, Arg->getType(), + AlignmentSource::Decl); CallArg = WrapperCGF.EmitLoadOfScalar(LV, SourceLocation()); } else { auto EI = VLASizes.find(Arg); @@ -512,7 +510,8 @@ CallArg = EI->second.second; else { LValue LV = WrapperCGF.MakeAddrLValue(WrapperCGF.GetAddrOfLocalVar(Arg), - Arg->getType(), BaseInfo); + Arg->getType(), + AlignmentSource::Decl); CallArg = WrapperCGF.EmitLoadOfScalar(LV, SourceLocation()); } } Index: lib/CodeGen/CGValue.h =================================================================== --- lib/CodeGen/CGValue.h +++ lib/CodeGen/CGValue.h @@ -31,6 +31,7 @@ namespace CodeGen { class AggValueSlot; struct CGBitFieldInfo; + class CodeGenModule; /// RValue - This trivial value class is used to represent the result of an /// expression that is evaluated. It can be one of three things: either a @@ -149,21 +150,18 @@ class LValueBaseInfo { AlignmentSource AlignSource; - bool MayAlias; + TBAAAccessInfo TBAAInfo; public: explicit LValueBaseInfo(AlignmentSource Source = AlignmentSource::Type, - bool Alias = false) - : AlignSource(Source), MayAlias(Alias) {} + TBAAAccessInfo TBAAInfo = TBAAAccessInfo()) + : AlignSource(Source), TBAAInfo(TBAAInfo) {} AlignmentSource getAlignmentSource() const { return AlignSource; } void setAlignmentSource(AlignmentSource Source) { AlignSource = Source; } - bool getMayAlias() const { return MayAlias; } - void setMayAlias(bool Alias) { MayAlias = Alias; } + TBAAAccessInfo getTBAAInfo() const { return TBAAInfo; } + void setTBAAInfo(TBAAAccessInfo Info) { TBAAInfo = Info; } - void mergeForCast(const LValueBaseInfo &Info) { - setAlignmentSource(Info.getAlignmentSource()); - setMayAlias(getMayAlias() || Info.getMayAlias()); - } + void mergeForCast(const LValueBaseInfo &TargetTypeInfo, CodeGenModule &CGM); }; /// LValue - This represents an lvalue references. Because C/C++ allow @@ -221,7 +219,6 @@ bool ImpreciseLifetime : 1; LValueBaseInfo BaseInfo; - TBAAAccessInfo TBAAInfo; // This flag shows if a nontemporal load/stores should be used when accessing // this lvalue. @@ -231,8 +228,7 @@ private: void Initialize(QualType Type, Qualifiers Quals, - CharUnits Alignment, LValueBaseInfo BaseInfo, - TBAAAccessInfo TBAAInfo = TBAAAccessInfo()) { + CharUnits Alignment, LValueBaseInfo BaseInfo) { assert((!Alignment.isZero() || Type->isIncompleteType()) && "initializing l-value with zero alignment!"); this->Type = Type; @@ -241,7 +237,6 @@ assert(this->Alignment == Alignment.getQuantity() && "Alignment exceeds allowed max!"); this->BaseInfo = BaseInfo; - this->TBAAInfo = TBAAInfo; // Initialize Objective-C flags. this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false; @@ -308,8 +303,8 @@ Expr *getBaseIvarExp() const { return BaseIvarExp; } void setBaseIvarExp(Expr *V) { BaseIvarExp = V; } - TBAAAccessInfo getTBAAInfo() const { return TBAAInfo; } - void setTBAAInfo(TBAAAccessInfo Info) { TBAAInfo = Info; } + TBAAAccessInfo getTBAAInfo() const { return BaseInfo.getTBAAInfo(); } + void setTBAAInfo(TBAAAccessInfo Info) { BaseInfo.setTBAAInfo(Info); } const Qualifiers &getQuals() const { return Quals; } Qualifiers &getQuals() { return Quals; } @@ -368,7 +363,7 @@ llvm::Value *getGlobalReg() const { assert(isGlobalReg()); return V; } static LValue MakeAddr(Address address, QualType type, ASTContext &Context, - LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) { + LValueBaseInfo BaseInfo) { Qualifiers qs = type.getQualifiers(); qs.setObjCGCAttr(Context.getObjCGCAttrKind(type)); @@ -376,7 +371,7 @@ R.LVType = Simple; assert(address.getPointer()->getType()->isPointerTy()); R.V = address.getPointer(); - R.Initialize(type, qs, address.getAlignment(), BaseInfo, TBAAInfo); + R.Initialize(type, qs, address.getAlignment(), BaseInfo); return R; } @@ -425,7 +420,7 @@ R.LVType = GlobalReg; R.V = Reg.getPointer(); R.Initialize(type, type.getQualifiers(), Reg.getAlignment(), - LValueBaseInfo(AlignmentSource::Decl, false)); + LValueBaseInfo(AlignmentSource::Decl)); return R; } Index: lib/CodeGen/CodeGenFunction.h =================================================================== --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -1911,17 +1911,24 @@ //===--------------------------------------------------------------------===// LValue MakeAddrLValue(Address Addr, QualType T, - LValueBaseInfo BaseInfo = - LValueBaseInfo(AlignmentSource::Type)) { - return LValue::MakeAddr(Addr, T, getContext(), BaseInfo, - CGM.getTBAAAccessInfo(T)); + AlignmentSource Source = AlignmentSource::Type) { + return LValue::MakeAddr(Addr, T, getContext(), + LValueBaseInfo(Source, CGM.getTBAAAccessInfo(T))); + } + + LValue MakeAddrLValue(Address Addr, QualType T, LValueBaseInfo BaseInfo) { + return LValue::MakeAddr(Addr, T, getContext(), BaseInfo); } LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, - LValueBaseInfo BaseInfo = - LValueBaseInfo(AlignmentSource::Type)) { + AlignmentSource Source = AlignmentSource::Type) { return LValue::MakeAddr(Address(V, Alignment), T, getContext(), - BaseInfo, CGM.getTBAAAccessInfo(T)); + LValueBaseInfo(Source, CGM.getTBAAAccessInfo(T))); + } + + LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, + LValueBaseInfo BaseInfo) { + return LValue::MakeAddr(Address(V, Alignment), T, getContext(), BaseInfo); } LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T); @@ -3058,16 +3065,15 @@ /// the LLVM value representation. llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, - LValueBaseInfo BaseInfo = - LValueBaseInfo(AlignmentSource::Type), + AlignmentSource Source = AlignmentSource::Type, bool isNontemporal = false) { - return EmitLoadOfScalar(Addr, Volatile, Ty, Loc, BaseInfo, - CGM.getTBAAAccessInfo(Ty), isNontemporal); + return EmitLoadOfScalar(Addr, Volatile, Ty, Loc, + LValueBaseInfo(Source, CGM.getTBAAAccessInfo(Ty)), + isNontemporal); } llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, LValueBaseInfo BaseInfo, - TBAAAccessInfo TBAAInfo, bool isNontemporal = false); /// EmitLoadOfScalar - Load a scalar value from an address, taking @@ -3081,16 +3087,15 @@ /// the LLVM value representation. void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, - LValueBaseInfo BaseInfo = - LValueBaseInfo(AlignmentSource::Type), + AlignmentSource Source = AlignmentSource::Type, bool isInit = false, bool isNontemporal = false) { - EmitStoreOfScalar(Value, Addr, Volatile, Ty, BaseInfo, - CGM.getTBAAAccessInfo(Ty), isInit, isNontemporal); + EmitStoreOfScalar(Value, Addr, Volatile, Ty, + LValueBaseInfo(Source, CGM.getTBAAAccessInfo(Ty)), + isInit, isNontemporal); } void EmitStoreOfScalar(llvm::Value *Value, Address Addr, - bool Volatile, QualType Ty, - LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo, + bool Volatile, QualType Ty, LValueBaseInfo BaseInfo, bool isInit = false, bool isNontemporal = false); /// EmitStoreOfScalar - Store a scalar value to an address, taking Index: lib/CodeGen/CodeGenFunction.cpp =================================================================== --- lib/CodeGen/CodeGenFunction.cpp +++ lib/CodeGen/CodeGenFunction.cpp @@ -132,13 +132,15 @@ if (auto TT = T->getAs()) { if (auto Align = TT->getDecl()->getMaxAlignment()) { if (BaseInfo) - *BaseInfo = LValueBaseInfo(AlignmentSource::AttributedType, false); + *BaseInfo = LValueBaseInfo(AlignmentSource::AttributedType, + CGM.getTBAAAccessInfo(T)); return getContext().toCharUnitsFromBits(Align); } } if (BaseInfo) - *BaseInfo = LValueBaseInfo(AlignmentSource::Type, false); + *BaseInfo = LValueBaseInfo(AlignmentSource::Type, + CGM.getTBAAAccessInfo(T)); CharUnits Alignment; if (T->isIncompleteType()) { @@ -170,8 +172,7 @@ LValue CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) { LValueBaseInfo BaseInfo; CharUnits Alignment = getNaturalTypeAlignment(T, &BaseInfo); - return LValue::MakeAddr(Address(V, Alignment), T, getContext(), BaseInfo, - CGM.getTBAAAccessInfo(T)); + return LValue::MakeAddr(Address(V, Alignment), T, getContext(), BaseInfo); } /// Given a value of type T* that may not be to a complete object, Index: lib/CodeGen/CodeGenModule.h =================================================================== --- lib/CodeGen/CodeGenModule.h +++ lib/CodeGen/CodeGenModule.h @@ -677,6 +677,19 @@ /// may-alias accesses. TBAAAccessInfo getTBAAMayAliasAccessInfo(); + /// isTBAAMayAliasAccessInfo - Test for the may-alias TBAA access descriptor. + bool isTBAAMayAliasAccessInfo(TBAAAccessInfo Info); + + /// mergeTBAAInfoForCast - Get merged TBAA information for the purposes of + /// type casts. + TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, + TBAAAccessInfo TargetInfo); + + /// mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the + /// purposes of conditional operator. + TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, + TBAAAccessInfo InfoB); + bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor); bool isPaddedAtomicType(QualType type); Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -52,6 +52,7 @@ #include "llvm/IR/Intrinsics.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" +#include "llvm/IR/Verifier.h" // TODO #include "llvm/ProfileData/InstrProfReader.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/ErrorHandling.h" @@ -612,6 +613,27 @@ return TBAA->getMayAliasAccessInfo(); } +bool CodeGenModule::isTBAAMayAliasAccessInfo(TBAAAccessInfo Info) { + if (!TBAA) + return false; + return TBAA->isMayAliasAccessInfo(Info); +} + +TBAAAccessInfo CodeGenModule::mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, + TBAAAccessInfo TargetInfo) { + if (!TBAA) + return TBAAAccessInfo(); + return TBAA->mergeTBAAInfoForCast(SourceInfo, TargetInfo); +} + +TBAAAccessInfo +CodeGenModule::mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, + TBAAAccessInfo InfoB) { + if (!TBAA) + return TBAAAccessInfo(); + return TBAA->mergeTBAAInfoForConditionalOperator(InfoA, InfoB); +} + void CodeGenModule::DecorateInstructionWithTBAA(llvm::Instruction *Inst, TBAAAccessInfo TBAAInfo) { if (llvm::MDNode *Tag = getTBAAAccessTagInfo(TBAAInfo)) Index: lib/CodeGen/CodeGenTBAA.h =================================================================== --- lib/CodeGen/CodeGenTBAA.h +++ lib/CodeGen/CodeGenTBAA.h @@ -47,6 +47,20 @@ : TBAAAccessInfo(/* AccessType= */ nullptr) {} + bool operator==(const TBAAAccessInfo &Other) const { + return BaseType == Other.BaseType && + AccessType == Other.AccessType && + Offset == Other.Offset; + } + + bool operator!=(const TBAAAccessInfo &Other) const { + return !(*this == Other); + } + + explicit operator bool() const { + return *this != TBAAAccessInfo(); + } + /// BaseType - The base/leading access type. May be null if this access /// descriptor represents an access that is not considered to be an access /// to an aggregate or union member. @@ -136,6 +150,19 @@ /// getMayAliasAccessInfo - Get TBAA information that represents may-alias /// accesses. TBAAAccessInfo getMayAliasAccessInfo(); + + /// isMayAliasAccessInfo - Test for the may-alias TBAA access descriptor. + bool isMayAliasAccessInfo(TBAAAccessInfo Info); + + /// mergeTBAAInfoForCast - Get merged TBAA information for the purpose of + /// type casts. + TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, + TBAAAccessInfo TargetInfo); + + /// mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the + /// purpose of conditional operator. + TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, + TBAAAccessInfo InfoB); }; } // end namespace CodeGen @@ -166,9 +193,7 @@ static bool isEqual(const clang::CodeGen::TBAAAccessInfo &LHS, const clang::CodeGen::TBAAAccessInfo &RHS) { - return LHS.BaseType == RHS.BaseType && - LHS.AccessType == RHS.AccessType && - LHS.Offset == RHS.Offset; + return LHS == RHS; } }; Index: lib/CodeGen/CodeGenTBAA.cpp =================================================================== --- lib/CodeGen/CodeGenTBAA.cpp +++ lib/CodeGen/CodeGenTBAA.cpp @@ -88,18 +88,45 @@ return false; } +/// Check if the given type is a valid base type to be used in access tags. +static bool isValidBaseType(QualType QTy) { + if (QTy->isReferenceType()) + return false; + if (const RecordType *TTy = QTy->getAs()) { + const RecordDecl *RD = TTy->getDecl()->getDefinition(); + // Incomplete types are not valid base access types. + if (!RD) + return false; + if (RD->hasFlexibleArrayMember()) + return false; + // RD can be struct, union, class, interface or enum. + // For now, we only handle struct and class. + if (RD->isStruct() || RD->isClass()) + return true; + } + return false; +} + llvm::MDNode *CodeGenTBAA::getTypeInfo(QualType QTy) { // At -O0 or relaxed aliasing, TBAA is not emitted for regular types. if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing) return nullptr; + // In some cases, such as dereferencing a structure member, the final access + // type may well itself be an aggregate. Since it is possible to dereference + // a member of that aggregate, this function shall be able to generate + // descriptors for any object types, including aggregate ones, without + // falling back to returning the "omnipotent char" type node. + // TODO: Combine getTypeInfo() and getBaseTypeInfo() into a single function. + if (isValidBaseType(QTy)) + return getBaseTypeInfo(QTy); + // If the type has the may_alias attribute (even on a typedef), it is // effectively in the general char alias class. if (TypeHasMayAlias(QTy)) return getChar(); const Type *Ty = Context.getCanonicalType(QTy).getTypePtr(); - if (llvm::MDNode *N = MetadataCache[Ty]) return N; @@ -232,20 +259,6 @@ return StructMetadataCache[Ty] = nullptr; } -/// Check if the given type is a valid base type to be used in access tags. -static bool isValidBaseType(QualType QTy) { - if (const RecordType *TTy = QTy->getAs()) { - const RecordDecl *RD = TTy->getDecl()->getDefinition(); - if (RD->hasFlexibleArrayMember()) - return false; - // RD can be struct, union, class, interface or enum. - // For now, we only handle struct and class. - if (RD->isStruct() || RD->isClass()) - return true; - } - return false; -} - llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) { if (!isValidBaseType(QTy)) return nullptr; @@ -309,3 +322,35 @@ TBAAAccessInfo CodeGenTBAA::getMayAliasAccessInfo() { return TBAAAccessInfo(getChar()); } + +bool CodeGenTBAA::isMayAliasAccessInfo(TBAAAccessInfo Info) { + return Info == getMayAliasAccessInfo(); +} + +TBAAAccessInfo CodeGenTBAA::mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, + TBAAAccessInfo TargetInfo) { + TBAAAccessInfo MayAliasInfo = getMayAliasAccessInfo(); + if (SourceInfo == MayAliasInfo || TargetInfo == MayAliasInfo) + return MayAliasInfo; + return TargetInfo; +} + +TBAAAccessInfo +CodeGenTBAA::mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, + TBAAAccessInfo InfoB) { + if (InfoA == InfoB) + return InfoA; + + if (!InfoA || !InfoB) + return TBAAAccessInfo(); + + TBAAAccessInfo MayAliasInfo = getMayAliasAccessInfo(); + if (InfoA == MayAliasInfo || InfoB == MayAliasInfo) + return MayAliasInfo; + + // TODO: Implement the rest of the logic here. For example, two accesses + // with same final access types result in an access to an object of that final + // access type. + + return MayAliasInfo; +}