diff options
| author | Roger Ferrer Ibanez <roger.ferreribanez@arm.com> | 2016-06-13 15:41:40 +0000 |
|---|---|---|
| committer | Roger Ferrer Ibanez <roger.ferreribanez@arm.com> | 2016-06-13 15:41:40 +0000 |
| commit | ac6617b288eda8958d060328163ae05050a59b25 (patch) | |
| tree | 7d03bd146c59467fd363c2b6e6c3c5ee9c824c63 /clang/lib/Sema | |
| parent | af0bbd92a2ea14a42a7ca83da5d40bf18a0a7aba (diff) | |
| download | bcm5719-llvm-ac6617b288eda8958d060328163ae05050a59b25.tar.gz bcm5719-llvm-ac6617b288eda8958d060328163ae05050a59b25.zip | |
Warn when taking address of a packed member
This patch implements PR#22821.
Taking the address of a packed member is dangerous since the reduced
alignment of the pointee is lost. This can lead to memory alignment
faults in some architectures if the pointer value is dereferenced.
This change adds a new warning to clang emitted when taking the address
of a packed member. A packed member is either a field/data member
declared as attribute((packed)) or belonging to a struct/class
declared as such. The associated flag is -Waddress-of-packed-member
Differential Revision: http://reviews.llvm.org/D20561
llvm-svn: 272552
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index f4a5dea8f94..f766091e54e 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -10514,6 +10514,30 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) { return QualType(); } + // Taking the address of a data member/field of a packed + // struct may be a problem if the pointer value is dereferenced. + Expr *rhs = OrigOp.get(); + const auto *ME = dyn_cast<MemberExpr>(rhs); + 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>()))) { + Diag(OpLoc, diag::warn_taking_address_of_packed_member) + << MD << RD << rhs->getSourceRange(); + break; + } + ME = dyn_cast<MemberExpr>(ME->getBase()); + } + return Context.getPointerType(op->getType()); } |

