Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
lib/Sema/SemaChecking.cpp
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 8,095 Lines • ▼ Show 20 Lines | if (Target->isBooleanType() && isa<CallExpr>(E)) { | ||||
} | } | ||||
} | } | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
DiagnoseNullConversion(S, E, T, CC); | DiagnoseNullConversion(S, E, T, CC); | ||||
S.DiscardMisalignedMemberAddress(Target, E); | |||||
if (!Source->isIntegerType() || !Target->isIntegerType()) | if (!Source->isIntegerType() || !Target->isIntegerType()) | ||||
return; | return; | ||||
// TODO: remove this early return once the false positives for constant->bool | // TODO: remove this early return once the false positives for constant->bool | ||||
// in templates, macros, etc, are reduced or removed. | // in templates, macros, etc, are reduced or removed. | ||||
if (Target->isSpecificBuiltinType(BuiltinType::Bool)) | if (Target->isSpecificBuiltinType(BuiltinType::Bool)) | ||||
return; | return; | ||||
▲ Show 20 Lines • Show All 1,031 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
void Sema::CheckCompletedExpr(Expr *E, SourceLocation CheckLoc, | void Sema::CheckCompletedExpr(Expr *E, SourceLocation CheckLoc, | ||||
bool IsConstexpr) { | bool IsConstexpr) { | ||||
CheckImplicitConversions(E, CheckLoc); | CheckImplicitConversions(E, CheckLoc); | ||||
CheckUnsequencedOperations(E); | CheckUnsequencedOperations(E); | ||||
if (!IsConstexpr && !E->isValueDependent()) | if (!IsConstexpr && !E->isValueDependent()) | ||||
CheckForIntOverflow(E); | CheckForIntOverflow(E); | ||||
DiagnoseMisalignedMembers(); | |||||
} | } | ||||
void Sema::CheckBitFieldInitialization(SourceLocation InitLoc, | void Sema::CheckBitFieldInitialization(SourceLocation InitLoc, | ||||
FieldDecl *BitField, | FieldDecl *BitField, | ||||
Expr *Init) { | Expr *Init) { | ||||
(void) AnalyzeBitFieldAssignment(*this, BitField, Init, InitLoc); | (void) AnalyzeBitFieldAssignment(*this, BitField, Init, InitLoc); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,540 Lines • ▼ Show 20 Lines | void Sema::CheckArgumentWithTypeTag(const ArgumentWithTypeTagAttr *Attr, | ||||
if (mismatch) | if (mismatch) | ||||
Diag(ArgumentExpr->getExprLoc(), diag::warn_type_safety_type_mismatch) | Diag(ArgumentExpr->getExprLoc(), diag::warn_type_safety_type_mismatch) | ||||
<< ArgumentType << ArgumentKind | << ArgumentType << ArgumentKind | ||||
<< TypeInfo.LayoutCompatible << RequiredType | << TypeInfo.LayoutCompatible << RequiredType | ||||
<< ArgumentExpr->getSourceRange() | << ArgumentExpr->getSourceRange() | ||||
<< TypeTagExpr->getSourceRange(); | << TypeTagExpr->getSourceRange(); | ||||
} | } | ||||
void Sema::AddPotentialMisalignedMembers(Expr *E, RecordDecl *RD, ValueDecl *MD, | |||||
CharUnits Alignment) { | |||||
MisalignedMembers.emplace_back(E, RD, MD, Alignment); | |||||
} | |||||
void Sema::DiagnoseMisalignedMembers() { | |||||
for (MisalignedMember &m : MisalignedMembers) { | |||||
Diag(m.E->getLocStart(), diag::warn_taking_address_of_packed_member) | |||||
<< m.MD << m.RD << m.E->getSourceRange(); | |||||
} | |||||
MisalignedMembers.clear(); | |||||
} | |||||
void Sema::DiscardMisalignedMemberAddress(const Type *T, Expr *E) { | |||||
if (!T->isPointerType()) | |||||
return; | |||||
if (isa<UnaryOperator>(E) && | |||||
cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf) { | |||||
auto *Op = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens(); | |||||
if (isa<MemberExpr>(Op)) { | |||||
auto MA = std::find(MisalignedMembers.begin(), MisalignedMembers.end(), | |||||
MisalignedMember(Op)); | |||||
if (MA != MisalignedMembers.end() && | |||||
Context.getTypeAlignInChars(T->getPointeeType()) <= MA->Alignment) | |||||
MisalignedMembers.erase(MA); | |||||
} | |||||
} | |||||
} | |||||
void Sema::RefersToMemberWithReducedAlignment( | |||||
Expr *E, | |||||
std::function<void(Expr *, RecordDecl *, ValueDecl *, CharUnits)> Action) { | |||||
const auto *ME = dyn_cast<MemberExpr>(E); | |||||
while (ME && isa<FieldDecl>(ME->getMemberDecl())) { | |||||
QualType BaseType = ME->getBase()->getType(); | |||||
if (ME->isArrow()) | |||||
BaseType = BaseType->getPointeeType(); | |||||
RecordDecl *RD = BaseType->getAs<RecordType>()->getDecl(); | |||||
ValueDecl *MD = ME->getMemberDecl(); | |||||
bool ByteAligned = Context.getTypeAlignInChars(MD->getType()).isOne(); | |||||
if (ByteAligned) // Attribute packed does not have any effect. | |||||
break; | |||||
if (!ByteAligned && | |||||
(RD->hasAttr<PackedAttr>() || (MD->hasAttr<PackedAttr>()))) { | |||||
CharUnits Alignment = std::min(Context.getTypeAlignInChars(MD->getType()), | |||||
Context.getTypeAlignInChars(BaseType)); | |||||
// Notify that this expression designates a member with reduced alignment | |||||
Action(E, RD, MD, Alignment); | |||||
break; | |||||
} | |||||
ME = dyn_cast<MemberExpr>(ME->getBase()); | |||||
} | |||||
} | |||||
void Sema::CheckAddressOfPackedMember(Expr *rhs) { | |||||
using namespace std::placeholders; | |||||
RefersToMemberWithReducedAlignment( | |||||
rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*this), _1, | |||||
_2, _3, _4)); | |||||
} | |||||