Skip to content

Commit 99aabd7

Browse files
committed
Vendor import of llvm-project main llvmorg-18-init-15692-g007ed0dccd6a.
1 parent 312c0ed commit 99aabd7

File tree

989 files changed

+80005
-92083
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

989 files changed

+80005
-92083
lines changed

clang/include/clang/AST/Decl.h

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,8 @@ class NamedDecl : public Decl {
358358
///
359359
/// \param IsKnownNewer \c true if this declaration is known to be newer
360360
/// than \p OldD (for instance, if this declaration is newly-created).
361-
bool declarationReplaces(NamedDecl *OldD, bool IsKnownNewer = true) const;
361+
bool declarationReplaces(const NamedDecl *OldD,
362+
bool IsKnownNewer = true) const;
362363

363364
/// Determine whether this declaration has linkage.
364365
bool hasLinkage() const;
@@ -4332,30 +4333,6 @@ class RecordDecl : public TagDecl {
43324333
return field_begin() == field_end();
43334334
}
43344335

4335-
FieldDecl *getLastField() {
4336-
FieldDecl *FD = nullptr;
4337-
for (FieldDecl *Field : fields())
4338-
FD = Field;
4339-
return FD;
4340-
}
4341-
const FieldDecl *getLastField() const {
4342-
return const_cast<RecordDecl *>(this)->getLastField();
4343-
}
4344-
4345-
template <typename Functor>
4346-
const FieldDecl *findFieldIf(Functor &Pred) const {
4347-
for (const Decl *D : decls()) {
4348-
if (const auto *FD = dyn_cast<FieldDecl>(D); FD && Pred(FD))
4349-
return FD;
4350-
4351-
if (const auto *RD = dyn_cast<RecordDecl>(D))
4352-
if (const FieldDecl *FD = RD->findFieldIf(Pred))
4353-
return FD;
4354-
}
4355-
4356-
return nullptr;
4357-
}
4358-
43594336
/// Note that the definition of this type is now complete.
43604337
virtual void completeDefinition();
43614338

clang/include/clang/AST/DeclBase.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include "clang/AST/SelectorLocationsKind.h"
2020
#include "clang/Basic/IdentifierTable.h"
2121
#include "clang/Basic/LLVM.h"
22-
#include "clang/Basic/LangOptions.h"
2322
#include "clang/Basic/SourceLocation.h"
2423
#include "clang/Basic/Specifiers.h"
2524
#include "llvm/ADT/ArrayRef.h"
@@ -489,15 +488,6 @@ class alignas(8) Decl {
489488
// Return true if this is a FileContext Decl.
490489
bool isFileContextDecl() const;
491490

492-
/// Whether it resembles a flexible array member. This is a static member
493-
/// because we want to be able to call it with a nullptr. That allows us to
494-
/// perform non-Decl specific checks based on the object's type and strict
495-
/// flex array level.
496-
static bool isFlexibleArrayMemberLike(
497-
ASTContext &Context, const Decl *D, QualType Ty,
498-
LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel,
499-
bool IgnoreTemplateOrMacroSubstitution);
500-
501491
ASTContext &getASTContext() const LLVM_READONLY;
502492

503493
/// Helper to get the language options from the ASTContext.

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2036,12 +2036,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
20362036
#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
20372037
DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \
20382038
/* The partial specialization. */ \
2039-
if (TemplateParameterList *TPL = D->getTemplateParameters()) { \
2040-
for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); \
2041-
I != E; ++I) { \
2042-
TRY_TO(TraverseDecl(*I)); \
2043-
} \
2044-
} \
2039+
TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
20452040
/* The args that remains unspecialized. */ \
20462041
TRY_TO(TraverseTemplateArgumentLocsHelper( \
20472042
D->getTemplateArgsAsWritten()->getTemplateArgs(), \

clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h

Lines changed: 44 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,22 @@ class Environment {
289289
/// `E` must be a glvalue or a `BuiltinType::BuiltinFn`
290290
StorageLocation *getStorageLocation(const Expr &E) const;
291291

292+
/// Returns the result of casting `getStorageLocation(...)` to a subclass of
293+
/// `StorageLocation` (using `cast_or_null<T>`).
294+
/// This assert-fails if the result of `getStorageLocation(...)` is not of
295+
/// type `T *`; if the storage location is not guaranteed to have type `T *`,
296+
/// consider using `dyn_cast_or_null<T>(getStorageLocation(...))` instead.
297+
template <typename T>
298+
std::enable_if_t<std::is_base_of_v<StorageLocation, T>, T *>
299+
get(const ValueDecl &D) const {
300+
return cast_or_null<T>(getStorageLocation(D));
301+
}
302+
template <typename T>
303+
std::enable_if_t<std::is_base_of_v<StorageLocation, T>, T *>
304+
get(const Expr &E) const {
305+
return cast_or_null<T>(getStorageLocation(E));
306+
}
307+
292308
/// Returns the storage location assigned to the `this` pointee in the
293309
/// environment or null if the `this` pointee has no assigned storage location
294310
/// in the environment.
@@ -325,7 +341,8 @@ class Environment {
325341
///
326342
/// Requirements:
327343
/// `E` must be a prvalue of record type.
328-
RecordStorageLocation &getResultObjectLocation(const Expr &RecordPRValue);
344+
RecordStorageLocation &
345+
getResultObjectLocation(const Expr &RecordPRValue) const;
329346

330347
/// Returns the return value of the current function. This can be null if:
331348
/// - The function has a void return type
@@ -434,24 +451,14 @@ class Environment {
434451

435452
/// Assigns `Val` as the value of the prvalue `E` in the environment.
436453
///
437-
/// If `E` is not yet associated with a storage location, associates it with
438-
/// a newly created storage location. In any case, associates the storage
439-
/// location of `E` with `Val`.
440-
///
441-
/// Once the migration to strict handling of value categories is complete
442-
/// (see https://discourse.llvm.org/t/70086), this function will be renamed to
443-
/// `setValue()`. At this point, prvalue expressions will be associated
444-
/// directly with `Value`s, and the legacy behavior of associating prvalue
445-
/// expressions with storage locations (as described above) will be
446-
/// eliminated.
447-
///
448454
/// Requirements:
449455
///
450-
/// `E` must be a prvalue
451-
/// If `Val` is a `RecordValue`, its `RecordStorageLocation` must be the
452-
/// same as that of any `RecordValue` that has already been associated with
453-
/// `E`. This is to guarantee that the result object initialized by a prvalue
454-
/// `RecordValue` has a durable storage location.
456+
/// - `E` must be a prvalue
457+
/// - If `Val` is a `RecordValue`, its `RecordStorageLocation` must be
458+
/// `getResultObjectLocation(E)`. An exception to this is if `E` is an
459+
/// expression that originally creates a `RecordValue` (such as a
460+
/// `CXXConstructExpr` or `CallExpr`), as these establish the location of
461+
/// the result object in the first place.
455462
void setValue(const Expr &E, Value &Val);
456463

457464
/// Returns the value assigned to `Loc` in the environment or null if `Loc`
@@ -466,6 +473,26 @@ class Environment {
466473
/// storage location in the environment, otherwise returns null.
467474
Value *getValue(const Expr &E) const;
468475

476+
/// Returns the result of casting `getValue(...)` to a subclass of `Value`
477+
/// (using `cast_or_null<T>`).
478+
/// This assert-fails if the result of `getValue(...)` is not of type `T *`;
479+
/// if the value is not guaranteed to have type `T *`, consider using
480+
/// `dyn_cast_or_null<T>(getValue(...))` instead.
481+
template <typename T>
482+
std::enable_if_t<std::is_base_of_v<Value, T>, T *>
483+
get(const StorageLocation &Loc) const {
484+
return cast_or_null<T>(getValue(Loc));
485+
}
486+
template <typename T>
487+
std::enable_if_t<std::is_base_of_v<Value, T>, T *>
488+
get(const ValueDecl &D) const {
489+
return cast_or_null<T>(getValue(D));
490+
}
491+
template <typename T>
492+
std::enable_if_t<std::is_base_of_v<Value, T>, T *> get(const Expr &E) const {
493+
return cast_or_null<T>(getValue(E));
494+
}
495+
469496
// FIXME: should we deprecate the following & call arena().create() directly?
470497

471498
/// Creates a `T` (some subclass of `Value`), forwarding `args` to the
@@ -608,14 +635,6 @@ class Environment {
608635
// The copy-constructor is for use in fork() only.
609636
Environment(const Environment &) = default;
610637

611-
/// Internal version of `setStorageLocation()` that doesn't check if the
612-
/// expression is a prvalue.
613-
void setStorageLocationInternal(const Expr &E, StorageLocation &Loc);
614-
615-
/// Internal version of `getStorageLocation()` that doesn't check if the
616-
/// expression is a prvalue.
617-
StorageLocation *getStorageLocationInternal(const Expr &E) const;
618-
619638
/// Creates a value appropriate for `Type`, if `Type` is supported, otherwise
620639
/// return null.
621640
///
@@ -708,20 +727,9 @@ RecordStorageLocation *getBaseObjectLocation(const MemberExpr &ME,
708727
std::vector<FieldDecl *> getFieldsForInitListExpr(const RecordDecl *RD);
709728

710729
/// Associates a new `RecordValue` with `Loc` and returns the new value.
711-
/// It is not defined whether the field values remain the same or not.
712-
///
713-
/// This function is primarily intended for use by checks that set custom
714-
/// properties on `RecordValue`s to model the state of these values. Such checks
715-
/// should avoid modifying the properties of an existing `RecordValue` because
716-
/// these changes would be visible to other `Environment`s that share the same
717-
/// `RecordValue`. Instead, call `refreshRecordValue()`, then set the properties
718-
/// on the new `RecordValue` that it returns. Typical usage:
719-
///
720-
/// refreshRecordValue(Loc, Env).setProperty("my_prop", MyPropValue);
721730
RecordValue &refreshRecordValue(RecordStorageLocation &Loc, Environment &Env);
722731

723732
/// Associates a new `RecordValue` with `Expr` and returns the new value.
724-
/// See also documentation for the overload above.
725733
RecordValue &refreshRecordValue(const Expr &Expr, Environment &Env);
726734

727735
} // namespace dataflow

clang/include/clang/Analysis/FlowSensitive/RecordOps.h

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,13 @@ namespace dataflow {
2222
/// Copies a record (struct, class, or union) from `Src` to `Dst`.
2323
///
2424
/// This performs a deep copy, i.e. it copies every field (including synthetic
25-
/// fields) and recurses on fields of record type. It also copies properties
26-
/// from the `RecordValue` associated with `Src` to the `RecordValue` associated
27-
/// with `Dst` (if these `RecordValue`s exist).
25+
/// fields) and recurses on fields of record type.
2826
///
2927
/// If there is a `RecordValue` associated with `Dst` in the environment, this
3028
/// function creates a new `RecordValue` and associates it with `Dst`; clients
3129
/// need to be aware of this and must not assume that the `RecordValue`
3230
/// associated with `Dst` remains the same after the call.
3331
///
34-
/// We create a new `RecordValue` rather than modifying properties on the old
35-
/// `RecordValue` because the old `RecordValue` may be shared with other
36-
/// `Environment`s, and we don't want changes to properties to be visible there.
37-
///
3832
/// Requirements:
3933
///
4034
/// `Src` and `Dst` must have the same canonical unqualified type.
@@ -49,9 +43,7 @@ void copyRecord(RecordStorageLocation &Src, RecordStorageLocation &Dst,
4943
///
5044
/// This performs a deep comparison, i.e. it compares every field (including
5145
/// synthetic fields) and recurses on fields of record type. Fields of reference
52-
/// type compare equal if they refer to the same storage location. If
53-
/// `RecordValue`s are associated with `Loc1` and Loc2`, it also compares the
54-
/// properties on those `RecordValue`s.
46+
/// type compare equal if they refer to the same storage location.
5547
///
5648
/// Note on how to interpret the result:
5749
/// - If this returns true, the records are guaranteed to be equal at runtime.

clang/include/clang/Analysis/FlowSensitive/Value.h

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,11 @@ class Value {
6363

6464
/// Assigns `Val` as the value of the synthetic property with the given
6565
/// `Name`.
66+
///
67+
/// Properties may not be set on `RecordValue`s; use synthetic fields instead
68+
/// (for details, see documentation for `RecordStorageLocation`).
6669
void setProperty(llvm::StringRef Name, Value &Val) {
70+
assert(getKind() != Kind::Record);
6771
Properties.insert_or_assign(Name, &Val);
6872
}
6973

@@ -184,33 +188,23 @@ class PointerValue final : public Value {
184188
/// In C++, prvalues of class type serve only a limited purpose: They can only
185189
/// be used to initialize a result object. It is not possible to access member
186190
/// variables or call member functions on a prvalue of class type.
187-
/// Correspondingly, `RecordValue` also serves only two limited purposes:
188-
/// - It conveys a prvalue of class type from the place where the object is
189-
/// constructed to the result object that it initializes.
191+
/// Correspondingly, `RecordValue` also serves only a limited purpose: It
192+
/// conveys a prvalue of class type from the place where the object is
193+
/// constructed to the result object that it initializes.
190194
///
191-
/// When creating a prvalue of class type, we already need a storage location
192-
/// for `this`, even though prvalues are otherwise not associated with storage
193-
/// locations. `RecordValue` is therefore essentially a wrapper for a storage
194-
/// location, which is then used to set the storage location for the result
195-
/// object when we process the AST node for that result object.
195+
/// When creating a prvalue of class type, we already need a storage location
196+
/// for `this`, even though prvalues are otherwise not associated with storage
197+
/// locations. `RecordValue` is therefore essentially a wrapper for a storage
198+
/// location, which is then used to set the storage location for the result
199+
/// object when we process the AST node for that result object.
196200
///
197-
/// For example:
198-
/// MyStruct S = MyStruct(3);
201+
/// For example:
202+
/// MyStruct S = MyStruct(3);
199203
///
200-
/// In this example, `MyStruct(3) is a prvalue, which is modeled as a
201-
/// `RecordValue` that wraps a `RecordStorageLocation`. This
202-
// `RecordStorageLocation` is then used as the storage location for `S`.
204+
/// In this example, `MyStruct(3) is a prvalue, which is modeled as a
205+
/// `RecordValue` that wraps a `RecordStorageLocation`. This
206+
/// `RecordStorageLocation` is then used as the storage location for `S`.
203207
///
204-
/// - It allows properties to be associated with an object of class type.
205-
/// Note that when doing so, you should avoid mutating the properties of an
206-
/// existing `RecordValue` in place, as these changes would be visible to
207-
/// other `Environment`s that share the same `RecordValue`. Instead, associate
208-
/// a new `RecordValue` with the `RecordStorageLocation` and set the
209-
/// properties on this new `RecordValue`. (See also `refreshRecordValue()` in
210-
/// DataflowEnvironment.h, which makes this easy.)
211-
/// Note also that this implies that it is common for the same
212-
/// `RecordStorageLocation` to be associated with different `RecordValue`s
213-
/// in different environments.
214208
/// Over time, we may eliminate `RecordValue` entirely. See also the discussion
215209
/// here: https://reviews.llvm.org/D155204#inline-1503204
216210
class RecordValue final : public Value {

clang/include/clang/Basic/Attr.td

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4331,24 +4331,6 @@ def AvailableOnlyInDefaultEvalMethod : InheritableAttr {
43314331
let Documentation = [Undocumented];
43324332
}
43334333

4334-
def CountedBy : InheritableAttr {
4335-
let Spellings = [Clang<"counted_by">];
4336-
let Subjects = SubjectList<[Field]>;
4337-
let Args = [IdentifierArgument<"CountedByField">];
4338-
let Documentation = [CountedByDocs];
4339-
let LangOpts = [COnly];
4340-
// FIXME: This is ugly. Let using a DeclArgument would be nice, but a Decl
4341-
// isn't yet available due to the fact that we're still parsing the
4342-
// structure. Maybe that code could be changed sometime in the future.
4343-
code AdditionalMembers = [{
4344-
private:
4345-
SourceRange CountedByFieldLoc;
4346-
public:
4347-
SourceRange getCountedByFieldLoc() const { return CountedByFieldLoc; }
4348-
void setCountedByFieldLoc(SourceRange Loc) { CountedByFieldLoc = Loc; }
4349-
}];
4350-
}
4351-
43524334
def PreferredType: InheritableAttr {
43534335
let Spellings = [Clang<"preferred_type">];
43544336
let Subjects = SubjectList<[BitField], ErrorDiag>;

clang/include/clang/Basic/AttrDocs.td

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -7500,72 +7500,6 @@ attribute, they default to the value ``65535``.
75007500
}];
75017501
}
75027502

7503-
def CountedByDocs : Documentation {
7504-
let Category = DocCatField;
7505-
let Content = [{
7506-
Clang supports the ``counted_by`` attribute on the flexible array member of a
7507-
structure in C. The argument for the attribute is the name of a field member in
7508-
the same structure holding the count of elements in the flexible array. This
7509-
information can be used to improve the results of the array bound sanitizer and
7510-
the ``__builtin_dynamic_object_size`` builtin.
7511-
7512-
For example, the following code:
7513-
7514-
.. code-block:: c
7515-
7516-
struct bar;
7517-
7518-
struct foo {
7519-
size_t count;
7520-
char other;
7521-
struct bar *array[] __attribute__((counted_by(count)));
7522-
};
7523-
7524-
specifies that the flexible array member ``array`` has the number of elements
7525-
allocated for it stored in ``count``. This establishes a relationship between
7526-
``array`` and ``count``. Specifically, ``p->array`` must have at least
7527-
``p->count`` number of elements available. It's the user's responsibility to
7528-
ensure that this relationship is maintained through changes to the structure.
7529-
7530-
In the following example, the allocated array erroneously has fewer elements
7531-
than what's specified by ``p->count``. This would result in an out-of-bounds
7532-
access not being detected.
7533-
7534-
.. code-block:: c
7535-
7536-
#define SIZE_INCR 42
7537-
7538-
struct foo *p;
7539-
7540-
void foo_alloc(size_t count) {
7541-
p = malloc(MAX(sizeof(struct foo),
7542-
offsetof(struct foo, array[0]) + count * sizeof(struct bar *)));
7543-
p->count = count + SIZE_INCR;
7544-
}
7545-
7546-
The next example updates ``p->count``, breaking the relationship requirement
7547-
that ``p->array`` must have at least ``p->count`` number of elements available:
7548-
7549-
.. code-block:: c
7550-
7551-
#define SIZE_INCR 42
7552-
7553-
struct foo *p;
7554-
7555-
void foo_alloc(size_t count) {
7556-
p = malloc(MAX(sizeof(struct foo),
7557-
offsetof(struct foo, array[0]) + count * sizeof(struct bar *)));
7558-
p->count = count;
7559-
}
7560-
7561-
void use_foo(int index) {
7562-
p->count += SIZE_INCR + 1; /* 'count' is now larger than the number of elements of 'array'. */
7563-
p->array[index] = 0; /* the sanitizer can't properly check if this is an out-of-bounds access. */
7564-
}
7565-
7566-
}];
7567-
}
7568-
75697503
def CoroOnlyDestroyWhenCompleteDocs : Documentation {
75707504
let Category = DocCatDecl;
75717505
let Content = [{

0 commit comments

Comments
 (0)