clang 20.0.0git
SemaBoundsSafety.cpp
Go to the documentation of this file.
1//===-- SemaBoundsSafety.cpp - Bounds Safety specific routines-*- C++ -*---===//
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/// \file
9/// This file declares semantic analysis functions specific to `-fbounds-safety`
10/// (Bounds Safety) and also its attributes when used without `-fbounds-safety`
11/// (e.g. `counted_by`)
12///
13//===----------------------------------------------------------------------===//
14#include "clang/Sema/Sema.h"
15
16namespace clang {
17
19getCountAttrKind(bool CountInBytes, bool OrNull) {
20 if (CountInBytes)
25}
26
28 const auto *RD = FD->getParent();
29 // An unnamed struct is anonymous struct only if it's not instantiated.
30 // However, the struct may not be fully processed yet to determine
31 // whether it's anonymous or not. In that case, this function treats it as
32 // an anonymous struct and tries to find a named parent.
33 while (RD && (RD->isAnonymousStructOrUnion() ||
34 (!RD->isCompleteDefinition() && RD->getName().empty()))) {
35 const auto *Parent = dyn_cast<RecordDecl>(RD->getParent());
36 if (!Parent)
37 break;
38 RD = Parent;
39 }
40 return RD;
41}
42
48 VALID,
49};
50
51bool Sema::CheckCountedByAttrOnField(FieldDecl *FD, Expr *E, bool CountInBytes,
52 bool OrNull) {
53 // Check the context the attribute is used in
54
55 unsigned Kind = getCountAttrKind(CountInBytes, OrNull);
56
57 if (FD->getParent()->isUnion()) {
58 Diag(FD->getBeginLoc(), diag::err_count_attr_in_union)
59 << Kind << FD->getSourceRange();
60 return true;
61 }
62
63 const auto FieldTy = FD->getType();
64 if (FieldTy->isArrayType() && (CountInBytes || OrNull)) {
65 Diag(FD->getBeginLoc(),
66 diag::err_count_attr_not_on_ptr_or_flexible_array_member)
67 << Kind << FD->getLocation() << /* suggest counted_by */ 1;
68 return true;
69 }
70 if (!FieldTy->isArrayType() && !FieldTy->isPointerType()) {
71 Diag(FD->getBeginLoc(),
72 diag::err_count_attr_not_on_ptr_or_flexible_array_member)
73 << Kind << FD->getLocation() << /* do not suggest counted_by */ 0;
74 return true;
75 }
76
77 LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel =
79 if (FieldTy->isArrayType() &&
81 StrictFlexArraysLevel, true)) {
82 Diag(FD->getBeginLoc(),
83 diag::err_counted_by_attr_on_array_not_flexible_array_member)
84 << Kind << FD->getLocation();
85 return true;
86 }
87
88 CountedByInvalidPointeeTypeKind InvalidTypeKind =
89