10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
12 #include "clang/Basic/TargetInfo.h"
20 void DefaultOperatorNewAlignmentCheck::registerMatchers(MatchFinder *Finder) {
22 cxxNewExpr(unless(hasAnyPlacementArg(anything()))).bind(
"new"),
this);
25 void DefaultOperatorNewAlignmentCheck::check(
26 const MatchFinder::MatchResult &Result) {
28 const auto *NewExpr = Result.Nodes.getNodeAs<CXXNewExpr>(
"new");
30 QualType T = NewExpr->getAllocatedType();
32 if (T->isDependentType())
34 const TagDecl *D = T->getAsTagDecl();
36 if (!D || !D->getDefinition() || !D->isCompleteDefinition())
39 ASTContext &Context = D->getASTContext();
42 if (!Context.isAlignmentRequired(T))
46 unsigned SpecifiedAlignment = D->getMaxAlignment();
48 if (!SpecifiedAlignment)
51 unsigned DefaultNewAlignment = Context.getTargetInfo().getNewAlign();
53 bool OverAligned = SpecifiedAlignment > DefaultNewAlignment;
54 bool HasDefaultOperatorNew =
55 !NewExpr->getOperatorNew() || NewExpr->getOperatorNew()->isImplicit();
57 unsigned CharWidth = Context.getTargetInfo().getCharWidth();
58 if (HasDefaultOperatorNew && OverAligned)
59 diag(NewExpr->getBeginLoc(),
60 "allocation function returns a pointer with alignment %0 but the "
61 "over-aligned type being allocated requires alignment %1")
62 << (DefaultNewAlignment / CharWidth)
63 << (SpecifiedAlignment / CharWidth);