clang-tools  10.0.0
DefaultOperatorNewAlignmentCheck.cpp
Go to the documentation of this file.
1 //===--- DefaultOperatorNewCheck.cpp - clang-tidy --------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
12 
13 using namespace clang::ast_matchers;
14 
15 namespace clang {
16 namespace tidy {
17 namespace cert {
18 
19 AST_MATCHER(CXXNewExpr, isPlacementNew) {
20  return Node.getNumPlacementArgs() > 0;
21 }
22 
23 void DefaultOperatorNewAlignmentCheck::registerMatchers(MatchFinder *Finder) {
24  // Check not applicable in C++17 (or newer).
25  if (getLangOpts().CPlusPlus17)
26  return;
27 
28  Finder->addMatcher(cxxNewExpr(unless(isPlacementNew())).bind("new"), this);
29 }
30 
31 void DefaultOperatorNewAlignmentCheck::check(
32  const MatchFinder::MatchResult &Result) {
33  // Get the found 'new' expression.
34  const auto *NewExpr = Result.Nodes.getNodeAs<CXXNewExpr>("new");
35 
36  QualType T = NewExpr->getAllocatedType();
37  // Dependent types do not have fixed alignment.
38  if (T->isDependentType())
39  return;
40  const TagDecl *D = T->getAsTagDecl();
41  // Alignment can not be obtained for undefined type.
42  if (!D || !D->getDefinition() || !D->isCompleteDefinition())
43  return;
44 
45  ASTContext &Context = D->getASTContext();
46 
47  // Check if no alignment was specified for the type.
48  if (!Context.isAlignmentRequired(T))
49  return;
50 
51  // The user-specified alignment (in bits).
52  unsigned SpecifiedAlignment = D->getMaxAlignment();
53  // Double-check if no alignment was specified.
54  if (!SpecifiedAlignment)
55  return;
56  // The alignment used by default 'operator new' (in bits).
57  unsigned DefaultNewAlignment = Context.getTargetInfo().getNewAlign();
58 
59  bool OverAligned = SpecifiedAlignment > DefaultNewAlignment;
60  bool HasDefaultOperatorNew =
61  !NewExpr->getOperatorNew() || NewExpr->getOperatorNew()->isImplicit();
62 
63  unsigned CharWidth = Context.getTargetInfo().getCharWidth();
64  if (HasDefaultOperatorNew && OverAligned)
65  diag(NewExpr->getBeginLoc(),
66  "allocation function returns a pointer with alignment %0 but the "
67  "over-aligned type being allocated requires alignment %1")
68  << (DefaultNewAlignment / CharWidth)
69  << (SpecifiedAlignment / CharWidth);
70 }
71 
72 } // namespace cert
73 } // namespace tidy
74 } // namespace clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//